/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__