git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/barcode/utils/reedsolomon.go (about) 1 package utils 2 3 import ( 4 "sync" 5 ) 6 7 type ReedSolomonEncoder struct { 8 gf *GaloisField 9 polynomes []*GFPoly 10 m *sync.Mutex 11 } 12 13 func NewReedSolomonEncoder(gf *GaloisField) *ReedSolomonEncoder { 14 return &ReedSolomonEncoder{ 15 gf, []*GFPoly{NewGFPoly(gf, []int{1})}, new(sync.Mutex), 16 } 17 } 18 19 func (rs *ReedSolomonEncoder) getPolynomial(degree int) *GFPoly { 20 rs.m.Lock() 21 defer rs.m.Unlock() 22 23 if degree >= len(rs.polynomes) { 24 last := rs.polynomes[len(rs.polynomes)-1] 25 for d := len(rs.polynomes); d <= degree; d++ { 26 next := last.Multiply(NewGFPoly(rs.gf, []int{1, rs.gf.ALogTbl[d-1+rs.gf.Base]})) 27 rs.polynomes = append(rs.polynomes, next) 28 last = next 29 } 30 } 31 return rs.polynomes[degree] 32 } 33 34 func (rs *ReedSolomonEncoder) Encode(data []int, eccCount int) []int { 35 generator := rs.getPolynomial(eccCount) 36 info := NewGFPoly(rs.gf, data) 37 info = info.MultByMonominal(eccCount, 1) 38 _, remainder := info.Divide(generator) 39 40 result := make([]int, eccCount) 41 numZero := int(eccCount) - len(remainder.Coefficients) 42 copy(result[numZero:], remainder.Coefficients) 43 return result 44 }