123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- 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 x,so 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
- }
|