git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/barcode/utils/galoisfield.go (about) 1 package utils 2 3 // GaloisField encapsulates galois field arithmetics 4 type GaloisField struct { 5 Size int 6 Base int 7 ALogTbl []int 8 LogTbl []int 9 } 10 11 // NewGaloisField creates a new galois field 12 func NewGaloisField(pp, fieldSize, b int) *GaloisField { 13 result := new(GaloisField) 14 15 result.Size = fieldSize 16 result.Base = b 17 result.ALogTbl = make([]int, fieldSize) 18 result.LogTbl = make([]int, fieldSize) 19 20 x := 1 21 for i := 0; i < fieldSize; i++ { 22 result.ALogTbl[i] = x 23 x = x * 2 24 if x >= fieldSize { 25 x = (x ^ pp) & (fieldSize - 1) 26 } 27 } 28 29 for i := 0; i < fieldSize; i++ { 30 result.LogTbl[result.ALogTbl[i]] = int(i) 31 } 32 33 return result 34 } 35 36 func (gf *GaloisField) Zero() *GFPoly { 37 return NewGFPoly(gf, []int{0}) 38 } 39 40 // AddOrSub add or substract two numbers 41 func (gf *GaloisField) AddOrSub(a, b int) int { 42 return a ^ b 43 } 44 45 // Multiply multiplys two numbers 46 func (gf *GaloisField) Multiply(a, b int) int { 47 if a == 0 || b == 0 { 48 return 0 49 } 50 return gf.ALogTbl[(gf.LogTbl[a]+gf.LogTbl[b])%(gf.Size-1)] 51 } 52 53 // Divide divides two numbers 54 func (gf *GaloisField) Divide(a, b int) int { 55 if b == 0 { 56 panic("divide by zero") 57 } else if a == 0 { 58 return 0 59 } 60 return gf.ALogTbl[(gf.LogTbl[a]-gf.LogTbl[b])%(gf.Size-1)] 61 } 62 63 func (gf *GaloisField) Invers(num int) int { 64 return gf.ALogTbl[(gf.Size-1)-gf.LogTbl[num]] 65 }