barcode/qr/errorcorrection.go

76 lines
1.5 KiB
Go

package qr
type galoisField struct {
aLogTbl []byte
logTbl []byte
polynomes map[byte][]byte
}
var gf *galoisField = newGF()
func newGF() *galoisField {
result := new(galoisField)
result.polynomes = make(map[byte][]byte)
result.aLogTbl = make([]byte, 255)
result.logTbl = make([]byte, 256)
result.aLogTbl[0] = 1
x := 1
for i := 1; i < 255; i++ {
x = x * 2
if x > 255 {
x = x ^ 285
}
result.aLogTbl[i] = byte(x)
}
for i := 1; i < 255; i++ {
result.logTbl[result.aLogTbl[i]] = byte(i)
}
return result
}
func (gf *galoisField) getPolynom(eccc byte) []byte {
_, ok := gf.polynomes[eccc]
if !ok {
if eccc == 1 {
gf.polynomes[eccc] = []byte{0, 0}
} else {
b1 := gf.getPolynom(eccc - 1)
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(gf.aLogTbl[result[x]]) ^ int(gf.aLogTbl[b1[x]])
result[x] = gf.logTbl[tmp0]
}
result[x+1] = byte(tmp1)
}
gf.polynomes[eccc] = result
}
}
return gf.polynomes[eccc]
}
func (gf *galoisField) calcECC(data []byte, eccCount byte) []byte {
tmp := make([]byte, len(data)+int(eccCount))
copy(tmp, data)
generator := gf.getPolynom(eccCount)
for i := 0; i < len(data); i++ {
alpha := gf.logTbl[tmp[i]]
for j := 0; j < len(generator); j++ {
idx := (int(alpha) + int(generator[j])) % 255
polyJ := gf.aLogTbl[idx]
tmp[i+j] = (tmp[i+j] ^ polyJ)
}
}
return tmp[len(data):]
}