reedsolomon.go 1.1 KB

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