errorcorrection.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package qr
  2. type galoisField struct {
  3. aLogTbl []byte
  4. logTbl []byte
  5. polynomes map[byte][]byte
  6. }
  7. var gf *galoisField = newGF()
  8. func newGF() *galoisField {
  9. result := new(galoisField)
  10. result.polynomes = make(map[byte][]byte)
  11. result.aLogTbl = make([]byte, 255)
  12. result.logTbl = make([]byte, 256)
  13. result.aLogTbl[0] = 1
  14. x := 1
  15. for i := 1; i < 255; i++ {
  16. x = x * 2
  17. if x > 255 {
  18. x = x ^ 285
  19. }
  20. result.aLogTbl[i] = byte(x)
  21. }
  22. for i := 1; i < 255; i++ {
  23. result.logTbl[result.aLogTbl[i]] = byte(i)
  24. }
  25. return result
  26. }
  27. func (gf *galoisField) getPolynom(eccc byte) []byte {
  28. _, ok := gf.polynomes[eccc]
  29. if !ok {
  30. if eccc == 1 {
  31. gf.polynomes[eccc] = []byte{0, 0}
  32. } else {
  33. b1 := gf.getPolynom(eccc - 1)
  34. result := make([]byte, eccc+1)
  35. for x := 0; x < len(b1); x++ {
  36. tmp1 := (int(b1[x]) + int(eccc-1)) % 255
  37. if x == 0 {
  38. result[x] = b1[x]
  39. } else {
  40. tmp0 := int(gf.aLogTbl[result[x]]) ^ int(gf.aLogTbl[b1[x]])
  41. result[x] = gf.logTbl[tmp0]
  42. }
  43. result[x+1] = byte(tmp1)
  44. }
  45. gf.polynomes[eccc] = result
  46. }
  47. }
  48. return gf.polynomes[eccc]
  49. }
  50. func (gf *galoisField) calcECC(data []byte, eccCount byte) []byte {
  51. tmp := make([]byte, len(data)+int(eccCount))
  52. copy(tmp, data)
  53. generator := gf.getPolynom(eccCount)
  54. for i := 0; i < len(data); i++ {
  55. alpha := gf.logTbl[tmp[i]]
  56. for j := 0; j < len(generator); j++ {
  57. idx := (int(alpha) + int(generator[j])) % 255
  58. polyJ := gf.aLogTbl[idx]
  59. tmp[i+j] = (tmp[i+j] ^ polyJ)
  60. }
  61. }
  62. return tmp[len(data):]
  63. }