frp/vendor/github.com/templexxx/reedsolomon/mathtool/gentbls.go

271 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
// set deg here
const deg = 8 // <= 8
type polynomial [deg + 1]byte
func main() {
f, err := os.OpenFile("tables", os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
log.Fatalln(err)
}
defer f.Close()
outputWriter := bufio.NewWriter(f)
ps := genPrimitivePolynomial()
title := strconv.FormatInt(int64(deg), 10) + " degree primitive polynomial\n"
var pss string
for i, p := range ps {
pf := formatPolynomial(p)
pf = strconv.FormatInt(int64(i+1), 10) + ". " + pf + ";\n"
pss = pss + pf
}
body := fmt.Sprintf(title+"%v", pss)
outputWriter.WriteString(body)
//set primitive polynomial here to generator tables
//x^8+x^4+x^3+x^2+1
var primitivePolynomial polynomial
primitivePolynomial[0] = 1
primitivePolynomial[2] = 1
primitivePolynomial[3] = 1
primitivePolynomial[4] = 1
primitivePolynomial[8] = 1
lenExpTable := (1 << deg) - 1
expTable := genExpTable(primitivePolynomial, lenExpTable)
body = fmt.Sprintf("expTbl: %#v\n", expTable)
outputWriter.WriteString(body)
logTable := genLogTable(expTable)
body = fmt.Sprintf("logTbl: %#v\n", logTable)
outputWriter.WriteString(body)
mulTable := genMulTable(expTable, logTable)
body = fmt.Sprintf("mulTbl: %#v\n", mulTable)
outputWriter.WriteString(body)
lowTable, highTable := genMulTableHalf(mulTable)
body = fmt.Sprintf("lowTbl: %#v\n", lowTable)
outputWriter.WriteString(body)
body = fmt.Sprintf("highTbl: %#v\n", highTable)
outputWriter.WriteString(body)
var combTable [256][32]byte
for i := range combTable {
l := lowTable[i]
for j := 0; j < 16; j++ {
combTable[i][j] = l[j]
}
h := highTable[i][:]
for k := 16; k < 32; k++ {
combTable[i][k] = h[k-16]
}
}
body = fmt.Sprintf("lowhighTbl: %#v\n", combTable)
outputWriter.WriteString(body)
inverseTable := genInverseTable(mulTable)
body = fmt.Sprintf("inverseTbl: %#v\n", inverseTable)
outputWriter.WriteString(body)
outputWriter.Flush()
}
// generate primitive Polynomial
func genPrimitivePolynomial() []polynomial {
// drop Polynomial xso the constant term must be 1
// so there are 2^(deg-1) Polynomials
cnt := 1 << (deg - 1)
var polynomials []polynomial
var p polynomial
p[0] = 1
p[deg] = 1
// gen all Polynomials
for i := 0; i < cnt; i++ {
p = genPolynomial(p, 1)
polynomials = append(polynomials, p)
}
// drop Polynomial x+1, so the cnt of Polynomials is odd
var psRaw []polynomial
for _, p := range polynomials {
var n int
for _, v := range p {
if v == 1 {
n++
}
}
if n&1 != 0 {
psRaw = append(psRaw, p)
}
}
// order of primitive element == 2^deg -1 ?
var ps []polynomial
for _, p := range psRaw {
lenTable := (1 << deg) - 1
table := genExpTable(p, lenTable)
var numOf1 int
for _, v := range table {
// cnt 1 in ExpTable
if int(v) == 1 {
numOf1++
}
}
if numOf1 == 1 {
ps = append(ps, p)
}
}
return ps
}
func genPolynomial(p polynomial, i int) polynomial {
if p[i] == 0 {
p[i] = 1
} else {
p[i] = 0
i++
if i == deg {
return p
}
p = genPolynomial(p, i)
}
return p
}
func genExpTable(primitivePolynomial polynomial, exp int) []byte {
table := make([]byte, exp)
var rawPolynomial polynomial
rawPolynomial[1] = 1
table[0] = byte(1)
table[1] = byte(2)
for i := 2; i < exp; i++ {
rawPolynomial = expGrowPolynomial(rawPolynomial, primitivePolynomial)
table[i] = byte(getValueOfPolynomial(rawPolynomial))
}
return table
}
func expGrowPolynomial(raw, primitivePolynomial polynomial) polynomial {
var newP polynomial
for i, v := range raw[:deg] {
if v == 1 {
newP[i+1] = 1
}
}
if newP[deg] == 1 {
for i, v := range primitivePolynomial[:deg] {
if v == 1 {
if newP[i] == 1 {
newP[i] = 0
} else {
newP[i] = 1
}
}
}
}
newP[deg] = 0
return newP
}
func getValueOfPolynomial(p polynomial) uint8 {
var v uint8
for i, coefficient := range p[:deg] {
if coefficient != 0 {
add := 1 << uint8(i)
v += uint8(add)
}
}
return v
}
func genLogTable(expTable []byte) []byte {
table := make([]byte, (1 << deg))
//table[0] 无法由本原元的幂得到
table[0] = 0
for i, v := range expTable {
table[v] = byte(i)
}
return table
}
func genMulTable(expTable, logTable []byte) [256][256]byte {
var result [256][256]byte
for a := range result {
for b := range result[a] {
if a == 0 || b == 0 {
result[a][b] = 0
continue
}
logA := int(logTable[a])
logB := int(logTable[b])
logSum := logA + logB
for logSum >= 255 {
logSum -= 255
}
result[a][b] = expTable[logSum]
}
}
return result
}
func genMulTableHalf(mulTable [256][256]byte) (low [256][16]byte, high [256][16]byte) {
for a := range low {
for b := range low {
//result := 0
var result byte
if !(a == 0 || b == 0) {
//result = int(mulTable[a][b])
result = mulTable[a][b]
}
// b & 00001111, [0,15]
if (b & 0xf) == b {
low[a][b] = result
}
// b & 11110000, [240,255]
if (b & 0xf0) == b {
high[a][b>>4] = result
}
}
}
return
}
func genInverseTable(mulTable [256][256]byte) [256]byte {
var inVerseTable [256]byte
for i, t := range mulTable {
for j, v := range t {
if int(v) == 1 {
inVerseTable[i] = byte(j)
}
}
}
return inVerseTable
}
func formatPolynomial(p polynomial) string {
var ps string
for i := deg; i > 1; i-- {
if p[i] == 1 {
ps = ps + "x^" + strconv.FormatInt(int64(i), 10) + "+"
}
}
if p[1] == 1 {
ps = ps + "x+"
}
if p[0] == 1 {
ps = ps + "1"
} else {
strings.TrimSuffix(ps, "+")
}
return ps
}