barcode/qr/errorcorrection.go

59 lines
1.3 KiB
Go
Raw Normal View History

2013-12-11 13:31:11 +00:00
package qr
import (
"github.com/boombuler/barcode/utils"
)
type errorCorrection struct {
fld *utils.GaloisField
2013-12-11 13:31:11 +00:00
polynomes map[byte][]byte
}
var ec *errorCorrection = newGF()
2013-12-11 13:31:11 +00:00
func newGF() *errorCorrection {
return &errorCorrection{utils.NewGaloisField(285), make(map[byte][]byte)}
2013-12-11 13:31:11 +00:00
}
func (ec *errorCorrection) getPolynomial(eccc byte) []byte {
_, ok := ec.polynomes[eccc]
2013-12-11 13:31:11 +00:00
if !ok {
if eccc == 1 {
ec.polynomes[eccc] = []byte{0, 0}
2013-12-11 13:31:11 +00:00
} else {
b1 := ec.getPolynomial(eccc - 1)
2013-12-11 13:31:11 +00:00
result := make([]byte, eccc+1)
for x := 0; x < len(b1); x++ {
tmp1 := (int(b1[x]) + int(eccc-1)) % 255
if x == 0 {
result[x] = b1[x]
} else {
tmp0 := int(ec.fld.ALogTbl[result[x]]) ^ int(ec.fld.ALogTbl[b1[x]])
result[x] = byte(ec.fld.LogTbl[tmp0])
2013-12-11 13:31:11 +00:00
}
result[x+1] = byte(tmp1)
}
ec.polynomes[eccc] = result
2013-12-11 13:31:11 +00:00
}
}
return ec.polynomes[eccc]
2013-12-11 13:31:11 +00:00
}
func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
2013-12-11 13:31:11 +00:00
tmp := make([]byte, len(data)+int(eccCount))
copy(tmp, data)
generator := ec.getPolynomial(eccCount)
2013-12-11 13:31:11 +00:00
for i := 0; i < len(data); i++ {
alpha := ec.fld.LogTbl[tmp[i]]
2013-12-11 13:31:11 +00:00
for j := 0; j < len(generator); j++ {
idx := (int(alpha) + int(generator[j])) % 255
polyJ := ec.fld.ALogTbl[idx]
tmp[i+j] = byte(ec.fld.AddOrSub(int(tmp[i+j]), polyJ))
2013-12-11 13:31:11 +00:00
}
}
return tmp[len(data):]
}