forked from makiuchi-d/gozxing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reedsolomon_encoder.go
59 lines (54 loc) · 1.73 KB
/
reedsolomon_encoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package reedsolomon
import (
errors "golang.org/x/xerrors"
)
type ReedSolomonEncoder struct {
field *GenericGF
cachedGenerators []*GenericGFPoly
}
func NewReedSolomonEncoder(field *GenericGF) *ReedSolomonEncoder {
gen, _ := NewGenericGFPoly(field, []int{1})
return &ReedSolomonEncoder{
field: field,
cachedGenerators: []*GenericGFPoly{gen},
}
}
func (this *ReedSolomonEncoder) buildGenerator(degree int) *GenericGFPoly {
size := len(this.cachedGenerators)
if degree >= size {
lastGenerator := this.cachedGenerators[size-1]
for d := size; d <= degree; d++ {
poly, _ := NewGenericGFPoly(
this.field, []int{1, this.field.Exp(d - 1 + this.field.GetGeneratorBase())})
nextGenerator, _ := lastGenerator.Multiply(poly)
this.cachedGenerators = append(this.cachedGenerators, nextGenerator)
lastGenerator = nextGenerator
}
}
return this.cachedGenerators[degree]
}
func (this *ReedSolomonEncoder) Encode(toEncode []int, ecBytes int) error {
if ecBytes <= 0 {
return errors.New("(IllegalArgumentException: No error correction bytes")
}
dataBytes := len(toEncode) - ecBytes
if dataBytes <= 0 {
return errors.New("IllegalArgumentException: No data bytes provided")
}
generator := this.buildGenerator(ecBytes)
infoCoefficients := make([]int, dataBytes)
copy(infoCoefficients, toEncode)
info, _ := NewGenericGFPoly(this.field, infoCoefficients)
info, _ = info.MultiplyByMonomial(ecBytes, 1)
_, remainder, e := info.Divide(generator)
if e != nil {
return e
}
coefficients := remainder.GetCoefficients()
numZeroCoefficients := ecBytes - len(coefficients)
for i := 0; i < numZeroCoefficients; i++ {
toEncode[dataBytes+i] = 0
}
copy(toEncode[dataBytes+numZeroCoefficients:], coefficients)
return nil
}