galois.h

Go to the documentation of this file.
00001 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and
00002 // repair tool). See https://parchive.sourceforge.net for details of PAR 2.0.
00003 //
00004 // Copyright (c) 2003 Peter Brian Clements
00005 //
00006 // par2cmdline is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // par2cmdline is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019 
00020 #ifndef __GALOIS_H__
00021 #define __GALOIS_H__
00022 
00023 template unsigned int bits, const unsigned int generator, typename valuetype> class GaloisTable;
00024 template unsigned int bits, const unsigned int generator, typename valuetype> class Galois;
00025 
00026 template class g> class GaloisLongMultiplyTable;
00027 
00028 // This source file defines the Galois object for carrying out
00029 // arithmetic in GF(2^16) using the generator 0x1100B.
00030 
00031 // Also defined are the GaloisTable object (which contains log and
00032 // anti log tables for use in multiplication and division), and
00033 // the GaloisLongMultiplyTable object (which contains tables for
00034 // carrying out multiplation of 16-bit galois numbers 8 bits at a time).
00035 
00036 template unsigned int bits, const unsigned int generator, typename valuetype>
00037 class GaloisTable
00038 {
00039 public:
00040   typedef valuetype ValueType;
00041 
00042   GaloisTable(void);
00043 
00044   enum
00045   {
00046     Bits = bits,
00047     Count = 100048     Limit = Count-1,
00049     Generator = generator,
00050   };
00051 
00052   ValueType log[Count];
00053   ValueType antilog[Count];
00054 };
00055 
00056 template unsigned int bits, const unsigned int generator, typename valuetype>
00057 class Galois
00058 {
00059 public:
00060   typedef valuetype ValueType;
00061 
00062   // Basic constructors
00063   Galois(void) {};
00064   Galois(ValueType v);
00065 
00066   // Copy and assignment
00067   Galois(const Galois &right) {value = right.value;}
00068   Galois& operator = (const Galois &right) { value = right.value; return *this;}
00069 
00070   // Addition
00071   Galois operator + (const Galois &right) const { return (value ^ right.value); }
00072   Galois& operator += (const Galois &right) { value ^= right.value; return *this;}
00073 
00074   // Subtraction
00075   Galois operator - (const Galois &right) const { return (value ^ right.value); }
00076   Galois& operator -= (const Galois &right) { value ^= right.value; return *this;}
00077 
00078   // Multiplication
00079   Galois operator * (const Galois &right) const;
00080   Galois& operator *= (const Galois &right);
00081 
00082   // Division
00083   Galois operator / (const Galois &right) const;
00084   Galois& operator /= (const Galois &right);
00085 
00086   // Power
00087   Galois pow(unsigned int right) const;
00088   Galois operator ^ (unsigned int right) const;
00089   Galois& operator ^= (unsigned int right);
00090 
00091   // Cast to value and value access
00092   operator ValueType(void) const {return value;}
00093   ValueType Value(void) const {return value;}
00094 
00095   // Direct log and antilog
00096   ValueType Log(void) const;
00097   ValueType ALog(void) const;
00098 
00099   enum 
00100   {
00101     Bits  = GaloisTable::Bits,
00102     Count = GaloisTable::Count,
00103     Limit = GaloisTable::Limit,
00104   };
00105 
00106 protected:
00107   ValueType value;
00108 
00109   static GaloisTable table;
00110 };
00111 
00112 #ifdef LONGMULTIPLY
00113 template class g> 
00114 class GaloisLongMultiplyTable
00115 {
00116 public:
00117   GaloisLongMultiplyTable(void);
00118 
00119   typedef g G;
00120 
00121   enum
00122   {
00123     Bytes = ((G::Bits + 7) >> 3),
00124     Count = ((Bytes * (Bytes+1)) / 2),
00125   };
00126 
00127   G tables[Count * 256 * 256];
00128 };
00129 #endif
00130 
00131 // Construct the log and antilog tables from the generator
00132 
00133 template unsigned int bits, const unsigned int generator, typename valuetype>
00134 inline GaloisTable::GaloisTable(void)
00135 {
00136   u32 b = 1;
00137 
00138   for (u32 l=0; l00139   {
00140     log[b]     = (ValueType)l;
00141     antilog[l] = (ValueType)b;
00142 
00143     b 00144     if (b & Count) b ^= Generator;
00145   }
00146 
00147   log[0] = (ValueType)Limit;
00148   antilog[Limit] = 0;
00149 }
00150 
00151 
00152 // The one and only galois log/antilog table object
00153 
00154 template unsigned int bits, const unsigned int generator, typename valuetype>
00155 GaloisTable Galois::table;
00156 
00157 
00158 template unsigned int bits, const unsigned int generator, typename valuetype>
00159 inline Galois::Galois(typename Galois::ValueType v)
00160 {
00161   value = v;
00162 }
00163 
00164 template unsigned int bits, const unsigned int generator, typename valuetype>
00165 inline Galois Galois::operator * (const Galois &right) const
00166 { 
00167   if (value == 0 || right.value == 0) return 0;
00168   unsigned int sum = table.log[value] + table.log[right.value];
00169   if (sum >= Limit) 
00170   {
00171     return table.antilog[sum-Limit];
00172   }
00173   else
00174   {
00175     return table.antilog[sum];
00176   }
00177 }
00178 
00179 template unsigned int bits, const unsigned int generator, typename valuetype>
00180 inline Galois& Galois::operator *= (const Galois &right)
00181 { 
00182   if (value == 0 || right.value == 0) 
00183   {
00184     value = 0;
00185   }
00186   else
00187   {
00188     unsigned int sum = table.log[value] + table.log[right.value];
00189     if (sum >= Limit) 
00190     {
00191       value = table.antilog[sum-Limit];
00192     }
00193     else
00194     {
00195       value = table.antilog[sum];
00196     }
00197   }
00198 
00199   return *this;
00200 }
00201 
00202 template unsigned int bits, const unsigned int generator, typename valuetype>
00203 inline Galois Galois::operator / (const Galois &right) const
00204 { 
00205   if (value == 0) return 0;
00206 
00207   assert(right.value != 0);
00208   if (right.value == 0) {return 0;} // Division by 0!
00209 
00210   int sum = table.log[value] - table.log[right.value];
00211   if (sum 00212   {
00213     return table.antilog[sum+Limit];
00214   }
00215   else
00216   {
00217     return table.antilog[sum];
00218   }
00219 }
00220 
00221 template unsigned int bits, const unsigned int generator, typename valuetype>
00222 inline Galois& Galois::operator /= (const Galois &right)
00223 { 
00224   if (value == 0) return *this;
00225 
00226   assert(right.value != 0);
00227   if (right.value == 0) {return *this;} // Division by 0!
00228 
00229   int sum = table.log[value] - table.log[right.value];
00230   if (sum 00231   {
00232     value = table.antilog[sum+Limit];
00233   }
00234   else
00235   {
00236     value = table.antilog[sum];
00237   }
00238 
00239   return *this;
00240 }
00241 
00242 template unsigned int bits, const unsigned int generator, typename valuetype>
00243 inline Galois Galois::pow(unsigned int right) const
00244 {
00245   if (right == 0) return 1;
00246   if (value == 0) return 0;
00247 
00248   unsigned int sum = table.log[value] * right;
00249 
00250   sum = (sum >> Bits) + (sum & Limit);
00251   if (sum >= Limit) 
00252   {
00253     return table.antilog[sum-Limit];
00254   }
00255   else
00256   {
00257     return table.antilog[sum];
00258   }  
00259 }
00260 
00261 template unsigned int bits, const unsigned int generator, typename valuetype>
00262 inline Galois Galois::operator ^ (unsigned int right) const
00263 {
00264   if (right == 0) return 1;
00265   if (value == 0) return 0;
00266 
00267   unsigned int sum = table.log[value] * right;
00268 
00269   sum = (sum >> Bits) + (sum & Limit);
00270   if (sum >= Limit) 
00271   {
00272     return table.antilog[sum-Limit];
00273   }
00274   else
00275   {
00276     return table.antilog[sum];
00277   }  
00278 }
00279 
00280 template unsigned int bits, const unsigned int generator, typename valuetype>
00281 inline Galois& Galois::operator ^= (unsigned int right)
00282 {
00283   if (right == 1) {value = 1; return *this;}
00284   if (value == 0) return *this;
00285 
00286   unsigned int sum = table.log[value] * right;
00287 
00288   sum = (sum >> Bits) + (sum & Limit);
00289   if (sum >= Limit) 
00290   {
00291     value = table.antilog[sum-Limit];
00292   }
00293   else
00294   {
00295     value = table.antilog[sum];
00296   }
00297 
00298   return *this;
00299 }
00300 
00301 template unsigned int bits, const unsigned int generator, typename valuetype>
00302 inline valuetype Galois::Log(void) const
00303 {
00304   return table.log[value];
00305 }
00306 
00307 template unsigned int bits, const unsigned int generator, typename valuetype>
00308 inline valuetype Galois::ALog(void) const
00309 {
00310   return table.antilog[value];
00311 }
00312 
00313 #ifdef LONGMULTIPLY
00314 template class g> 
00315 inline GaloisLongMultiplyTable::GaloisLongMultiplyTable(void)
00316 {
00317   G *table = tables;
00318 
00319   for (unsigned int i=0; i00320   {
00321     for (unsigned int j=i; j00322     {
00323       for (unsigned int ii=0; ii00324       {
00325         for (unsigned int jj=0; jj00326         {
00327           *table++ = G(ii 00328         }
00329       }
00330     }
00331   }
00332 }
00333 #endif
00334 
00335 typedef Galois Galois8;
00336 typedef Galois Galois16;
00337 
00338 #endif // __GALOIS_H__

Generated on Sun Oct 12 01:45:29 2008 for NNTPGrab by  1.5.4