76 lines
1.5 KiB
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):]
|
|
}
|