PageRenderTime 39ms CodeModel.GetById 21ms app.highlight 15ms RepoModel.GetById 0ms app.codeStats 0ms

/par2cmdline-0.4-tbb-20100203/galois.h

#
C Header | 353 lines | 254 code | 62 blank | 37 comment | 43 complexity | 3fc7fd86a224a01d00fc5dd6ce3d3dde MD5 | raw file
Possible License(s): GPL-2.0
  1//  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
  2//  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
  3//
  4//  Copyright (c) 2003 Peter Brian Clements
  5//
  6//  par2cmdline is free software; you can redistribute it and/or modify
  7//  it under the terms of the GNU General Public License as published by
  8//  the Free Software Foundation; either version 2 of the License, or
  9//  (at your option) any later version.
 10//
 11//  par2cmdline is distributed in the hope that it will be useful,
 12//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 13//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14//  GNU General Public License for more details.
 15//
 16//  You should have received a copy of the GNU General Public License
 17//  along with this program; if not, write to the Free Software
 18//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19
 20#ifndef __GALOIS_H__
 21#define __GALOIS_H__
 22
 23template <const unsigned int bits, const unsigned int generator, typename valuetype> class GaloisTable;
 24template <const unsigned int bits, const unsigned int generator, typename valuetype> class Galois;
 25
 26template <class g> class GaloisLongMultiplyTable;
 27
 28// This source file defines the Galois object for carrying out
 29// arithmetic in GF(2^16) using the generator 0x1100B.
 30
 31// Also defined are the GaloisTable object (which contains log and
 32// anti log tables for use in multiplication and division), and
 33// the GaloisLongMultiplyTable object (which contains tables for
 34// carrying out multiplation of 16-bit galois numbers 8 bits at a time).
 35
 36template <const unsigned int bits, const unsigned int generator, typename valuetype>
 37class GaloisTable
 38{
 39public:
 40  typedef valuetype ValueType;
 41
 42  GaloisTable(void);
 43
 44  enum
 45  {
 46    Bits = bits,
 47    Count = 1<<Bits,
 48    Limit = Count-1,
 49    Generator = generator,
 50  };
 51#if __APPLE__
 52  // Using fixed sized arrays in a static variable causes a blowout in the __DATA segment
 53  // which can be reduced by making the tables heap-based instead of __DATA segment based.
 54  ~GaloisTable(void) {
 55    delete [] log;
 56    delete [] antilog;
 57  }
 58  ValueType* log;
 59  ValueType* antilog;
 60#else
 61  ValueType log[Count];
 62  ValueType antilog[Count];
 63#endif
 64};
 65
 66template <const unsigned int bits, const unsigned int generator, typename valuetype>
 67class Galois
 68{
 69public:
 70  typedef valuetype ValueType;
 71
 72  // Basic constructors
 73  Galois(void) {};
 74  Galois(ValueType v);
 75
 76  // Copy and assignment
 77  Galois(const Galois &right) {value = right.value;}
 78  Galois& operator = (const Galois &right) { value = right.value; return *this;}
 79
 80  // Addition
 81  Galois operator + (const Galois &right) const { return (value ^ right.value); }
 82  Galois& operator += (const Galois &right) { value ^= right.value; return *this;}
 83
 84  // Subtraction
 85  Galois operator - (const Galois &right) const { return (value ^ right.value); }
 86  Galois& operator -= (const Galois &right) { value ^= right.value; return *this;}
 87
 88  // Multiplication
 89  Galois operator * (const Galois &right) const;
 90  Galois& operator *= (const Galois &right);
 91
 92  // Division
 93  Galois operator / (const Galois &right) const;
 94  Galois& operator /= (const Galois &right);
 95
 96  // Power
 97  Galois pow(unsigned int right) const;
 98  Galois operator ^ (unsigned int right) const;
 99  Galois& operator ^= (unsigned int right);
100
101  // Cast to value and value access
102  operator ValueType(void) const {return value;}
103  ValueType Value(void) const {return value;}
104
105  // Direct log and antilog
106  ValueType Log(void) const;
107  ValueType ALog(void) const;
108
109  enum 
110  {
111    Bits  = GaloisTable<bits,generator,valuetype>::Bits,
112    Count = GaloisTable<bits,generator,valuetype>::Count,
113    Limit = GaloisTable<bits,generator,valuetype>::Limit,
114  };
115
116protected:
117  ValueType value;
118
119  static GaloisTable<bits,generator,valuetype> table;
120};
121
122#ifdef LONGMULTIPLY
123template <class g> 
124class GaloisLongMultiplyTable
125{
126public:
127  GaloisLongMultiplyTable(void);
128
129  typedef g G;
130
131  enum
132  {
133    Bytes = ((G::Bits + 7) >> 3),
134    Count = ((Bytes * (Bytes+1)) / 2),
135  };
136
137  G tables[Count * 256 * 256];
138};
139#endif
140
141// Construct the log and antilog tables from the generator
142
143template <const unsigned int bits, const unsigned int generator, typename valuetype>
144inline GaloisTable<bits,generator,valuetype>::GaloisTable(void)
145{
146#if __APPLE__
147  log = new ValueType[Count];
148  antilog = new ValueType[Count];
149#endif
150
151  u32 b = 1;
152
153  for (u32 l=0; l<Limit; l++)
154  {
155    log[b]     = (ValueType)l;
156    antilog[l] = (ValueType)b;
157
158    b <<= 1;
159    if (b & Count) b ^= Generator;
160  }
161
162  log[0] = (ValueType)Limit;
163  antilog[Limit] = 0;
164}
165
166
167// The one and only galois log/antilog table object
168
169template <const unsigned int bits, const unsigned int generator, typename valuetype>
170GaloisTable<bits,generator,valuetype> Galois<bits,generator,valuetype>::table;
171
172
173template <const unsigned int bits, const unsigned int generator, typename valuetype>
174inline Galois<bits,generator,valuetype>::Galois(typename Galois<bits,generator,valuetype>::ValueType v)
175{
176  value = v;
177}
178
179template <const unsigned int bits, const unsigned int generator, typename valuetype>
180inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator * (const Galois<bits,generator,valuetype> &right) const
181{ 
182  if (value == 0 || right.value == 0) return 0;
183  unsigned int sum = table.log[value] + table.log[right.value];
184  if (sum >= Limit) 
185  {
186    return table.antilog[sum-Limit];
187  }
188  else
189  {
190    return table.antilog[sum];
191  }
192}
193
194template <const unsigned int bits, const unsigned int generator, typename valuetype>
195inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator *= (const Galois<bits,generator,valuetype> &right)
196{ 
197  if (value == 0 || right.value == 0) 
198  {
199    value = 0;
200  }
201  else
202  {
203    unsigned int sum = table.log[value] + table.log[right.value];
204    if (sum >= Limit) 
205    {
206      value = table.antilog[sum-Limit];
207    }
208    else
209    {
210      value = table.antilog[sum];
211    }
212  }
213
214  return *this;
215}
216
217template <const unsigned int bits, const unsigned int generator, typename valuetype>
218inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator / (const Galois<bits,generator,valuetype> &right) const
219{ 
220  if (value == 0) return 0;
221
222  assert(right.value != 0);
223  if (right.value == 0) {return 0;} // Division by 0!
224
225  int sum = table.log[value] - table.log[right.value];
226  if (sum < 0) 
227  {
228    return table.antilog[sum+Limit];
229  }
230  else
231  {
232    return table.antilog[sum];
233  }
234}
235
236template <const unsigned int bits, const unsigned int generator, typename valuetype>
237inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator /= (const Galois<bits,generator,valuetype> &right)
238{ 
239  if (value == 0) return *this;
240
241  assert(right.value != 0);
242  if (right.value == 0) {return *this;} // Division by 0!
243
244  int sum = table.log[value] - table.log[right.value];
245  if (sum < 0) 
246  {
247    value = table.antilog[sum+Limit];
248  }
249  else
250  {
251    value = table.antilog[sum];
252  }
253
254  return *this;
255}
256
257template <const unsigned int bits, const unsigned int generator, typename valuetype>
258inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::pow(unsigned int right) const
259{
260  if (right == 0) return 1;
261  if (value == 0) return 0;
262
263  unsigned int sum = table.log[value] * right;
264
265  sum = (sum >> Bits) + (sum & Limit);
266  if (sum >= Limit) 
267  {
268    return table.antilog[sum-Limit];
269  }
270  else
271  {
272    return table.antilog[sum];
273  }  
274}
275
276template <const unsigned int bits, const unsigned int generator, typename valuetype>
277inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator ^ (unsigned int right) const
278{
279  if (right == 0) return 1;
280  if (value == 0) return 0;
281
282  unsigned int sum = table.log[value] * right;
283
284  sum = (sum >> Bits) + (sum & Limit);
285  if (sum >= Limit) 
286  {
287    return table.antilog[sum-Limit];
288  }
289  else
290  {
291    return table.antilog[sum];
292  }  
293}
294
295template <const unsigned int bits, const unsigned int generator, typename valuetype>
296inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator ^= (unsigned int right)
297{
298  if (right == 1) {value = 1; return *this;}
299  if (value == 0) return *this;
300
301  unsigned int sum = table.log[value] * right;
302
303  sum = (sum >> Bits) + (sum & Limit);
304  if (sum >= Limit) 
305  {
306    value = table.antilog[sum-Limit];
307  }
308  else
309  {
310    value = table.antilog[sum];
311  }
312
313  return *this;
314}
315
316template <const unsigned int bits, const unsigned int generator, typename valuetype>
317inline valuetype Galois<bits,generator,valuetype>::Log(void) const
318{
319  return table.log[value];
320}
321
322template <const unsigned int bits, const unsigned int generator, typename valuetype>
323inline valuetype Galois<bits,generator,valuetype>::ALog(void) const
324{
325  return table.antilog[value];
326}
327
328#ifdef LONGMULTIPLY
329template <class g> 
330inline GaloisLongMultiplyTable<g>::GaloisLongMultiplyTable(void)
331{
332  G *table = tables;
333
334  for (unsigned int i=0; i<Bytes; i++)
335  {
336    for (unsigned int j=i; j<Bytes; j++)
337    {
338      for (unsigned int ii=0; ii<256; ii++)
339      {
340        for (unsigned int jj=0; jj<256; jj++)
341        {
342          *table++ = G(ii << (8*i)) * G(jj << (8*j));
343        }
344      }
345    }
346  }
347}
348#endif
349
350typedef Galois<8,0x11D,u8> Galois8;
351typedef Galois<16,0x1100B,u16> Galois16;
352
353#endif // __GALOIS_H__