gentbls.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strconv"
  8. "strings"
  9. )
  10. // set deg here
  11. const deg = 8 // <= 8
  12. type polynomial [deg + 1]byte
  13. func main() {
  14. f, err := os.OpenFile("tables", os.O_WRONLY|os.O_CREATE, 0666)
  15. if err != nil {
  16. log.Fatalln(err)
  17. }
  18. defer f.Close()
  19. outputWriter := bufio.NewWriter(f)
  20. ps := genPrimitivePolynomial()
  21. title := strconv.FormatInt(int64(deg), 10) + " degree primitive polynomial:\n"
  22. var pss string
  23. for i, p := range ps {
  24. pf := formatPolynomial(p)
  25. pf = strconv.FormatInt(int64(i+1), 10) + ". " + pf + ";\n"
  26. pss = pss + pf
  27. }
  28. body := fmt.Sprintf(title+"%v", pss)
  29. outputWriter.WriteString(body)
  30. //set primitive polynomial here to generator tables
  31. //x^8+x^4+x^3+x^2+1
  32. var primitivePolynomial polynomial
  33. primitivePolynomial[0] = 1
  34. primitivePolynomial[2] = 1
  35. primitivePolynomial[3] = 1
  36. primitivePolynomial[4] = 1
  37. primitivePolynomial[8] = 1
  38. lenExpTable := (1 << deg) - 1
  39. expTable := genExpTable(primitivePolynomial, lenExpTable)
  40. body = fmt.Sprintf("expTbl: %#v\n", expTable)
  41. outputWriter.WriteString(body)
  42. logTable := genLogTable(expTable)
  43. body = fmt.Sprintf("logTbl: %#v\n", logTable)
  44. outputWriter.WriteString(body)
  45. mulTable := genMulTable(expTable, logTable)
  46. body = fmt.Sprintf("mulTbl: %#v\n", mulTable)
  47. outputWriter.WriteString(body)
  48. lowTable, highTable := genMulTableHalf(mulTable)
  49. body = fmt.Sprintf("lowTbl: %#v\n", lowTable)
  50. outputWriter.WriteString(body)
  51. body = fmt.Sprintf("highTbl: %#v\n", highTable)
  52. outputWriter.WriteString(body)
  53. var combTable [256][32]byte
  54. for i := range combTable {
  55. l := lowTable[i]
  56. for j := 0; j < 16; j++ {
  57. combTable[i][j] = l[j]
  58. }
  59. h := highTable[i][:]
  60. for k := 16; k < 32; k++ {
  61. combTable[i][k] = h[k-16]
  62. }
  63. }
  64. body = fmt.Sprintf("lowhighTbl: %#v\n", combTable)
  65. outputWriter.WriteString(body)
  66. inverseTable := genInverseTable(mulTable)
  67. body = fmt.Sprintf("inverseTbl: %#v\n", inverseTable)
  68. outputWriter.WriteString(body)
  69. outputWriter.Flush()
  70. }
  71. // generate primitive Polynomial
  72. func genPrimitivePolynomial() []polynomial {
  73. // drop Polynomial x,so the constant term must be 1
  74. // so there are 2^(deg-1) Polynomials
  75. cnt := 1 << (deg - 1)
  76. var polynomials []polynomial
  77. var p polynomial
  78. p[0] = 1
  79. p[deg] = 1
  80. // gen all Polynomials
  81. for i := 0; i < cnt; i++ {
  82. p = genPolynomial(p, 1)
  83. polynomials = append(polynomials, p)
  84. }
  85. // drop Polynomial x+1, so the cnt of Polynomials is odd
  86. var psRaw []polynomial
  87. for _, p := range polynomials {
  88. var n int
  89. for _, v := range p {
  90. if v == 1 {
  91. n++
  92. }
  93. }
  94. if n&1 != 0 {
  95. psRaw = append(psRaw, p)
  96. }
  97. }
  98. // order of primitive element == 2^deg -1 ?
  99. var ps []polynomial
  100. for _, p := range psRaw {
  101. lenTable := (1 << deg) - 1
  102. table := genExpTable(p, lenTable)
  103. var numOf1 int
  104. for _, v := range table {
  105. // cnt 1 in ExpTable
  106. if int(v) == 1 {
  107. numOf1++
  108. }
  109. }
  110. if numOf1 == 1 {
  111. ps = append(ps, p)
  112. }
  113. }
  114. return ps
  115. }
  116. func genPolynomial(p polynomial, i int) polynomial {
  117. if p[i] == 0 {
  118. p[i] = 1
  119. } else {
  120. p[i] = 0
  121. i++
  122. if i == deg {
  123. return p
  124. }
  125. p = genPolynomial(p, i)
  126. }
  127. return p
  128. }
  129. func genExpTable(primitivePolynomial polynomial, exp int) []byte {
  130. table := make([]byte, exp)
  131. var rawPolynomial polynomial
  132. rawPolynomial[1] = 1
  133. table[0] = byte(1)
  134. table[1] = byte(2)
  135. for i := 2; i < exp; i++ {
  136. rawPolynomial = expGrowPolynomial(rawPolynomial, primitivePolynomial)
  137. table[i] = byte(getValueOfPolynomial(rawPolynomial))
  138. }
  139. return table
  140. }
  141. func expGrowPolynomial(raw, primitivePolynomial polynomial) polynomial {
  142. var newP polynomial
  143. for i, v := range raw[:deg] {
  144. if v == 1 {
  145. newP[i+1] = 1
  146. }
  147. }
  148. if newP[deg] == 1 {
  149. for i, v := range primitivePolynomial[:deg] {
  150. if v == 1 {
  151. if newP[i] == 1 {
  152. newP[i] = 0
  153. } else {
  154. newP[i] = 1
  155. }
  156. }
  157. }
  158. }
  159. newP[deg] = 0
  160. return newP
  161. }
  162. func getValueOfPolynomial(p polynomial) uint8 {
  163. var v uint8
  164. for i, coefficient := range p[:deg] {
  165. if coefficient != 0 {
  166. add := 1 << uint8(i)
  167. v += uint8(add)
  168. }
  169. }
  170. return v
  171. }
  172. func genLogTable(expTable []byte) []byte {
  173. table := make([]byte, (1 << deg))
  174. //table[0] 无法由本原元的幂得到
  175. table[0] = 0
  176. for i, v := range expTable {
  177. table[v] = byte(i)
  178. }
  179. return table
  180. }
  181. func genMulTable(expTable, logTable []byte) [256][256]byte {
  182. var result [256][256]byte
  183. for a := range result {
  184. for b := range result[a] {
  185. if a == 0 || b == 0 {
  186. result[a][b] = 0
  187. continue
  188. }
  189. logA := int(logTable[a])
  190. logB := int(logTable[b])
  191. logSum := logA + logB
  192. for logSum >= 255 {
  193. logSum -= 255
  194. }
  195. result[a][b] = expTable[logSum]
  196. }
  197. }
  198. return result
  199. }
  200. func genMulTableHalf(mulTable [256][256]byte) (low [256][16]byte, high [256][16]byte) {
  201. for a := range low {
  202. for b := range low {
  203. //result := 0
  204. var result byte
  205. if !(a == 0 || b == 0) {
  206. //result = int(mulTable[a][b])
  207. result = mulTable[a][b]
  208. }
  209. // b & 00001111, [0,15]
  210. if (b & 0xf) == b {
  211. low[a][b] = result
  212. }
  213. // b & 11110000, [240,255]
  214. if (b & 0xf0) == b {
  215. high[a][b>>4] = result
  216. }
  217. }
  218. }
  219. return
  220. }
  221. func genInverseTable(mulTable [256][256]byte) [256]byte {
  222. var inVerseTable [256]byte
  223. for i, t := range mulTable {
  224. for j, v := range t {
  225. if int(v) == 1 {
  226. inVerseTable[i] = byte(j)
  227. }
  228. }
  229. }
  230. return inVerseTable
  231. }
  232. func formatPolynomial(p polynomial) string {
  233. var ps string
  234. for i := deg; i > 1; i-- {
  235. if p[i] == 1 {
  236. ps = ps + "x^" + strconv.FormatInt(int64(i), 10) + "+"
  237. }
  238. }
  239. if p[1] == 1 {
  240. ps = ps + "x+"
  241. }
  242. if p[0] == 1 {
  243. ps = ps + "1"
  244. } else {
  245. strings.TrimSuffix(ps, "+")
  246. }
  247. return ps
  248. }