PageRenderTime 54ms CodeModel.GetById 24ms 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. #ifndef __GALOIS_H__
  20. #define __GALOIS_H__
  21. template <const unsigned int bits, const unsigned int generator, typename valuetype> class GaloisTable;
  22. template <const unsigned int bits, const unsigned int generator, typename valuetype> class Galois;
  23. template <class g> class GaloisLongMultiplyTable;
  24. // This source file defines the Galois object for carrying out
  25. // arithmetic in GF(2^16) using the generator 0x1100B.
  26. // Also defined are the GaloisTable object (which contains log and
  27. // anti log tables for use in multiplication and division), and
  28. // the GaloisLongMultiplyTable object (which contains tables for
  29. // carrying out multiplation of 16-bit galois numbers 8 bits at a time).
  30. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  31. class GaloisTable
  32. {
  33. public:
  34. typedef valuetype ValueType;
  35. GaloisTable(void);
  36. enum
  37. {
  38. Bits = bits,
  39. Count = 1<<Bits,
  40. Limit = Count-1,
  41. Generator = generator,
  42. };
  43. #if __APPLE__
  44. // Using fixed sized arrays in a static variable causes a blowout in the __DATA segment
  45. // which can be reduced by making the tables heap-based instead of __DATA segment based.
  46. ~GaloisTable(void) {
  47. delete [] log;
  48. delete [] antilog;
  49. }
  50. ValueType* log;
  51. ValueType* antilog;
  52. #else
  53. ValueType log[Count];
  54. ValueType antilog[Count];
  55. #endif
  56. };
  57. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  58. class Galois
  59. {
  60. public:
  61. typedef valuetype ValueType;
  62. // Basic constructors
  63. Galois(void) {};
  64. Galois(ValueType v);
  65. // Copy and assignment
  66. Galois(const Galois &right) {value = right.value;}
  67. Galois& operator = (const Galois &right) { value = right.value; return *this;}
  68. // Addition
  69. Galois operator + (const Galois &right) const { return (value ^ right.value); }
  70. Galois& operator += (const Galois &right) { value ^= right.value; return *this;}
  71. // Subtraction
  72. Galois operator - (const Galois &right) const { return (value ^ right.value); }
  73. Galois& operator -= (const Galois &right) { value ^= right.value; return *this;}
  74. // Multiplication
  75. Galois operator * (const Galois &right) const;
  76. Galois& operator *= (const Galois &right);
  77. // Division
  78. Galois operator / (const Galois &right) const;
  79. Galois& operator /= (const Galois &right);
  80. // Power
  81. Galois pow(unsigned int right) const;
  82. Galois operator ^ (unsigned int right) const;
  83. Galois& operator ^= (unsigned int right);
  84. // Cast to value and value access
  85. operator ValueType(void) const {return value;}
  86. ValueType Value(void) const {return value;}
  87. // Direct log and antilog
  88. ValueType Log(void) const;
  89. ValueType ALog(void) const;
  90. enum
  91. {
  92. Bits = GaloisTable<bits,generator,valuetype>::Bits,
  93. Count = GaloisTable<bits,generator,valuetype>::Count,
  94. Limit = GaloisTable<bits,generator,valuetype>::Limit,
  95. };
  96. protected:
  97. ValueType value;
  98. static GaloisTable<bits,generator,valuetype> table;
  99. };
  100. #ifdef LONGMULTIPLY
  101. template <class g>
  102. class GaloisLongMultiplyTable
  103. {
  104. public:
  105. GaloisLongMultiplyTable(void);
  106. typedef g G;
  107. enum
  108. {
  109. Bytes = ((G::Bits + 7) >> 3),
  110. Count = ((Bytes * (Bytes+1)) / 2),
  111. };
  112. G tables[Count * 256 * 256];
  113. };
  114. #endif
  115. // Construct the log and antilog tables from the generator
  116. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  117. inline GaloisTable<bits,generator,valuetype>::GaloisTable(void)
  118. {
  119. #if __APPLE__
  120. log = new ValueType[Count];
  121. antilog = new ValueType[Count];
  122. #endif
  123. u32 b = 1;
  124. for (u32 l=0; l<Limit; l++)
  125. {
  126. log[b] = (ValueType)l;
  127. antilog[l] = (ValueType)b;
  128. b <<= 1;
  129. if (b & Count) b ^= Generator;
  130. }
  131. log[0] = (ValueType)Limit;
  132. antilog[Limit] = 0;
  133. }
  134. // The one and only galois log/antilog table object
  135. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  136. GaloisTable<bits,generator,valuetype> Galois<bits,generator,valuetype>::table;
  137. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  138. inline Galois<bits,generator,valuetype>::Galois(typename Galois<bits,generator,valuetype>::ValueType v)
  139. {
  140. value = v;
  141. }
  142. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  143. inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator * (const Galois<bits,generator,valuetype> &right) const
  144. {
  145. if (value == 0 || right.value == 0) return 0;
  146. unsigned int sum = table.log[value] + table.log[right.value];
  147. if (sum >= Limit)
  148. {
  149. return table.antilog[sum-Limit];
  150. }
  151. else
  152. {
  153. return table.antilog[sum];
  154. }
  155. }
  156. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  157. inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator *= (const Galois<bits,generator,valuetype> &right)
  158. {
  159. if (value == 0 || right.value == 0)
  160. {
  161. value = 0;
  162. }
  163. else
  164. {
  165. unsigned int sum = table.log[value] + table.log[right.value];
  166. if (sum >= Limit)
  167. {
  168. value = table.antilog[sum-Limit];
  169. }
  170. else
  171. {
  172. value = table.antilog[sum];
  173. }
  174. }
  175. return *this;
  176. }
  177. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  178. inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator / (const Galois<bits,generator,valuetype> &right) const
  179. {
  180. if (value == 0) return 0;
  181. assert(right.value != 0);
  182. if (right.value == 0) {return 0;} // Division by 0!
  183. int sum = table.log[value] - table.log[right.value];
  184. if (sum < 0)
  185. {
  186. return table.antilog[sum+Limit];
  187. }
  188. else
  189. {
  190. return table.antilog[sum];
  191. }
  192. }
  193. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  194. inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator /= (const Galois<bits,generator,valuetype> &right)
  195. {
  196. if (value == 0) return *this;
  197. assert(right.value != 0);
  198. if (right.value == 0) {return *this;} // Division by 0!
  199. int sum = table.log[value] - table.log[right.value];
  200. if (sum < 0)
  201. {
  202. value = table.antilog[sum+Limit];
  203. }
  204. else
  205. {
  206. value = table.antilog[sum];
  207. }
  208. return *this;
  209. }
  210. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  211. inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::pow(unsigned int right) const
  212. {
  213. if (right == 0) return 1;
  214. if (value == 0) return 0;
  215. unsigned int sum = table.log[value] * right;
  216. sum = (sum >> Bits) + (sum & Limit);
  217. if (sum >= Limit)
  218. {
  219. return table.antilog[sum-Limit];
  220. }
  221. else
  222. {
  223. return table.antilog[sum];
  224. }
  225. }
  226. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  227. inline Galois<bits,generator,valuetype> Galois<bits,generator,valuetype>::operator ^ (unsigned int right) const
  228. {
  229. if (right == 0) return 1;
  230. if (value == 0) return 0;
  231. unsigned int sum = table.log[value] * right;
  232. sum = (sum >> Bits) + (sum & Limit);
  233. if (sum >= Limit)
  234. {
  235. return table.antilog[sum-Limit];
  236. }
  237. else
  238. {
  239. return table.antilog[sum];
  240. }
  241. }
  242. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  243. inline Galois<bits,generator,valuetype>& Galois<bits,generator,valuetype>::operator ^= (unsigned int right)
  244. {
  245. if (right == 1) {value = 1; return *this;}
  246. if (value == 0) return *this;
  247. unsigned int sum = table.log[value] * right;
  248. sum = (sum >> Bits) + (sum & Limit);
  249. if (sum >= Limit)
  250. {
  251. value = table.antilog[sum-Limit];
  252. }
  253. else
  254. {
  255. value = table.antilog[sum];
  256. }
  257. return *this;
  258. }
  259. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  260. inline valuetype Galois<bits,generator,valuetype>::Log(void) const
  261. {
  262. return table.log[value];
  263. }
  264. template <const unsigned int bits, const unsigned int generator, typename valuetype>
  265. inline valuetype Galois<bits,generator,valuetype>::ALog(void) const
  266. {
  267. return table.antilog[value];
  268. }
  269. #ifdef LONGMULTIPLY
  270. template <class g>
  271. inline GaloisLongMultiplyTable<g>::GaloisLongMultiplyTable(void)
  272. {
  273. G *table = tables;
  274. for (unsigned int i=0; i<Bytes; i++)
  275. {
  276. for (unsigned int j=i; j<Bytes; j++)
  277. {
  278. for (unsigned int ii=0; ii<256; ii++)
  279. {
  280. for (unsigned int jj=0; jj<256; jj++)
  281. {
  282. *table++ = G(ii << (8*i)) * G(jj << (8*j));
  283. }
  284. }
  285. }
  286. }
  287. }
  288. #endif
  289. typedef Galois<8,0x11D,u8> Galois8;
  290. typedef Galois<16,0x1100B,u16> Galois16;
  291. #endif // __GALOIS_H__