errorcorrection.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package qr
  2. import (
  3. "github.com/boombuler/barcode/utils"
  4. )
  5. type errorCorrection struct {
  6. fld *utils.GaloisField
  7. polynomes map[byte][]byte
  8. }
  9. var ec *errorCorrection = newGF()
  10. func newGF() *errorCorrection {
  11. return &errorCorrection{utils.NewGaloisField(285), make(map[byte][]byte)}
  12. }
  13. func (ec *errorCorrection) getPolynomial(eccc byte) []byte {
  14. _, ok := ec.polynomes[eccc]
  15. if !ok {
  16. if eccc == 1 {
  17. ec.polynomes[eccc] = []byte{0, 0}
  18. } else {
  19. b1 := ec.getPolynomial(eccc - 1)
  20. result := make([]byte, eccc+1)
  21. for x := 0; x < len(b1); x++ {
  22. tmp1 := (int(b1[x]) + int(eccc-1)) % 255
  23. if x == 0 {
  24. result[x] = b1[x]
  25. } else {
  26. tmp0 := int(ec.fld.ALogTbl[result[x]]) ^ int(ec.fld.ALogTbl[b1[x]])
  27. result[x] = byte(ec.fld.LogTbl[tmp0])
  28. }
  29. result[x+1] = byte(tmp1)
  30. }
  31. ec.polynomes[eccc] = result
  32. }
  33. }
  34. return ec.polynomes[eccc]
  35. }
  36. func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
  37. tmp := make([]byte, len(data)+int(eccCount))
  38. copy(tmp, data)
  39. generator := ec.getPolynomial(eccCount)
  40. for i := 0; i < len(data); i++ {
  41. alpha := ec.fld.LogTbl[tmp[i]]
  42. for j := 0; j < len(generator); j++ {
  43. idx := (int(alpha) + int(generator[j])) % 255
  44. polyJ := ec.fld.ALogTbl[idx]
  45. tmp[i+j] = byte(ec.fld.AddOrSub(int(tmp[i+j]), polyJ))
  46. }
  47. }
  48. return tmp[len(data):]
  49. }