errorcorrection.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package qr
  2. import (
  3. "github.com/boombuler/barcode/utils"
  4. "sync"
  5. )
  6. type errorCorrection struct {
  7. fld *utils.GaloisField
  8. m *sync.Mutex
  9. polynomes []*utils.GFPoly
  10. }
  11. var ec = newGF()
  12. func newGF() *errorCorrection {
  13. fld := utils.NewGaloisField(285)
  14. return &errorCorrection{fld,
  15. new(sync.Mutex),
  16. []*utils.GFPoly{
  17. utils.NewGFPoly(fld, []byte{1}),
  18. },
  19. }
  20. }
  21. func (ec *errorCorrection) getPolynomial(degree int) *utils.GFPoly {
  22. ec.m.Lock()
  23. defer ec.m.Unlock()
  24. if degree >= len(ec.polynomes) {
  25. last := ec.polynomes[len(ec.polynomes)-1]
  26. for d := len(ec.polynomes); d <= degree; d++ {
  27. next := last.Multiply(utils.NewGFPoly(ec.fld, []byte{1, byte(ec.fld.ALogTbl[d-1])}))
  28. ec.polynomes = append(ec.polynomes, next)
  29. last = next
  30. }
  31. }
  32. return ec.polynomes[degree]
  33. }
  34. func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
  35. generator := ec.getPolynomial(int(eccCount))
  36. info := utils.NewGFPoly(ec.fld, data)
  37. info = info.MultByMonominal(int(eccCount), 1)
  38. _, remainder := info.Divide(generator)
  39. result := make([]byte, eccCount)
  40. numZero := int(eccCount) - len(remainder.Coefficients)
  41. copy(result[numZero:], remainder.Coefficients)
  42. return result
  43. }