- commit
- d3700c0954bc0485491ad762126a21a134fbe4e9
- parent
- f88a46e3cca8631f37b9988bd169f51294086dfb
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-03-01 02:24
refactor/minimize code
Diffstat
| D | .travis.yml | 8 | -------- |
| A | bitset.go | 28 | ++++++++++++++++++++++++++++ |
| D | bitset/bitset.go | 273 | ------------------------------------------------------------ |
| A | ecc.go | 132 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | encoder.go | 486 | ------------------------------------------------------------ |
| A | gf.go | 94 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | qrcode.go | 619 | ++++++++----------------------------------------------------- |
| M | qrcode/main.go | 76 | +------------------------------------------------------------ |
| D | reedsolomon/gf2_8.go | 387 | ------------------------------------------------------------ |
| D | reedsolomon/gf_poly.go | 216 | ------------------------------------------------------------ |
| D | reedsolomon/reed_solomon.go | 73 | ------------------------------------------------------------ |
| D | regular_symbol.go | 315 | ------------------------------------------------------------ |
| A | render.go | 186 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | symbol.go | 309 | ------------------------------------------------------------ |
| M | version.go | 3371 | +++++++------------------------------------------------------ |
15 files changed, 889 insertions, 5684 deletions
diff --git a/.travis.yml b/.travis.yml
@@ -1,8 +0,0 @@1 -1 language: go2 -13 -1 go:4 -1 - 1.75 -16 -1 script:7 -1 - go test -v ./...8 -1
diff --git a/bitset.go b/bitset.go
@@ -0,0 +1,28 @@
-1 1 package qrcode
-1 2
-1 3 type Bitset struct {
-1 4 Length int
-1 5 Bytes []byte
-1 6 }
-1 7
-1 8 func NewBitset() *Bitset {
-1 9 return &Bitset{Length: 0, Bytes: make([]byte, 0)}
-1 10 }
-1 11
-1 12 func (b *Bitset) Write(value uint, length int) {
-1 13 for i := length - 1; i >= 0; i-- {
-1 14 if b.Length/8 == len(b.Bytes) {
-1 15 b.Bytes = append(b.Bytes, 0)
-1 16 }
-1 17
-1 18 if value&(1<<i) != 0 {
-1 19 b.Bytes[b.Length/8] |= 0x80 >> (b.Length % 8)
-1 20 }
-1 21
-1 22 b.Length++
-1 23 }
-1 24 }
-1 25
-1 26 func (b *Bitset) At(index int) bool {
-1 27 return b.Bytes[index/8]&(0x80>>(index%8)) != 0
-1 28 }
diff --git a/bitset/bitset.go b/bitset/bitset.go
@@ -1,273 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 // Package bitset implements an append only bit array.5 -1 //6 -1 // To create a Bitset and append some bits:7 -1 // // Bitset Contents8 -1 // b := bitset.New() // {}9 -1 // b.AppendBools(true, true, false) // {1, 1, 0}10 -1 // b.AppendBools(true) // {1, 1, 0, 1}11 -1 // b.AppendValue(0x02, 4) // {1, 1, 0, 1, 0, 0, 1, 0}12 -1 //13 -1 // To read values:14 -1 //15 -1 // len := b.Len() // 816 -1 // v := b.At(0) // 117 -1 // v = b.At(1) // 118 -1 // v = b.At(2) // 019 -1 // v = b.At(8) // 020 -1 package bitset21 -122 -1 import (23 -1 "bytes"24 -1 "fmt"25 -1 "log"26 -1 )27 -128 -1 const (29 -1 b0 = false30 -1 b1 = true31 -1 )32 -133 -1 // Bitset stores an array of bits.34 -1 type Bitset struct {35 -1 // The number of bits stored.36 -1 numBits int37 -138 -1 // Storage for individual bits.39 -1 bits []byte40 -1 }41 -142 -1 // New returns an initialised Bitset with optional initial bits v.43 -1 func New(v ...bool) *Bitset {44 -1 b := &Bitset{numBits: 0, bits: make([]byte, 0)}45 -1 b.AppendBools(v...)46 -147 -1 return b48 -1 }49 -150 -1 // Clone returns a copy.51 -1 func Clone(from *Bitset) *Bitset {52 -1 return &Bitset{numBits: from.numBits, bits: from.bits[:]}53 -1 }54 -155 -1 // Substr returns a substring, consisting of the bits from indexes start to end.56 -1 func (b *Bitset) Substr(start int, end int) *Bitset {57 -1 if start > end || end > b.numBits {58 -1 log.Panicf("Out of range start=%d end=%d numBits=%d", start, end, b.numBits)59 -1 }60 -161 -1 result := New()62 -1 result.ensureCapacity(end - start)63 -164 -1 for i := start; i < end; i++ {65 -1 if b.At(i) {66 -1 result.bits[result.numBits/8] |= 0x80 >> uint(result.numBits%8)67 -1 }68 -1 result.numBits++69 -1 }70 -171 -1 return result72 -1 }73 -174 -1 // NewFromBase2String constructs and returns a Bitset from a string. The string75 -1 // consists of '1', '0' or ' ' characters, e.g. "1010 0101". The '1' and '0'76 -1 // characters represent true/false bits respectively, and ' ' characters are77 -1 // ignored.78 -1 //79 -1 // The function panics if the input string contains other characters.80 -1 func NewFromBase2String(b2string string) *Bitset {81 -1 b := &Bitset{numBits: 0, bits: make([]byte, 0)}82 -183 -1 for _, c := range b2string {84 -1 switch c {85 -1 case '1':86 -1 b.AppendBools(true)87 -1 case '0':88 -1 b.AppendBools(false)89 -1 case ' ':90 -1 default:91 -1 log.Panicf("Invalid char %c in NewFromBase2String", c)92 -1 }93 -1 }94 -195 -1 return b96 -1 }97 -198 -1 // AppendBytes appends a list of whole bytes.99 -1 func (b *Bitset) AppendBytes(data []byte) {100 -1 for _, d := range data {101 -1 b.AppendByte(d, 8)102 -1 }103 -1 }104 -1105 -1 // AppendByte appends the numBits least significant bits from value.106 -1 func (b *Bitset) AppendByte(value byte, numBits int) {107 -1 b.ensureCapacity(numBits)108 -1109 -1 if numBits > 8 {110 -1 log.Panicf("numBits %d out of range 0-8", numBits)111 -1 }112 -1113 -1 for i := numBits - 1; i >= 0; i-- {114 -1 if value&(1<<uint(i)) != 0 {115 -1 b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)116 -1 }117 -1118 -1 b.numBits++119 -1 }120 -1 }121 -1122 -1 // AppendUint32 appends the numBits least significant bits from value.123 -1 func (b *Bitset) AppendUint32(value uint32, numBits int) {124 -1 b.ensureCapacity(numBits)125 -1126 -1 if numBits > 32 {127 -1 log.Panicf("numBits %d out of range 0-32", numBits)128 -1 }129 -1130 -1 for i := numBits - 1; i >= 0; i-- {131 -1 if value&(1<<uint(i)) != 0 {132 -1 b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)133 -1 }134 -1135 -1 b.numBits++136 -1 }137 -1 }138 -1139 -1 // ensureCapacity ensures the Bitset can store an additional |numBits|.140 -1 //141 -1 // The underlying array is expanded if necessary. To prevent frequent142 -1 // reallocation, expanding the underlying array at least doubles its capacity.143 -1 func (b *Bitset) ensureCapacity(numBits int) {144 -1 numBits += b.numBits145 -1146 -1 newNumBytes := numBits / 8147 -1 if numBits%8 != 0 {148 -1 newNumBytes++149 -1 }150 -1151 -1 if len(b.bits) >= newNumBytes {152 -1 return153 -1 }154 -1155 -1 b.bits = append(b.bits, make([]byte, newNumBytes+2*len(b.bits))...)156 -1 }157 -1158 -1 // Append bits copied from |other|.159 -1 //160 -1 // The new length is b.Len() + other.Len().161 -1 func (b *Bitset) Append(other *Bitset) {162 -1 b.ensureCapacity(other.numBits)163 -1164 -1 for i := 0; i < other.numBits; i++ {165 -1 if other.At(i) {166 -1 b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)167 -1 }168 -1 b.numBits++169 -1 }170 -1 }171 -1172 -1 // AppendBools appends bits to the Bitset.173 -1 func (b *Bitset) AppendBools(bits ...bool) {174 -1 b.ensureCapacity(len(bits))175 -1176 -1 for _, v := range bits {177 -1 if v {178 -1 b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8)179 -1 }180 -1 b.numBits++181 -1 }182 -1 }183 -1184 -1 // AppendNumBools appends num bits of value value.185 -1 func (b *Bitset) AppendNumBools(num int, value bool) {186 -1 for i := 0; i < num; i++ {187 -1 b.AppendBools(value)188 -1 }189 -1 }190 -1191 -1 // String returns a human readable representation of the Bitset's contents.192 -1 func (b *Bitset) String() string {193 -1 var bitString string194 -1 for i := 0; i < b.numBits; i++ {195 -1 if (i % 8) == 0 {196 -1 bitString += " "197 -1 }198 -1199 -1 if (b.bits[i/8] & (0x80 >> byte(i%8))) != 0 {200 -1 bitString += "1"201 -1 } else {202 -1 bitString += "0"203 -1 }204 -1 }205 -1206 -1 return fmt.Sprintf("numBits=%d, bits=%s", b.numBits, bitString)207 -1 }208 -1209 -1 // Len returns the length of the Bitset in bits.210 -1 func (b *Bitset) Len() int {211 -1 return b.numBits212 -1 }213 -1214 -1 // Bits returns the contents of the Bitset.215 -1 func (b *Bitset) Bits() []bool {216 -1 result := make([]bool, b.numBits)217 -1218 -1 var i int219 -1 for i = 0; i < b.numBits; i++ {220 -1 result[i] = (b.bits[i/8] & (0x80 >> byte(i%8))) != 0221 -1 }222 -1223 -1 return result224 -1 }225 -1226 -1 // At returns the value of the bit at |index|.227 -1 func (b *Bitset) At(index int) bool {228 -1 if index >= b.numBits {229 -1 log.Panicf("Index %d out of range", index)230 -1 }231 -1232 -1 return (b.bits[index/8] & (0x80 >> byte(index%8))) != 0233 -1 }234 -1235 -1 // Equals returns true if the Bitset equals other.236 -1 func (b *Bitset) Equals(other *Bitset) bool {237 -1 if b.numBits != other.numBits {238 -1 return false239 -1 }240 -1241 -1 if !bytes.Equal(b.bits[0:b.numBits/8], other.bits[0:b.numBits/8]) {242 -1 return false243 -1 }244 -1245 -1 for i := 8 * (b.numBits / 8); i < b.numBits; i++ {246 -1 a := (b.bits[i/8] & (0x80 >> byte(i%8)))247 -1 b := (other.bits[i/8] & (0x80 >> byte(i%8)))248 -1249 -1 if a != b {250 -1 return false251 -1 }252 -1 }253 -1254 -1 return true255 -1 }256 -1257 -1 // ByteAt returns a byte consisting of upto 8 bits starting at index.258 -1 func (b *Bitset) ByteAt(index int) byte {259 -1 if index < 0 || index >= b.numBits {260 -1 log.Panicf("Index %d out of range", index)261 -1 }262 -1263 -1 var result byte264 -1265 -1 for i := index; i < index+8 && i < b.numBits; i++ {266 -1 result <<= 1267 -1 if b.At(i) {268 -1 result |= 1269 -1 }270 -1 }271 -1272 -1 return result273 -1 }
diff --git a/ecc.go b/ecc.go
@@ -0,0 +1,132 @@
-1 1 package qrcode
-1 2
-1 3 type Polynomial struct {
-1 4 term []gfElement
-1 5 }
-1 6
-1 7 func newPolynomial(data []byte) Polynomial {
-1 8 result := Polynomial{term: make([]gfElement, len(data))}
-1 9 for j := 0; j < len(data); j += 1 {
-1 10 result.term[len(data) - j - 1] = gfElement(data[j])
-1 11 }
-1 12 return result
-1 13 }
-1 14
-1 15 func newMonomial(term gfElement, degree int) Polynomial {
-1 16 if term == gfZero {
-1 17 return Polynomial{}
-1 18 }
-1 19 result := Polynomial{term: make([]gfElement, degree+1)}
-1 20 result.term[degree] = term
-1 21 return result
-1 22 }
-1 23
-1 24 func (p Polynomial) data(numTerms int) []byte {
-1 25 result := make([]byte, numTerms)
-1 26
-1 27 for j := len(p.term) - 1; j >= 0 && j < numTerms; j-- {
-1 28 result[numTerms - j - 1] = byte(p.term[j])
-1 29 }
-1 30
-1 31 return result
-1 32 }
-1 33
-1 34 func (p Polynomial) numTerms() int {
-1 35 return len(p.term)
-1 36 }
-1 37
-1 38 func (p Polynomial) normalised() Polynomial {
-1 39 numTerms := p.numTerms()
-1 40 maxNonzeroTerm := numTerms - 1
-1 41
-1 42 for i := numTerms - 1; i >= 0; i-- {
-1 43 if p.term[i] != 0 {
-1 44 break
-1 45 }
-1 46
-1 47 maxNonzeroTerm = i - 1
-1 48 }
-1 49
-1 50 if maxNonzeroTerm < 0 {
-1 51 return Polynomial{}
-1 52 } else if maxNonzeroTerm < numTerms-1 {
-1 53 p.term = p.term[0 : maxNonzeroTerm+1]
-1 54 }
-1 55
-1 56 return p
-1 57 }
-1 58
-1 59 func polyAdd(a, b Polynomial) Polynomial {
-1 60 numATerms := a.numTerms()
-1 61 numBTerms := b.numTerms()
-1 62
-1 63 numTerms := numATerms
-1 64 if numBTerms > numTerms {
-1 65 numTerms = numBTerms
-1 66 }
-1 67
-1 68 result := Polynomial{term: make([]gfElement, numTerms)}
-1 69
-1 70 for i := 0; i < numTerms; i++ {
-1 71 switch {
-1 72 case numATerms > i && numBTerms > i:
-1 73 result.term[i] = a.term[i] ^ b.term[i]
-1 74 case numATerms > i:
-1 75 result.term[i] = a.term[i]
-1 76 default:
-1 77 result.term[i] = b.term[i]
-1 78 }
-1 79 }
-1 80
-1 81 return result.normalised()
-1 82 }
-1 83
-1 84 func polyMultiply(a, b Polynomial) Polynomial {
-1 85 numATerms := a.numTerms()
-1 86 numBTerms := b.numTerms()
-1 87
-1 88 result := Polynomial{term: make([]gfElement, numATerms+numBTerms)}
-1 89
-1 90 for i := 0; i < numATerms; i++ {
-1 91 for j := 0; j < numBTerms; j++ {
-1 92 if a.term[i] != 0 && b.term[j] != 0 {
-1 93 monomial := newMonomial(gfMultiply(a.term[i], b.term[j]), i + j)
-1 94 result = polyAdd(result, monomial)
-1 95 }
-1 96 }
-1 97 }
-1 98
-1 99 return result.normalised()
-1 100 }
-1 101
-1 102 func polyRemainder(numerator, denominator Polynomial) Polynomial {
-1 103 remainder := numerator
-1 104
-1 105 for remainder.numTerms() >= denominator.numTerms() {
-1 106 degree := remainder.numTerms() - denominator.numTerms()
-1 107 coefficient := gfDivide(remainder.term[remainder.numTerms()-1],
-1 108 denominator.term[denominator.numTerms()-1])
-1 109
-1 110 divisor := polyMultiply(denominator,
-1 111 newMonomial(coefficient, degree))
-1 112
-1 113 remainder = polyAdd(remainder, divisor)
-1 114 }
-1 115
-1 116 return remainder.normalised()
-1 117 }
-1 118
-1 119 // ISO/IEC 18004 table 9 specifies the numECBytes required.
-1 120 func getErrorCorrection(data []byte, numECBytes int) []byte {
-1 121 ecpoly := newPolynomial(data)
-1 122 ecpoly = polyMultiply(ecpoly, newMonomial(gfOne, numECBytes))
-1 123
-1 124 generator := Polynomial{term: []gfElement{1}}
-1 125 for i := 0; i < numECBytes; i++ {
-1 126 nextPoly := Polynomial{term: []gfElement{gfExpTable[i], 1}}
-1 127 generator = polyMultiply(generator, nextPoly)
-1 128 }
-1 129
-1 130 remainder := polyRemainder(ecpoly, generator)
-1 131 return remainder.data(numECBytes)
-1 132 }
diff --git a/encoder.go b/encoder.go
@@ -1,486 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 package qrcode5 -16 -1 import (7 -1 "errors"8 -1 "log"9 -110 -1 bitset "github.com/skip2/go-qrcode/bitset"11 -1 )12 -113 -1 // Data encoding.14 -1 //15 -1 // The main data portion of a QR Code consists of one or more segments of data.16 -1 // A segment consists of:17 -1 //18 -1 // - The segment Data Mode: numeric, alphanumeric, or byte.19 -1 // - The length of segment in bits.20 -1 // - Encoded data.21 -1 //22 -1 // For example, the string "123ZZ#!#!" may be represented as:23 -1 //24 -1 // [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"]25 -1 //26 -1 // Multiple data modes exist to minimise the size of encoded data. For example,27 -1 // 8-bit bytes require 8 bits to encode each, but base 10 numeric data can be28 -1 // encoded at a higher density of 3 numbers (e.g. 123) per 10 bits.29 -1 //30 -1 // Some data can be represented in multiple modes. Numeric data can be31 -1 // represented in all three modes, whereas alphanumeric data (e.g. 'A') can be32 -1 // represented in alphanumeric and byte mode.33 -1 //34 -1 // Starting a new segment (to use a different Data Mode) has a cost, the bits to35 -1 // state the new segment Data Mode and length. To minimise each QR Code's symbol36 -1 // size, an optimisation routine coalesces segment types where possible, to37 -1 // reduce the encoded data length.38 -1 //39 -1 // There are several other data modes available (e.g. Kanji mode) which are not40 -1 // implemented here.41 -142 -1 // A segment encoding mode.43 -1 type dataMode uint844 -145 -1 const (46 -1 // Each dataMode is a subset of the subsequent dataMode:47 -1 // dataModeNone < dataModeNumeric < dataModeAlphanumeric < dataModeByte48 -1 //49 -1 // This ordering is important for determining which data modes a character can50 -1 // be encoded with. E.g. 'E' can be encoded in both dataModeAlphanumeric and51 -1 // dataModeByte.52 -1 dataModeNone dataMode = 1 << iota53 -1 dataModeNumeric54 -1 dataModeAlphanumeric55 -1 dataModeByte56 -1 )57 -158 -1 // dataModeString returns d as a short printable string.59 -1 func dataModeString(d dataMode) string {60 -1 switch d {61 -1 case dataModeNone:62 -1 return "none"63 -1 case dataModeNumeric:64 -1 return "numeric"65 -1 case dataModeAlphanumeric:66 -1 return "alphanumeric"67 -1 case dataModeByte:68 -1 return "byte"69 -1 }70 -171 -1 return "unknown"72 -1 }73 -174 -1 type dataEncoderType uint875 -176 -1 const (77 -1 dataEncoderType1To9 dataEncoderType = iota78 -1 dataEncoderType10To2679 -1 dataEncoderType27To4080 -1 )81 -182 -1 // segment is a single segment of data.83 -1 type segment struct {84 -1 // Data Mode (e.g. numeric).85 -1 dataMode dataMode86 -187 -1 // segment data (e.g. "abc").88 -1 data []byte89 -1 }90 -191 -1 // A dataEncoder encodes data for a particular QR Code version.92 -1 type dataEncoder struct {93 -1 // Minimum & maximum versions supported.94 -1 minVersion int95 -1 maxVersion int96 -197 -1 // Mode indicator bit sequences.98 -1 numericModeIndicator *bitset.Bitset99 -1 alphanumericModeIndicator *bitset.Bitset100 -1 byteModeIndicator *bitset.Bitset101 -1102 -1 // Character count lengths.103 -1 numNumericCharCountBits int104 -1 numAlphanumericCharCountBits int105 -1 numByteCharCountBits int106 -1107 -1 // The raw input data.108 -1 data []byte109 -1110 -1 // The data classified into unoptimised segments.111 -1 actual []segment112 -1113 -1 // The data classified into optimised segments.114 -1 optimised []segment115 -1 }116 -1117 -1 // newDataEncoder constructs a dataEncoder.118 -1 func newDataEncoder(t dataEncoderType) *dataEncoder {119 -1 d := &dataEncoder{}120 -1121 -1 switch t {122 -1 case dataEncoderType1To9:123 -1 d = &dataEncoder{124 -1 minVersion: 1,125 -1 maxVersion: 9,126 -1 numericModeIndicator: bitset.New(b0, b0, b0, b1),127 -1 alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),128 -1 byteModeIndicator: bitset.New(b0, b1, b0, b0),129 -1 numNumericCharCountBits: 10,130 -1 numAlphanumericCharCountBits: 9,131 -1 numByteCharCountBits: 8,132 -1 }133 -1 case dataEncoderType10To26:134 -1 d = &dataEncoder{135 -1 minVersion: 10,136 -1 maxVersion: 26,137 -1 numericModeIndicator: bitset.New(b0, b0, b0, b1),138 -1 alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),139 -1 byteModeIndicator: bitset.New(b0, b1, b0, b0),140 -1 numNumericCharCountBits: 12,141 -1 numAlphanumericCharCountBits: 11,142 -1 numByteCharCountBits: 16,143 -1 }144 -1 case dataEncoderType27To40:145 -1 d = &dataEncoder{146 -1 minVersion: 27,147 -1 maxVersion: 40,148 -1 numericModeIndicator: bitset.New(b0, b0, b0, b1),149 -1 alphanumericModeIndicator: bitset.New(b0, b0, b1, b0),150 -1 byteModeIndicator: bitset.New(b0, b1, b0, b0),151 -1 numNumericCharCountBits: 14,152 -1 numAlphanumericCharCountBits: 13,153 -1 numByteCharCountBits: 16,154 -1 }155 -1 default:156 -1 log.Panic("Unknown dataEncoderType")157 -1 }158 -1159 -1 return d160 -1 }161 -1162 -1 // encode data as one or more segments and return the encoded data.163 -1 //164 -1 // The returned data does not include the terminator bit sequence.165 -1 func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) {166 -1 d.data = data167 -1 d.actual = nil168 -1 d.optimised = nil169 -1170 -1 if len(data) == 0 {171 -1 return nil, errors.New("no data to encode")172 -1 }173 -1174 -1 // Classify data into unoptimised segments.175 -1 highestRequiredMode := d.classifyDataModes()176 -1177 -1 // Optimise segments.178 -1 err := d.optimiseDataModes()179 -1 if err != nil {180 -1 return nil, err181 -1 }182 -1183 -1 // Check if a single byte encoded segment would be more efficient.184 -1 optimizedLength := 0185 -1 for _, s := range d.optimised {186 -1 length, err := d.encodedLength(s.dataMode, len(s.data))187 -1 if err != nil {188 -1 return nil, err189 -1 }190 -1 optimizedLength += length191 -1 }192 -1193 -1 singleByteSegmentLength, err := d.encodedLength(highestRequiredMode, len(d.data))194 -1 if err != nil {195 -1 return nil, err196 -1 }197 -1198 -1 if singleByteSegmentLength <= optimizedLength {199 -1 d.optimised = []segment{segment{dataMode: highestRequiredMode, data: d.data}}200 -1 }201 -1202 -1 // Encode data.203 -1 encoded := bitset.New()204 -1 for _, s := range d.optimised {205 -1 d.encodeDataRaw(s.data, s.dataMode, encoded)206 -1 }207 -1208 -1 return encoded, nil209 -1 }210 -1211 -1 // classifyDataModes classifies the raw data into unoptimised segments.212 -1 // e.g. "123ZZ#!#!" =>213 -1 // [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"].214 -1 //215 -1 // Returns the highest data mode needed to encode the data. e.g. for a mixed216 -1 // numeric/alphanumeric input, the highest is alphanumeric.217 -1 //218 -1 // dataModeNone < dataModeNumeric < dataModeAlphanumeric < dataModeByte219 -1 func (d *dataEncoder) classifyDataModes() dataMode {220 -1 var start int221 -1 mode := dataModeNone222 -1 highestRequiredMode := mode223 -1224 -1 for i, v := range d.data {225 -1 newMode := dataModeNone226 -1 switch {227 -1 case v >= 0x30 && v <= 0x39:228 -1 newMode = dataModeNumeric229 -1 case v == 0x20 || v == 0x24 || v == 0x25 || v == 0x2a || v == 0x2b || v ==230 -1 0x2d || v == 0x2e || v == 0x2f || v == 0x3a || (v >= 0x41 && v <= 0x5a):231 -1 newMode = dataModeAlphanumeric232 -1 default:233 -1 newMode = dataModeByte234 -1 }235 -1236 -1 if newMode != mode {237 -1 if i > 0 {238 -1 d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:i]})239 -1240 -1 start = i241 -1 }242 -1243 -1 mode = newMode244 -1 }245 -1246 -1 if newMode > highestRequiredMode {247 -1 highestRequiredMode = newMode248 -1 }249 -1 }250 -1251 -1 d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:len(d.data)]})252 -1253 -1 return highestRequiredMode254 -1 }255 -1256 -1 // optimiseDataModes optimises the list of segments to reduce the overall output257 -1 // encoded data length.258 -1 //259 -1 // The algorithm coalesces adjacent segments. segments are only coalesced when260 -1 // the Data Modes are compatible, and when the coalesced segment has a shorter261 -1 // encoded length than separate segments.262 -1 //263 -1 // Multiple segments may be coalesced. For example a string of alternating264 -1 // alphanumeric/numeric segments ANANANANA can be optimised to just A.265 -1 func (d *dataEncoder) optimiseDataModes() error {266 -1 for i := 0; i < len(d.actual); {267 -1 mode := d.actual[i].dataMode268 -1 numChars := len(d.actual[i].data)269 -1270 -1 j := i + 1271 -1 for j < len(d.actual) {272 -1 nextNumChars := len(d.actual[j].data)273 -1 nextMode := d.actual[j].dataMode274 -1275 -1 if nextMode > mode {276 -1 break277 -1 }278 -1279 -1 coalescedLength, err := d.encodedLength(mode, numChars+nextNumChars)280 -1281 -1 if err != nil {282 -1 return err283 -1 }284 -1285 -1 seperateLength1, err := d.encodedLength(mode, numChars)286 -1287 -1 if err != nil {288 -1 return err289 -1 }290 -1291 -1 seperateLength2, err := d.encodedLength(nextMode, nextNumChars)292 -1293 -1 if err != nil {294 -1 return err295 -1 }296 -1297 -1 if coalescedLength < seperateLength1+seperateLength2 {298 -1 j++299 -1 numChars += nextNumChars300 -1 } else {301 -1 break302 -1 }303 -1 }304 -1305 -1 optimised := segment{dataMode: mode,306 -1 data: make([]byte, 0, numChars)}307 -1308 -1 for k := i; k < j; k++ {309 -1 optimised.data = append(optimised.data, d.actual[k].data...)310 -1 }311 -1312 -1 d.optimised = append(d.optimised, optimised)313 -1314 -1 i = j315 -1 }316 -1317 -1 return nil318 -1 }319 -1320 -1 // encodeDataRaw encodes data in dataMode. The encoded data is appended to321 -1 // encoded.322 -1 func (d *dataEncoder) encodeDataRaw(data []byte, dataMode dataMode, encoded *bitset.Bitset) {323 -1 modeIndicator := d.modeIndicator(dataMode)324 -1 charCountBits := d.charCountBits(dataMode)325 -1326 -1 // Append mode indicator.327 -1 encoded.Append(modeIndicator)328 -1329 -1 // Append character count.330 -1 encoded.AppendUint32(uint32(len(data)), charCountBits)331 -1332 -1 // Append data.333 -1 switch dataMode {334 -1 case dataModeNumeric:335 -1 for i := 0; i < len(data); i += 3 {336 -1 charsRemaining := len(data) - i337 -1338 -1 var value uint32339 -1 bitsUsed := 1340 -1341 -1 for j := 0; j < charsRemaining && j < 3; j++ {342 -1 value *= 10343 -1 value += uint32(data[i+j] - 0x30)344 -1 bitsUsed += 3345 -1 }346 -1 encoded.AppendUint32(value, bitsUsed)347 -1 }348 -1 case dataModeAlphanumeric:349 -1 for i := 0; i < len(data); i += 2 {350 -1 charsRemaining := len(data) - i351 -1352 -1 var value uint32353 -1 for j := 0; j < charsRemaining && j < 2; j++ {354 -1 value *= 45355 -1 value += encodeAlphanumericCharacter(data[i+j])356 -1 }357 -1358 -1 bitsUsed := 6359 -1 if charsRemaining > 1 {360 -1 bitsUsed = 11361 -1 }362 -1363 -1 encoded.AppendUint32(value, bitsUsed)364 -1 }365 -1 case dataModeByte:366 -1 for _, b := range data {367 -1 encoded.AppendByte(b, 8)368 -1 }369 -1 }370 -1 }371 -1372 -1 // modeIndicator returns the segment header bits for a segment of type dataMode.373 -1 func (d *dataEncoder) modeIndicator(dataMode dataMode) *bitset.Bitset {374 -1 switch dataMode {375 -1 case dataModeNumeric:376 -1 return d.numericModeIndicator377 -1 case dataModeAlphanumeric:378 -1 return d.alphanumericModeIndicator379 -1 case dataModeByte:380 -1 return d.byteModeIndicator381 -1 default:382 -1 log.Panic("Unknown data mode")383 -1 }384 -1385 -1 return nil386 -1 }387 -1388 -1 // charCountBits returns the number of bits used to encode the length of a data389 -1 // segment of type dataMode.390 -1 func (d *dataEncoder) charCountBits(dataMode dataMode) int {391 -1 switch dataMode {392 -1 case dataModeNumeric:393 -1 return d.numNumericCharCountBits394 -1 case dataModeAlphanumeric:395 -1 return d.numAlphanumericCharCountBits396 -1 case dataModeByte:397 -1 return d.numByteCharCountBits398 -1 default:399 -1 log.Panic("Unknown data mode")400 -1 }401 -1402 -1 return 0403 -1 }404 -1405 -1 // encodedLength returns the number of bits required to encode n symbols in406 -1 // dataMode.407 -1 //408 -1 // The number of bits required is affected by:409 -1 // - QR code type - Mode Indicator length.410 -1 // - Data mode - number of bits used to represent data length.411 -1 // - Data mode - how the data is encoded.412 -1 // - Number of symbols encoded.413 -1 //414 -1 // An error is returned if the mode is not supported, or the length requested is415 -1 // too long to be represented.416 -1 func (d *dataEncoder) encodedLength(dataMode dataMode, n int) (int, error) {417 -1 modeIndicator := d.modeIndicator(dataMode)418 -1 charCountBits := d.charCountBits(dataMode)419 -1420 -1 if modeIndicator == nil {421 -1 return 0, errors.New("mode not supported")422 -1 }423 -1424 -1 maxLength := (1 << uint8(charCountBits)) - 1425 -1426 -1 if n > maxLength {427 -1 return 0, errors.New("length too long to be represented")428 -1 }429 -1430 -1 length := modeIndicator.Len() + charCountBits431 -1432 -1 switch dataMode {433 -1 case dataModeNumeric:434 -1 length += 10 * (n / 3)435 -1436 -1 if n%3 != 0 {437 -1 length += 1 + 3*(n%3)438 -1 }439 -1 case dataModeAlphanumeric:440 -1 length += 11 * (n / 2)441 -1 length += 6 * (n % 2)442 -1 case dataModeByte:443 -1 length += 8 * n444 -1 }445 -1446 -1 return length, nil447 -1 }448 -1449 -1 // encodeAlphanumericChar returns the QR Code encoded value of v.450 -1 //451 -1 // v must be a QR Code defined alphanumeric character: 0-9, A-Z, SP, $%*+-./ or452 -1 // :. The characters are mapped to values in the range 0-44 respectively.453 -1 func encodeAlphanumericCharacter(v byte) uint32 {454 -1 c := uint32(v)455 -1456 -1 switch {457 -1 case c >= '0' && c <= '9':458 -1 // 0-9 encoded as 0-9.459 -1 return c - '0'460 -1 case c >= 'A' && c <= 'Z':461 -1 // A-Z encoded as 10-35.462 -1 return c - 'A' + 10463 -1 case c == ' ':464 -1 return 36465 -1 case c == '$':466 -1 return 37467 -1 case c == '%':468 -1 return 38469 -1 case c == '*':470 -1 return 39471 -1 case c == '+':472 -1 return 40473 -1 case c == '-':474 -1 return 41475 -1 case c == '.':476 -1 return 42477 -1 case c == '/':478 -1 return 43479 -1 case c == ':':480 -1 return 44481 -1 default:482 -1 log.Panicf("encodeAlphanumericCharacter() with non alphanumeric char %v.", v)483 -1 }484 -1485 -1 return 0486 -1 }
diff --git a/gf.go b/gf.go
@@ -0,0 +1,94 @@
-1 1 package qrcode
-1 2
-1 3 import "log"
-1 4
-1 5 const (
-1 6 gfZero = gfElement(0)
-1 7 gfOne = gfElement(1)
-1 8 )
-1 9
-1 10 var (
-1 11 gfExpTable = [256]gfElement{
-1 12 1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
-1 13 116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
-1 14 180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
-1 15 96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
-1 16 106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
-1 17 5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
-1 18 185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
-1 19 94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
-1 20 253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
-1 21 223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
-1 22 17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
-1 23 103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
-1 24 59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
-1 25 46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
-1 26 132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
-1 27 85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
-1 28 230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
-1 29 215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
-1 30 150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
-1 31 174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
-1 32 28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
-1 33 89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
-1 34 172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
-1 35 244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
-1 36 44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
-1 37 108, 216, 173, 71, 142, 1}
-1 38
-1 39 gfLogTable = [256]int{
-1 40 -1, 0, 1, 25, 2, 50, 26, 198, 3, 223,
-1 41 51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
-1 42 52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
-1 43 76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
-1 44 53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
-1 45 194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
-1 46 77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
-1 47 48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
-1 48 54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
-1 49 19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
-1 50 195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
-1 51 186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
-1 52 78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
-1 53 192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
-1 54 49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
-1 55 180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
-1 56 55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
-1 57 151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
-1 58 20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
-1 59 65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
-1 60 196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
-1 61 59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
-1 62 187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
-1 63 160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
-1 64 79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
-1 65 244, 234, 168, 80, 88, 175}
-1 66 )
-1 67
-1 68 type gfElement uint8
-1 69
-1 70 func gfMultiply(a, b gfElement) gfElement {
-1 71 if a == gfZero || b == gfZero {
-1 72 return gfZero
-1 73 }
-1 74
-1 75 return gfExpTable[(gfLogTable[a] + gfLogTable[b]) % 255]
-1 76 }
-1 77
-1 78 func gfDivide(a, b gfElement) gfElement {
-1 79 if a == gfZero {
-1 80 return gfZero
-1 81 } else if b == gfZero {
-1 82 log.Panicln("Divide by zero")
-1 83 }
-1 84
-1 85 return gfMultiply(a, gfInverse(b))
-1 86 }
-1 87
-1 88 func gfInverse(a gfElement) gfElement {
-1 89 if a == gfZero {
-1 90 log.Panicln("No multiplicative inverse of 0")
-1 91 }
-1 92
-1 93 return gfExpTable[255 - gfLogTable[a]]
-1 94 }
diff --git a/qrcode.go b/qrcode.go
@@ -1,589 +1,120 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 /*5 -1 Package qrcode implements a QR Code encoder.6 -17 -1 A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be8 -1 encoded.9 -110 -1 A QR Code contains error recovery information to aid reading damaged or11 -1 obscured codes. There are four levels of error recovery: qrcode.{Low, Medium,12 -1 High, Highest}. QR Codes with a higher recovery level are more robust to damage,13 -1 at the cost of being physically larger.14 -115 -1 Three functions cover most use cases:16 -117 -1 - Create a PNG image:18 -119 -1 var png []byte20 -1 png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256)21 -122 -1 - Create a PNG image and write to a file:23 -124 -1 err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png")25 -126 -1 - Create a PNG image with custom colors and write to file:27 -128 -1 err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png")29 -130 -1 All examples use the qrcode.Medium error Recovery Level and create a fixed31 -1 256x256px size QR Code. The last function creates a white on black instead of black32 -1 on white QR Code.33 -134 -1 To generate a variable sized image instead, specify a negative size (in place of35 -1 the 256 above), such as -4 or -5. Larger negative numbers create larger images:36 -1 A size of -5 sets each module (QR Code "pixel") to be 5px wide/high.37 -138 -1 - Create a PNG image (variable size, with minimum white padding) and write to a file:39 -140 -1 err := qrcode.WriteFile("https://example.org", qrcode.Medium, -5, "qr.png")41 -142 -1 The maximum capacity of a QR Code varies according to the content encoded and43 -1 the error recovery level. The maximum capacity is 2,953 bytes, 4,29644 -1 alphanumeric characters, 7,089 numeric digits, or a combination of these.45 -146 -1 This package implements a subset of QR Code 2005, as defined in ISO/IEC47 -1 18004:2006.48 -1 */49 1 package qrcode 50 2 51 3 import ( 52 4 "bytes" 53 5 "errors" 54 6 "fmt"55 -1 "image"56 -1 "image/color"57 -1 "image/png"58 -1 "io"59 -1 "io/ioutil"60 -1 "log"61 -1 "os"62 -163 -1 bitset "github.com/skip2/go-qrcode/bitset"64 -1 reedsolomon "github.com/skip2/go-qrcode/reedsolomon"65 7 ) 66 867 -1 // Encode a QR Code and return a raw PNG image.68 -1 //69 -1 // size is both the image width and height in pixels. If size is too small then70 -1 // a larger image is silently returned. Negative values for size cause a71 -1 // variable sized image to be returned: See the documentation for Image().72 -1 //73 -1 // To serve over HTTP, remember to send a Content-Type: image/png header.74 -1 func Encode(content string, level RecoveryLevel, size int) ([]byte, error) {75 -1 var q *QRCode76 -177 -1 q, err := New(content, level)78 -179 -1 if err != nil {80 -1 return nil, err81 -1 }82 -183 -1 return q.PNG(size)84 -1 }85 -186 -1 // WriteFile encodes, then writes a QR Code to the given filename in PNG format.87 -1 //88 -1 // size is both the image width and height in pixels. If size is too small then89 -1 // a larger image is silently written. Negative values for size cause a variable90 -1 // sized image to be written: See the documentation for Image().91 -1 func WriteFile(content string, level RecoveryLevel, size int, filename string) error {92 -1 var q *QRCode93 -194 -1 q, err := New(content, level)95 -196 -1 if err != nil {97 -1 return err98 -1 }99 -1100 -1 return q.WriteFile(size, filename)101 -1 }102 -1103 -1 // WriteColorFile encodes, then writes a QR Code to the given filename in PNG format.104 -1 // With WriteColorFile you can also specify the colors you want to use.105 -1 //106 -1 // size is both the image width and height in pixels. If size is too small then107 -1 // a larger image is silently written. Negative values for size cause a variable108 -1 // sized image to be written: See the documentation for Image().109 -1 func WriteColorFile(content string, level RecoveryLevel, size int, background,110 -1 foreground color.Color, filename string) error {111 -1112 -1 var q *QRCode113 -1114 -1 q, err := New(content, level)115 -1116 -1 q.BackgroundColor = background117 -1 q.ForegroundColor = foreground118 -1119 -1 if err != nil {120 -1 return err121 -1 }122 -1123 -1 return q.WriteFile(size, filename)124 -1 }125 -1126 -1 // A QRCode represents a valid encoded QRCode.127 -1 type QRCode struct {128 -1 // Original content encoded.129 -1 Content string130 -1131 -1 // QR Code type.132 -1 Level RecoveryLevel133 -1 VersionNumber int134 -1135 -1 // User settable drawing options.136 -1 ForegroundColor color.Color137 -1 BackgroundColor color.Color138 -1139 -1 // Disable the QR Code border.140 -1 DisableBorder bool141 -1142 -1 encoder *dataEncoder143 -1 version qrCodeVersion144 -1145 -1 data *bitset.Bitset146 -1 symbol *symbol147 -1 mask int148 -1 }-1 9 func getVersion(data []byte) *version { -1 10 var numByteCharCountBits int 149 11150 -1 // New constructs a QRCode.151 -1 //152 -1 // var q *qrcode.QRCode153 -1 // q, err := qrcode.New("my content", qrcode.Medium)154 -1 //155 -1 // An error occurs if the content is too long.156 -1 func New(content string, level RecoveryLevel) (*QRCode, error) {157 -1 encoders := []dataEncoderType{dataEncoderType1To9, dataEncoderType10To26,158 -1 dataEncoderType27To40}159 -1160 -1 var encoder *dataEncoder161 -1 var encoded *bitset.Bitset162 -1 var chosenVersion *qrCodeVersion163 -1 var err error164 -1165 -1 for _, t := range encoders {166 -1 encoder = newDataEncoder(t)167 -1 encoded, err = encoder.encode([]byte(content))168 -1169 -1 if err != nil {170 -1 continue171 -1 }172 -1173 -1 chosenVersion = chooseQRCodeVersion(level, encoder, encoded.Len())174 -1175 -1 if chosenVersion != nil {176 -1 break-1 12 for _, v := range versions { -1 13 if v.version < 10 { -1 14 numByteCharCountBits = 8 -1 15 } else { -1 16 numByteCharCountBits = 16 177 17 }178 -1 }179 -1180 -1 if err != nil {181 -1 return nil, err182 -1 } else if chosenVersion == nil {183 -1 return nil, errors.New("content too long to encode")184 -1 }185 -1186 -1 q := &QRCode{187 -1 Content: content,188 -1189 -1 Level: level,190 -1 VersionNumber: chosenVersion.version,191 -1192 -1 ForegroundColor: color.Black,193 -1 BackgroundColor: color.White,194 -1195 -1 encoder: encoder,196 -1 data: encoded,197 -1 version: *chosenVersion,198 -1 }199 -1200 -1 return q, nil201 -1 }202 -1203 -1 // NewWithForcedVersion constructs a QRCode of a specific version.204 -1 //205 -1 // var q *qrcode.QRCode206 -1 // q, err := qrcode.NewWithForcedVersion("my content", 25, qrcode.Medium)207 -1 //208 -1 // An error occurs in case of invalid version.209 -1 func NewWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) {210 -1 var encoder *dataEncoder211 -1212 -1 switch {213 -1 case version >= 1 && version <= 9:214 -1 encoder = newDataEncoder(dataEncoderType1To9)215 -1 case version >= 10 && version <= 26:216 -1 encoder = newDataEncoder(dataEncoderType10To26)217 -1 case version >= 27 && version <= 40:218 -1 encoder = newDataEncoder(dataEncoderType27To40)219 -1 default:220 -1 return nil, fmt.Errorf("Invalid version %d (expected 1-40 inclusive)", version)221 -1 }222 -1223 -1 var encoded *bitset.Bitset224 -1 encoded, err := encoder.encode([]byte(content))225 -1226 -1 if err != nil {227 -1 return nil, err228 -1 }229 -1230 -1 chosenVersion := getQRCodeVersion(level, version)231 -1232 -1 if chosenVersion == nil {233 -1 return nil, errors.New("cannot find QR Code version")234 -1 }235 -1236 -1 if encoded.Len() > chosenVersion.numDataBits() {237 -1 return nil, fmt.Errorf("Cannot encode QR code: content too large for fixed size QR Code version %d (encoded length is %d bits, maximum length is %d bits)",238 -1 version,239 -1 encoded.Len(),240 -1 chosenVersion.numDataBits())241 -1 }242 -1243 -1 q := &QRCode{244 -1 Content: content,245 -1246 -1 Level: level,247 -1 VersionNumber: chosenVersion.version,248 -1249 -1 ForegroundColor: color.Black,250 -1 BackgroundColor: color.White,251 -1252 -1 encoder: encoder,253 -1 data: encoded,254 -1 version: *chosenVersion,255 -1 }256 -1257 -1 return q, nil258 -1 }259 -1260 -1 // Bitmap returns the QR Code as a 2D array of 1-bit pixels.261 -1 //262 -1 // bitmap[y][x] is true if the pixel at (x, y) is set.263 -1 //264 -1 // The bitmap includes the required "quiet zone" around the QR Code to aid265 -1 // decoding.266 -1 func (q *QRCode) Bitmap() [][]bool {267 -1 // Build QR code.268 -1 q.encode()269 -1270 -1 return q.symbol.bitmap()271 -1 }272 -1273 -1 // Image returns the QR Code as an image.Image.274 -1 //275 -1 // A positive size sets a fixed image width and height (e.g. 256 yields an276 -1 // 256x256px image).277 -1 //278 -1 // Depending on the amount of data encoded, fixed size images can have different279 -1 // amounts of padding (white space around the QR Code). As an alternative, a280 -1 // variable sized image can be generated instead:281 -1 //282 -1 // A negative size causes a variable sized image to be returned. The image283 -1 // returned is the minimum size required for the QR Code. Choose a larger284 -1 // negative number to increase the scale of the image. e.g. a size of -5 causes285 -1 // each module (QR Code "pixel") to be 5px in size.286 -1 func (q *QRCode) Image(size int) image.Image {287 -1 // Build QR code.288 -1 q.encode()289 -1290 -1 // Minimum pixels (both width and height) required.291 -1 realSize := q.symbol.size292 -1293 -1 // Variable size support.294 -1 if size < 0 {295 -1 size = size * -1 * realSize296 -1 }297 -1298 -1 // Actual pixels available to draw the symbol. Automatically increase the299 -1 // image size if it's not large enough.300 -1 if size < realSize {301 -1 size = realSize302 -1 }303 -1304 -1 // Output image.305 -1 rect := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{size, size}}306 -1307 -1 // Saves a few bytes to have them in this order308 -1 p := color.Palette([]color.Color{q.BackgroundColor, q.ForegroundColor})309 -1 img := image.NewPaletted(rect, p)310 -1 fgClr := uint8(img.Palette.Index(q.ForegroundColor))311 -1312 -1 // QR code bitmap.313 -1 bitmap := q.symbol.bitmap()314 -1315 -1 // Map each image pixel to the nearest QR code module.316 -1 modulesPerPixel := float64(realSize) / float64(size)317 -1 for y := 0; y < size; y++ {318 -1 y2 := int(float64(y) * modulesPerPixel)319 -1 for x := 0; x < size; x++ {320 -1 x2 := int(float64(x) * modulesPerPixel)321 -1322 -1 v := bitmap[y2][x2]323 -1324 -1 if v {325 -1 pos := img.PixOffset(x, y)326 -1 img.Pix[pos] = fgClr327 -1 }-1 18 if v.numDataBits() >= len(data)*8+8+numByteCharCountBits { -1 19 return &v 328 20 } 329 21 } 330 22331 -1 return img332 -1 }333 -1334 -1 // PNG returns the QR Code as a PNG image.335 -1 //336 -1 // size is both the image width and height in pixels. If size is too small then337 -1 // a larger image is silently returned. Negative values for size cause a338 -1 // variable sized image to be returned: See the documentation for Image().339 -1 func (q *QRCode) PNG(size int) ([]byte, error) {340 -1 img := q.Image(size)341 -1342 -1 encoder := png.Encoder{CompressionLevel: png.BestCompression}343 -1344 -1 var b bytes.Buffer345 -1 err := encoder.Encode(&b, img)346 -1347 -1 if err != nil {348 -1 return nil, err349 -1 }350 -1351 -1 return b.Bytes(), nil-1 23 return nil 352 24 } 353 25354 -1 // Write writes the QR Code as a PNG image to io.Writer.355 -1 //356 -1 // size is both the image width and height in pixels. If size is too small then357 -1 // a larger image is silently written. Negative values for size cause a358 -1 // variable sized image to be written: See the documentation for Image().359 -1 func (q *QRCode) Write(size int, out io.Writer) error {360 -1 var png []byte361 -1362 -1 png, err := q.PNG(size)-1 26 func encodeContent(data []byte, version *version) []byte { -1 27 encoded := NewBitset() -1 28 encoded.Write(0b0100, 4) 363 29364 -1 if err != nil {365 -1 return err-1 30 if version.version < 10 { -1 31 encoded.Write(uint(len(data)), 8) -1 32 } else { -1 33 encoded.Write(uint(len(data)), 16) 366 34 }367 -1 _, err = out.Write(png)368 -1 return err369 -1 }370 35371 -1 // WriteFile writes the QR Code as a PNG image to the specified file.372 -1 //373 -1 // size is both the image width and height in pixels. If size is too small then374 -1 // a larger image is silently written. Negative values for size cause a375 -1 // variable sized image to be written: See the documentation for Image().376 -1 func (q *QRCode) WriteFile(size int, filename string) error {377 -1 var png []byte378 -1379 -1 png, err := q.PNG(size)380 -1381 -1 if err != nil {382 -1 return err-1 36 for _, b := range data { -1 37 encoded.Write(uint(b), 8) 383 38 } 384 39385 -1 return ioutil.WriteFile(filename, png, os.FileMode(0644))386 -1 }387 -1388 -1 // encode completes the steps required to encode the QR Code. These include389 -1 // adding the terminator bits and padding, splitting the data into blocks and390 -1 // applying the error correction, and selecting the best data mask.391 -1 func (q *QRCode) encode() {392 -1 numTerminatorBits := q.version.numTerminatorBitsRequired(q.data.Len())393 -1394 -1 q.addTerminatorBits(numTerminatorBits)395 -1 q.addPadding()-1 40 encoded.Write(0, 4) 396 41397 -1 encoded := q.encodeBlocks()398 -1399 -1 const numMasks int = 8400 -1 penalty := 0401 -1402 -1 for mask := 0; mask < numMasks; mask++ {403 -1 var s *symbol404 -1 var err error405 -1406 -1 s, err = buildRegularSymbol(q.version, mask, encoded, !q.DisableBorder)407 -1408 -1 if err != nil {409 -1 log.Panic(err.Error())410 -1 }411 -1412 -1 numEmptyModules := s.numEmptyModules()413 -1 if numEmptyModules != 0 {414 -1 log.Panicf("bug: numEmptyModules is %d (expected 0) (version=%d)",415 -1 numEmptyModules, q.VersionNumber)416 -1 }417 -1418 -1 p := s.penaltyScore()419 -1420 -1 //log.Printf("mask=%d p=%3d p1=%3d p2=%3d p3=%3d p4=%d\n", mask, p, s.penalty1(), s.penalty2(), s.penalty3(), s.penalty4())421 -1422 -1 if q.symbol == nil || p < penalty {423 -1 q.symbol = s424 -1 q.mask = mask425 -1 penalty = p-1 42 for encoded.Length < version.numDataBits() { -1 43 encoded.Write(0b11101100, 8) -1 44 if encoded.Length < version.numDataBits() { -1 45 encoded.Write(0b00010001, 8) 426 46 } 427 47 }428 -1 }429 48430 -1 // addTerminatorBits adds final terminator bits to the encoded data.431 -1 //432 -1 // The number of terminator bits required is determined when the QR Code version433 -1 // is chosen (which itself depends on the length of the data encoded). The434 -1 // terminator bits are thus added after the QR Code version435 -1 // is chosen, rather than at the data encoding stage.436 -1 func (q *QRCode) addTerminatorBits(numTerminatorBits int) {437 -1 q.data.AppendNumBools(numTerminatorBits, false)-1 49 return encoded.Bytes 438 50 } 439 51440 -1 // encodeBlocks takes the completed (terminated & padded) encoded data, splits441 -1 // the data into blocks (as specified by the QR Code version), applies error442 -1 // correction to each block, then interleaves the blocks together.443 -1 //444 -1 // The QR Code's final data sequence is returned.445 -1 func (q *QRCode) encodeBlocks() *bitset.Bitset {446 -1 // Split into blocks.447 -1 type dataBlock struct {448 -1 data *bitset.Bitset449 -1 ecStartOffset int450 -1 }451 -1452 -1 block := make([]dataBlock, q.version.numBlocks())-1 52 func encodeBlocks(data []byte, version *version) *Bitset { -1 53 result := NewBitset() 453 54 -1 55 content := make([][]byte, 0) -1 56 ecc := make([][]byte, 0) 454 57 start := 0455 -1 end := 0456 -1 blockID := 0457 58458 -1 for _, b := range q.version.block {459 -1 for j := 0; j < b.numBlocks; j++ {-1 59 for _, g := range version.groups { -1 60 numECCodeWords := g.numCodewords - g.numDataCodewords -1 61 for j := 0; j < g.numBlocks; j++ { -1 62 end := start + g.numDataCodewords -1 63 content = append(content, data[start:end]) -1 64 ecc = append(ecc, getErrorCorrection(data[start:end], numECCodeWords)) 460 65 start = end461 -1 end = start + b.numDataCodewords*8462 -1463 -1 // Apply error correction to each block.464 -1 numErrorCodewords := b.numCodewords - b.numDataCodewords465 -1 block[blockID].data = reedsolomon.Encode(q.data.Substr(start, end), numErrorCodewords)466 -1 block[blockID].ecStartOffset = end - start467 -1468 -1 blockID++469 66 } 470 67 } 471 68 472 69 // Interleave the blocks.473 -1474 -1 result := bitset.New()475 -1476 -1 // Combine data blocks.477 70 working := true478 -1 for i := 0; working; i += 8 {-1 71 for i := 0; working; i += 1 { 479 72 working = false480 -1481 -1 for j, b := range block {482 -1 if i >= block[j].ecStartOffset {483 -1 continue-1 73 for _, c := range content { -1 74 if i < len(c) { -1 75 result.Write(uint(c[i]), 8) -1 76 working = true 484 77 }485 -1486 -1 result.Append(b.data.Substr(i, i+8))487 -1488 -1 working = true489 78 } 490 79 } 491 80492 -1 // Combine error correction blocks.493 81 working = true494 -1 for i := 0; working; i += 8 {-1 82 for i := 0; working; i += 1 { 495 83 working = false496 -1497 -1 for j, b := range block {498 -1 offset := i + block[j].ecStartOffset499 -1 if offset >= block[j].data.Len() {500 -1 continue-1 84 for _, c := range ecc { -1 85 if i < len(c) { -1 86 result.Write(uint(c[i]), 8) -1 87 working = true 501 88 }502 -1503 -1 result.Append(b.data.Substr(offset, offset+8))504 -1505 -1 working = true506 89 } 507 90 } 508 91509 -1 // Append remainder bits.510 -1 result.AppendNumBools(q.version.numRemainderBits, false)-1 92 result.Write(0, version.numRemainderBits) 511 93 512 94 return result 513 95 } 514 96515 -1 // max returns the maximum of a and b.516 -1 func max(a int, b int) int {517 -1 if a > b {518 -1 return a519 -1 }520 -1521 -1 return b522 -1 }523 -1524 -1 // addPadding pads the encoded data upto the full length required.525 -1 func (q *QRCode) addPadding() {526 -1 numDataBits := q.version.numDataBits()527 -1528 -1 if q.data.Len() == numDataBits {529 -1 return530 -1 }531 -1532 -1 // Pad to the nearest codeword boundary.533 -1 q.data.AppendNumBools(q.version.numBitsToPadToCodeword(q.data.Len()), false)534 -1535 -1 // Pad codewords 0b11101100 and 0b00010001.536 -1 padding := [2]*bitset.Bitset{537 -1 bitset.New(true, true, true, false, true, true, false, false),538 -1 bitset.New(false, false, false, true, false, false, false, true),539 -1 }540 -1541 -1 // Insert pad codewords alternately.542 -1 i := 0543 -1 for numDataBits-q.data.Len() >= 8 {544 -1 q.data.Append(padding[i])545 -1546 -1 i = 1 - i // Alternate between 0 and 1.547 -1 }548 -1549 -1 if q.data.Len() != numDataBits {550 -1 log.Panicf("BUG: got len %d, expected %d", q.data.Len(), numDataBits)551 -1 }552 -1 }553 -1554 -1 // ToString produces a multi-line string that forms a QR-code image.555 -1 func (q *QRCode) ToString(inverseColor bool) string {556 -1 bits := q.Bitmap()557 -1 var buf bytes.Buffer558 -1 for y := range bits {559 -1 for x := range bits[y] {560 -1 if bits[y][x] != inverseColor {561 -1 buf.WriteString(" ")562 -1 } else {563 -1 buf.WriteString("██")564 -1 }565 -1 }566 -1 buf.WriteString("\n")567 -1 }568 -1 return buf.String()569 -1 }570 -1571 -1 // ToSmallString produces a multi-line string that forms a QR-code image, a572 -1 // factor two smaller in x and y then ToString.573 -1 func (q *QRCode) ToSmallString(inverseColor bool) string {574 -1 bits := q.Bitmap()-1 97 func terminal(b *bitmap, padding int) string { 575 98 var buf bytes.Buffer576 -1 // if there is an odd number of rows, the last one needs special treatment577 -1 for y := 0; y < len(bits)-1; y += 2 {578 -1 for x := range bits[y] {579 -1 if bits[y][x] == bits[y+1][x] {580 -1 if bits[y][x] != inverseColor {-1 99 // if there is an odd number of rows, just shorten the final margin -1 100 for y := -padding; y+1 < b.size+padding; y += 2 { -1 101 for x := -padding; x < b.size+padding; x += 1 { -1 102 if y < 0 || x < 0 || y >= b.size || x >= b.size { -1 103 buf.WriteString("█") -1 104 } else if y+1 == b.size { -1 105 if b.get(x, y) { -1 106 buf.WriteString("▄") -1 107 } else { -1 108 buf.WriteString("█") -1 109 } -1 110 } else if b.get(x, y) == b.get(x, y+1) { -1 111 if b.get(x, y) { 581 112 buf.WriteString(" ") 582 113 } else { 583 114 buf.WriteString("█") 584 115 } 585 116 } else {586 -1 if bits[y][x] != inverseColor {-1 117 if b.get(x, y) { 587 118 buf.WriteString("▄") 588 119 } else { 589 120 buf.WriteString("▀") @@ -592,17 +123,21 @@ func (q *QRCode) ToSmallString(inverseColor bool) string { 592 123 } 593 124 buf.WriteString("\n") 594 125 }595 -1 // special treatment for the last row if odd596 -1 if len(bits)%2 == 1 {597 -1 y := len(bits) - 1598 -1 for x := range bits[y] {599 -1 if bits[y][x] != inverseColor {600 -1 buf.WriteString(" ")601 -1 } else {602 -1 buf.WriteString("▀")603 -1 }604 -1 }605 -1 buf.WriteString("\n")606 -1 }607 126 return buf.String() 608 127 } -1 128 -1 129 func Print(content string) error { -1 130 bytes := []byte(content) -1 131 -1 132 version := getVersion(bytes) -1 133 if version == nil { -1 134 return errors.New("content too long to encode") -1 135 } -1 136 -1 137 encodedContent := encodeContent(bytes, version) -1 138 encodedBlocks := encodeBlocks(encodedContent, version) -1 139 bitmap := render(encodedBlocks, version) -1 140 -1 141 fmt.Print(terminal(bitmap, 2)) -1 142 return nil -1 143 }
diff --git a/qrcode/main.go b/qrcode/main.go
@@ -1,88 +1,14 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 1 package main 5 2 6 3 import (7 -1 "flag"8 4 "fmt" 9 5 "os"10 -1 "strings"11 6 12 7 qrcode "github.com/skip2/go-qrcode" 13 8 ) 14 9 15 10 func main() {16 -1 outFile := flag.String("o", "", "out PNG file prefix, empty for stdout")17 -1 size := flag.Int("s", 256, "image size (pixel)")18 -1 textArt := flag.Bool("t", false, "print as text-art on stdout")19 -1 negative := flag.Bool("i", false, "invert black and white")20 -1 disableBorder := flag.Bool("d", false, "disable QR Code border")21 -1 flag.Usage = func() {22 -1 fmt.Fprintf(os.Stderr, `qrcode -- QR Code encoder in Go23 -1 https://github.com/skip2/go-qrcode24 -125 -1 Flags:26 -1 `)27 -1 flag.PrintDefaults()28 -1 fmt.Fprintf(os.Stderr, `29 -1 Usage:30 -1 1. Arguments except for flags are joined by " " and used to generate QR code.31 -1 Default output is STDOUT, pipe to imagemagick command "display" to display32 -1 on any X server.33 -134 -1 qrcode hello word | display35 -136 -1 2. Save to file if "display" not available:37 -138 -1 qrcode "homepage: https://github.com/skip2/go-qrcode" > out.png39 -140 -1 `)41 -1 }42 -1 flag.Parse()43 -144 -1 if len(flag.Args()) == 0 {45 -1 flag.Usage()46 -1 checkError(fmt.Errorf("Error: no content given"))47 -1 }48 -149 -1 content := strings.Join(flag.Args(), " ")50 -151 -1 var err error52 -1 var q *qrcode.QRCode53 -1 q, err = qrcode.New(content, qrcode.Highest)54 -1 checkError(err)55 -156 -1 if *disableBorder {57 -1 q.DisableBorder = true58 -1 }59 -160 -1 if *textArt {61 -1 art := q.ToString(*negative)62 -1 fmt.Println(art)63 -1 return64 -1 }65 -166 -1 if *negative {67 -1 q.ForegroundColor, q.BackgroundColor = q.BackgroundColor, q.ForegroundColor68 -1 }69 -170 -1 var png []byte71 -1 png, err = q.PNG(*size)72 -1 checkError(err)73 -174 -1 if *outFile == "" {75 -1 os.Stdout.Write(png)76 -1 } else {77 -1 var fh *os.File78 -1 fh, err = os.Create(*outFile + ".png")79 -1 checkError(err)80 -1 defer fh.Close()81 -1 fh.Write(png)82 -1 }83 -1 }84 -185 -1 func checkError(err error) {-1 11 err := qrcode.Print(os.Args[1]) 86 12 if err != nil { 87 13 fmt.Fprintf(os.Stderr, "%s\n", err) 88 14 os.Exit(1)
diff --git a/reedsolomon/gf2_8.go b/reedsolomon/gf2_8.go
@@ -1,387 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 package reedsolomon5 -16 -1 // Addition, subtraction, multiplication, and division in GF(2^8).7 -1 // Operations are performed modulo x^8 + x^4 + x^3 + x^2 + 1.8 -19 -1 // http://en.wikipedia.org/wiki/Finite_field_arithmetic10 -111 -1 import "log"12 -113 -1 const (14 -1 gfZero = gfElement(0)15 -1 gfOne = gfElement(1)16 -1 )17 -118 -1 var (19 -1 gfExpTable = [256]gfElement{20 -1 /* 0 - 9 */ 1, 2, 4, 8, 16, 32, 64, 128, 29, 58,21 -1 /* 10 - 19 */ 116, 232, 205, 135, 19, 38, 76, 152, 45, 90,22 -1 /* 20 - 29 */ 180, 117, 234, 201, 143, 3, 6, 12, 24, 48,23 -1 /* 30 - 39 */ 96, 192, 157, 39, 78, 156, 37, 74, 148, 53,24 -1 /* 40 - 49 */ 106, 212, 181, 119, 238, 193, 159, 35, 70, 140,25 -1 /* 50 - 59 */ 5, 10, 20, 40, 80, 160, 93, 186, 105, 210,26 -1 /* 60 - 69 */ 185, 111, 222, 161, 95, 190, 97, 194, 153, 47,27 -1 /* 70 - 79 */ 94, 188, 101, 202, 137, 15, 30, 60, 120, 240,28 -1 /* 80 - 89 */ 253, 231, 211, 187, 107, 214, 177, 127, 254, 225,29 -1 /* 90 - 99 */ 223, 163, 91, 182, 113, 226, 217, 175, 67, 134,30 -1 /* 100 - 109 */ 17, 34, 68, 136, 13, 26, 52, 104, 208, 189,31 -1 /* 110 - 119 */ 103, 206, 129, 31, 62, 124, 248, 237, 199, 147,32 -1 /* 120 - 129 */ 59, 118, 236, 197, 151, 51, 102, 204, 133, 23,33 -1 /* 130 - 139 */ 46, 92, 184, 109, 218, 169, 79, 158, 33, 66,34 -1 /* 140 - 149 */ 132, 21, 42, 84, 168, 77, 154, 41, 82, 164,35 -1 /* 150 - 159 */ 85, 170, 73, 146, 57, 114, 228, 213, 183, 115,36 -1 /* 160 - 169 */ 230, 209, 191, 99, 198, 145, 63, 126, 252, 229,37 -1 /* 170 - 179 */ 215, 179, 123, 246, 241, 255, 227, 219, 171, 75,38 -1 /* 180 - 189 */ 150, 49, 98, 196, 149, 55, 110, 220, 165, 87,39 -1 /* 190 - 199 */ 174, 65, 130, 25, 50, 100, 200, 141, 7, 14,40 -1 /* 200 - 209 */ 28, 56, 112, 224, 221, 167, 83, 166, 81, 162,41 -1 /* 210 - 219 */ 89, 178, 121, 242, 249, 239, 195, 155, 43, 86,42 -1 /* 220 - 229 */ 172, 69, 138, 9, 18, 36, 72, 144, 61, 122,43 -1 /* 230 - 239 */ 244, 245, 247, 243, 251, 235, 203, 139, 11, 22,44 -1 /* 240 - 249 */ 44, 88, 176, 125, 250, 233, 207, 131, 27, 54,45 -1 /* 250 - 255 */ 108, 216, 173, 71, 142, 1}46 -147 -1 gfLogTable = [256]int{48 -1 /* 0 - 9 */ -1, 0, 1, 25, 2, 50, 26, 198, 3, 223,49 -1 /* 10 - 19 */ 51, 238, 27, 104, 199, 75, 4, 100, 224, 14,50 -1 /* 20 - 29 */ 52, 141, 239, 129, 28, 193, 105, 248, 200, 8,51 -1 /* 30 - 39 */ 76, 113, 5, 138, 101, 47, 225, 36, 15, 33,52 -1 /* 40 - 49 */ 53, 147, 142, 218, 240, 18, 130, 69, 29, 181,53 -1 /* 50 - 59 */ 194, 125, 106, 39, 249, 185, 201, 154, 9, 120,54 -1 /* 60 - 69 */ 77, 228, 114, 166, 6, 191, 139, 98, 102, 221,55 -1 /* 70 - 79 */ 48, 253, 226, 152, 37, 179, 16, 145, 34, 136,56 -1 /* 80 - 89 */ 54, 208, 148, 206, 143, 150, 219, 189, 241, 210,57 -1 /* 90 - 99 */ 19, 92, 131, 56, 70, 64, 30, 66, 182, 163,58 -1 /* 100 - 109 */ 195, 72, 126, 110, 107, 58, 40, 84, 250, 133,59 -1 /* 110 - 119 */ 186, 61, 202, 94, 155, 159, 10, 21, 121, 43,60 -1 /* 120 - 129 */ 78, 212, 229, 172, 115, 243, 167, 87, 7, 112,61 -1 /* 130 - 139 */ 192, 247, 140, 128, 99, 13, 103, 74, 222, 237,62 -1 /* 140 - 149 */ 49, 197, 254, 24, 227, 165, 153, 119, 38, 184,63 -1 /* 150 - 159 */ 180, 124, 17, 68, 146, 217, 35, 32, 137, 46,64 -1 /* 160 - 169 */ 55, 63, 209, 91, 149, 188, 207, 205, 144, 135,65 -1 /* 170 - 179 */ 151, 178, 220, 252, 190, 97, 242, 86, 211, 171,66 -1 /* 180 - 189 */ 20, 42, 93, 158, 132, 60, 57, 83, 71, 109,67 -1 /* 190 - 199 */ 65, 162, 31, 45, 67, 216, 183, 123, 164, 118,68 -1 /* 200 - 209 */ 196, 23, 73, 236, 127, 12, 111, 246, 108, 161,69 -1 /* 210 - 219 */ 59, 82, 41, 157, 85, 170, 251, 96, 134, 177,70 -1 /* 220 - 229 */ 187, 204, 62, 90, 203, 89, 95, 176, 156, 169,71 -1 /* 230 - 239 */ 160, 81, 11, 245, 22, 235, 122, 117, 44, 215,72 -1 /* 240 - 249 */ 79, 174, 213, 233, 230, 231, 173, 232, 116, 214,73 -1 /* 250 - 255 */ 244, 234, 168, 80, 88, 175}74 -1 )75 -176 -1 // gfElement is an element in GF(2^8).77 -1 type gfElement uint878 -179 -1 // newGFElement creates and returns a new gfElement.80 -1 func newGFElement(data byte) gfElement {81 -1 return gfElement(data)82 -1 }83 -184 -1 // gfAdd returns a + b.85 -1 func gfAdd(a, b gfElement) gfElement {86 -1 return a ^ b87 -1 }88 -189 -1 // gfSub returns a - b.90 -1 //91 -1 // Note addition is equivalent to subtraction in GF(2).92 -1 func gfSub(a, b gfElement) gfElement {93 -1 return a ^ b94 -1 }95 -196 -1 // gfMultiply returns a * b.97 -1 func gfMultiply(a, b gfElement) gfElement {98 -1 if a == gfZero || b == gfZero {99 -1 return gfZero100 -1 }101 -1102 -1 return gfExpTable[(gfLogTable[a]+gfLogTable[b])%255]103 -1 }104 -1105 -1 // gfDivide returns a / b.106 -1 //107 -1 // Divide by zero results in a panic.108 -1 func gfDivide(a, b gfElement) gfElement {109 -1 if a == gfZero {110 -1 return gfZero111 -1 } else if b == gfZero {112 -1 log.Panicln("Divide by zero")113 -1 }114 -1115 -1 return gfMultiply(a, gfInverse(b))116 -1 }117 -1118 -1 // gfInverse returns the multiplicative inverse of a, a^-1.119 -1 //120 -1 // a * a^-1 = 1121 -1 func gfInverse(a gfElement) gfElement {122 -1 if a == gfZero {123 -1 log.Panicln("No multiplicative inverse of 0")124 -1 }125 -1126 -1 return gfExpTable[255-gfLogTable[a]]127 -1 }128 -1129 -1 // a^i | bits | polynomial | decimal130 -1 // --------------------------------------------------------------------------131 -1 // 0 | 000000000 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 0132 -1 // a^0 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1133 -1 // a^1 | 000000010 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 2134 -1 // a^2 | 000000100 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 4135 -1 // a^3 | 000001000 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 8136 -1 // a^4 | 000010000 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 16137 -1 // a^5 | 000100000 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 32138 -1 // a^6 | 001000000 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 64139 -1 // a^7 | 010000000 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 128140 -1 // a^8 | 000011101 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 29141 -1 // a^9 | 000111010 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 58142 -1 // a^10 | 001110100 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 116143 -1 // a^11 | 011101000 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 232144 -1 // a^12 | 011001101 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 205145 -1 // a^13 | 010000111 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 135146 -1 // a^14 | 000010011 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 19147 -1 // a^15 | 000100110 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 38148 -1 // a^16 | 001001100 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 76149 -1 // a^17 | 010011000 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 152150 -1 // a^18 | 000101101 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 45151 -1 // a^19 | 001011010 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 90152 -1 // a^20 | 010110100 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 180153 -1 // a^21 | 001110101 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 117154 -1 // a^22 | 011101010 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 234155 -1 // a^23 | 011001001 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 201156 -1 // a^24 | 010001111 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 143157 -1 // a^25 | 000000011 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 3158 -1 // a^26 | 000000110 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 6159 -1 // a^27 | 000001100 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 12160 -1 // a^28 | 000011000 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 24161 -1 // a^29 | 000110000 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 48162 -1 // a^30 | 001100000 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 96163 -1 // a^31 | 011000000 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 192164 -1 // a^32 | 010011101 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 157165 -1 // a^33 | 000100111 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 39166 -1 // a^34 | 001001110 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 78167 -1 // a^35 | 010011100 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 156168 -1 // a^36 | 000100101 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 37169 -1 // a^37 | 001001010 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 74170 -1 // a^38 | 010010100 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 148171 -1 // a^39 | 000110101 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 53172 -1 // a^40 | 001101010 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 106173 -1 // a^41 | 011010100 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 212174 -1 // a^42 | 010110101 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 181175 -1 // a^43 | 001110111 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 119176 -1 // a^44 | 011101110 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 238177 -1 // a^45 | 011000001 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 193178 -1 // a^46 | 010011111 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 159179 -1 // a^47 | 000100011 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 35180 -1 // a^48 | 001000110 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 70181 -1 // a^49 | 010001100 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 140182 -1 // a^50 | 000000101 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 5183 -1 // a^51 | 000001010 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 10184 -1 // a^52 | 000010100 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 20185 -1 // a^53 | 000101000 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 40186 -1 // a^54 | 001010000 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 80187 -1 // a^55 | 010100000 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 160188 -1 // a^56 | 001011101 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 93189 -1 // a^57 | 010111010 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 186190 -1 // a^58 | 001101001 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 105191 -1 // a^59 | 011010010 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 210192 -1 // a^60 | 010111001 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 185193 -1 // a^61 | 001101111 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 111194 -1 // a^62 | 011011110 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 222195 -1 // a^63 | 010100001 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 161196 -1 // a^64 | 001011111 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 95197 -1 // a^65 | 010111110 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 190198 -1 // a^66 | 001100001 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 97199 -1 // a^67 | 011000010 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 194200 -1 // a^68 | 010011001 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 153201 -1 // a^69 | 000101111 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 47202 -1 // a^70 | 001011110 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 94203 -1 // a^71 | 010111100 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 188204 -1 // a^72 | 001100101 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 101205 -1 // a^73 | 011001010 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 202206 -1 // a^74 | 010001001 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 137207 -1 // a^75 | 000001111 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 15208 -1 // a^76 | 000011110 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 30209 -1 // a^77 | 000111100 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 60210 -1 // a^78 | 001111000 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 120211 -1 // a^79 | 011110000 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 240212 -1 // a^80 | 011111101 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 253213 -1 // a^81 | 011100111 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 231214 -1 // a^82 | 011010011 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 211215 -1 // a^83 | 010111011 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 187216 -1 // a^84 | 001101011 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 107217 -1 // a^85 | 011010110 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 214218 -1 // a^86 | 010110001 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 177219 -1 // a^87 | 001111111 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 127220 -1 // a^88 | 011111110 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 254221 -1 // a^89 | 011100001 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 225222 -1 // a^90 | 011011111 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 223223 -1 // a^91 | 010100011 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 163224 -1 // a^92 | 001011011 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 91225 -1 // a^93 | 010110110 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 182226 -1 // a^94 | 001110001 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 113227 -1 // a^95 | 011100010 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 226228 -1 // a^96 | 011011001 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 217229 -1 // a^97 | 010101111 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 175230 -1 // a^98 | 001000011 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 67231 -1 // a^99 | 010000110 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 134232 -1 // a^100 | 000010001 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 17233 -1 // a^101 | 000100010 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 34234 -1 // a^102 | 001000100 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 68235 -1 // a^103 | 010001000 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 136236 -1 // a^104 | 000001101 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 13237 -1 // a^105 | 000011010 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 26238 -1 // a^106 | 000110100 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 52239 -1 // a^107 | 001101000 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 104240 -1 // a^108 | 011010000 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 208241 -1 // a^109 | 010111101 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 189242 -1 // a^110 | 001100111 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 103243 -1 // a^111 | 011001110 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 206244 -1 // a^112 | 010000001 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 129245 -1 // a^113 | 000011111 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 31246 -1 // a^114 | 000111110 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 62247 -1 // a^115 | 001111100 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 124248 -1 // a^116 | 011111000 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 248249 -1 // a^117 | 011101101 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 237250 -1 // a^118 | 011000111 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 199251 -1 // a^119 | 010010011 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 147252 -1 // a^120 | 000111011 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 59253 -1 // a^121 | 001110110 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 118254 -1 // a^122 | 011101100 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 236255 -1 // a^123 | 011000101 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 197256 -1 // a^124 | 010010111 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 151257 -1 // a^125 | 000110011 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 51258 -1 // a^126 | 001100110 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 102259 -1 // a^127 | 011001100 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 204260 -1 // a^128 | 010000101 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 133261 -1 // a^129 | 000010111 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 23262 -1 // a^130 | 000101110 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 46263 -1 // a^131 | 001011100 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 92264 -1 // a^132 | 010111000 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 184265 -1 // a^133 | 001101101 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 109266 -1 // a^134 | 011011010 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 218267 -1 // a^135 | 010101001 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 169268 -1 // a^136 | 001001111 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 79269 -1 // a^137 | 010011110 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 158270 -1 // a^138 | 000100001 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 33271 -1 // a^139 | 001000010 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 66272 -1 // a^140 | 010000100 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 132273 -1 // a^141 | 000010101 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 21274 -1 // a^142 | 000101010 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 42275 -1 // a^143 | 001010100 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 84276 -1 // a^144 | 010101000 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 168277 -1 // a^145 | 001001101 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 77278 -1 // a^146 | 010011010 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 154279 -1 // a^147 | 000101001 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 41280 -1 // a^148 | 001010010 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 82281 -1 // a^149 | 010100100 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 164282 -1 // a^150 | 001010101 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 85283 -1 // a^151 | 010101010 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 170284 -1 // a^152 | 001001001 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 73285 -1 // a^153 | 010010010 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 146286 -1 // a^154 | 000111001 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 57287 -1 // a^155 | 001110010 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 114288 -1 // a^156 | 011100100 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 228289 -1 // a^157 | 011010101 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 213290 -1 // a^158 | 010110111 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 183291 -1 // a^159 | 001110011 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 115292 -1 // a^160 | 011100110 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 230293 -1 // a^161 | 011010001 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 209294 -1 // a^162 | 010111111 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 191295 -1 // a^163 | 001100011 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 99296 -1 // a^164 | 011000110 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 198297 -1 // a^165 | 010010001 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 145298 -1 // a^166 | 000111111 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 63299 -1 // a^167 | 001111110 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 126300 -1 // a^168 | 011111100 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 252301 -1 // a^169 | 011100101 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 229302 -1 // a^170 | 011010111 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 215303 -1 // a^171 | 010110011 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 179304 -1 // a^172 | 001111011 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 123305 -1 // a^173 | 011110110 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 246306 -1 // a^174 | 011110001 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 241307 -1 // a^175 | 011111111 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 255308 -1 // a^176 | 011100011 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 227309 -1 // a^177 | 011011011 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 219310 -1 // a^178 | 010101011 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 171311 -1 // a^179 | 001001011 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 75312 -1 // a^180 | 010010110 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 150313 -1 // a^181 | 000110001 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 49314 -1 // a^182 | 001100010 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 98315 -1 // a^183 | 011000100 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 196316 -1 // a^184 | 010010101 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 149317 -1 // a^185 | 000110111 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 55318 -1 // a^186 | 001101110 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 110319 -1 // a^187 | 011011100 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 220320 -1 // a^188 | 010100101 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 165321 -1 // a^189 | 001010111 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 87322 -1 // a^190 | 010101110 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 174323 -1 // a^191 | 001000001 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 65324 -1 // a^192 | 010000010 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 130325 -1 // a^193 | 000011001 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 25326 -1 // a^194 | 000110010 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 50327 -1 // a^195 | 001100100 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 100328 -1 // a^196 | 011001000 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 200329 -1 // a^197 | 010001101 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 141330 -1 // a^198 | 000000111 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 7331 -1 // a^199 | 000001110 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 14332 -1 // a^200 | 000011100 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 28333 -1 // a^201 | 000111000 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 56334 -1 // a^202 | 001110000 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 112335 -1 // a^203 | 011100000 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 224336 -1 // a^204 | 011011101 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 221337 -1 // a^205 | 010100111 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 167338 -1 // a^206 | 001010011 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 83339 -1 // a^207 | 010100110 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 166340 -1 // a^208 | 001010001 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 81341 -1 // a^209 | 010100010 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 162342 -1 // a^210 | 001011001 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 89343 -1 // a^211 | 010110010 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 178344 -1 // a^212 | 001111001 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 121345 -1 // a^213 | 011110010 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 242346 -1 // a^214 | 011111001 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 249347 -1 // a^215 | 011101111 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 239348 -1 // a^216 | 011000011 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 195349 -1 // a^217 | 010011011 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 155350 -1 // a^218 | 000101011 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 43351 -1 // a^219 | 001010110 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 86352 -1 // a^220 | 010101100 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 172353 -1 // a^221 | 001000101 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 69354 -1 // a^222 | 010001010 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 138355 -1 // a^223 | 000001001 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 9356 -1 // a^224 | 000010010 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 18357 -1 // a^225 | 000100100 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 36358 -1 // a^226 | 001001000 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 72359 -1 // a^227 | 010010000 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 144360 -1 // a^228 | 000111101 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 61361 -1 // a^229 | 001111010 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 122362 -1 // a^230 | 011110100 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 244363 -1 // a^231 | 011110101 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 245364 -1 // a^232 | 011110111 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 247365 -1 // a^233 | 011110011 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 243366 -1 // a^234 | 011111011 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 251367 -1 // a^235 | 011101011 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 235368 -1 // a^236 | 011001011 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 203369 -1 // a^237 | 010001011 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 139370 -1 // a^238 | 000001011 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 11371 -1 // a^239 | 000010110 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 22372 -1 // a^240 | 000101100 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 44373 -1 // a^241 | 001011000 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 88374 -1 // a^242 | 010110000 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 176375 -1 // a^243 | 001111101 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 125376 -1 // a^244 | 011111010 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 250377 -1 // a^245 | 011101001 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 233378 -1 // a^246 | 011001111 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 207379 -1 // a^247 | 010000011 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 131380 -1 // a^248 | 000011011 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 27381 -1 // a^249 | 000110110 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 54382 -1 // a^250 | 001101100 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 108383 -1 // a^251 | 011011000 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 216384 -1 // a^252 | 010101101 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 173385 -1 // a^253 | 001000111 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 71386 -1 // a^254 | 010001110 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 142387 -1 // a^255 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1
diff --git a/reedsolomon/gf_poly.go b/reedsolomon/gf_poly.go
@@ -1,216 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 package reedsolomon5 -16 -1 import (7 -1 "fmt"8 -1 "log"9 -110 -1 bitset "github.com/skip2/go-qrcode/bitset"11 -1 )12 -113 -1 // gfPoly is a polynomial over GF(2^8).14 -1 type gfPoly struct {15 -1 // The ith value is the coefficient of the ith degree of x.16 -1 // term[0]*(x^0) + term[1]*(x^1) + term[2]*(x^2) ...17 -1 term []gfElement18 -1 }19 -120 -1 // newGFPolyFromData returns |data| as a polynomial over GF(2^8).21 -1 //22 -1 // Each data byte becomes the coefficient of an x term.23 -1 //24 -1 // For an n byte input the polynomial is:25 -1 // data[n-1]*(x^n-1) + data[n-2]*(x^n-2) ... + data[0]*(x^0).26 -1 func newGFPolyFromData(data *bitset.Bitset) gfPoly {27 -1 numTotalBytes := data.Len() / 828 -1 if data.Len()%8 != 0 {29 -1 numTotalBytes++30 -1 }31 -132 -1 result := gfPoly{term: make([]gfElement, numTotalBytes)}33 -134 -1 i := numTotalBytes - 135 -1 for j := 0; j < data.Len(); j += 8 {36 -1 result.term[i] = gfElement(data.ByteAt(j))37 -1 i--38 -1 }39 -140 -1 return result41 -1 }42 -143 -1 // newGFPolyMonomial returns term*(x^degree).44 -1 func newGFPolyMonomial(term gfElement, degree int) gfPoly {45 -1 if term == gfZero {46 -1 return gfPoly{}47 -1 }48 -149 -1 result := gfPoly{term: make([]gfElement, degree+1)}50 -1 result.term[degree] = term51 -152 -1 return result53 -1 }54 -155 -1 func (e gfPoly) data(numTerms int) []byte {56 -1 result := make([]byte, numTerms)57 -158 -1 i := numTerms - len(e.term)59 -1 for j := len(e.term) - 1; j >= 0; j-- {60 -1 result[i] = byte(e.term[j])61 -1 i++62 -1 }63 -164 -1 return result65 -1 }66 -167 -1 // numTerms returns the number of68 -1 func (e gfPoly) numTerms() int {69 -1 return len(e.term)70 -1 }71 -172 -1 // gfPolyMultiply returns a * b.73 -1 func gfPolyMultiply(a, b gfPoly) gfPoly {74 -1 numATerms := a.numTerms()75 -1 numBTerms := b.numTerms()76 -177 -1 result := gfPoly{term: make([]gfElement, numATerms+numBTerms)}78 -179 -1 for i := 0; i < numATerms; i++ {80 -1 for j := 0; j < numBTerms; j++ {81 -1 if a.term[i] != 0 && b.term[j] != 0 {82 -1 monomial := gfPoly{term: make([]gfElement, i+j+1)}83 -1 monomial.term[i+j] = gfMultiply(a.term[i], b.term[j])84 -185 -1 result = gfPolyAdd(result, monomial)86 -1 }87 -1 }88 -1 }89 -190 -1 return result.normalised()91 -1 }92 -193 -1 // gfPolyRemainder return the remainder of numerator / denominator.94 -1 func gfPolyRemainder(numerator, denominator gfPoly) gfPoly {95 -1 if denominator.equals(gfPoly{}) {96 -1 log.Panicln("Remainder by zero")97 -1 }98 -199 -1 remainder := numerator100 -1101 -1 for remainder.numTerms() >= denominator.numTerms() {102 -1 degree := remainder.numTerms() - denominator.numTerms()103 -1 coefficient := gfDivide(remainder.term[remainder.numTerms()-1],104 -1 denominator.term[denominator.numTerms()-1])105 -1106 -1 divisor := gfPolyMultiply(denominator,107 -1 newGFPolyMonomial(coefficient, degree))108 -1109 -1 remainder = gfPolyAdd(remainder, divisor)110 -1 }111 -1112 -1 return remainder.normalised()113 -1 }114 -1115 -1 // gfPolyAdd returns a + b.116 -1 func gfPolyAdd(a, b gfPoly) gfPoly {117 -1 numATerms := a.numTerms()118 -1 numBTerms := b.numTerms()119 -1120 -1 numTerms := numATerms121 -1 if numBTerms > numTerms {122 -1 numTerms = numBTerms123 -1 }124 -1125 -1 result := gfPoly{term: make([]gfElement, numTerms)}126 -1127 -1 for i := 0; i < numTerms; i++ {128 -1 switch {129 -1 case numATerms > i && numBTerms > i:130 -1 result.term[i] = gfAdd(a.term[i], b.term[i])131 -1 case numATerms > i:132 -1 result.term[i] = a.term[i]133 -1 default:134 -1 result.term[i] = b.term[i]135 -1 }136 -1 }137 -1138 -1 return result.normalised()139 -1 }140 -1141 -1 func (e gfPoly) normalised() gfPoly {142 -1 numTerms := e.numTerms()143 -1 maxNonzeroTerm := numTerms - 1144 -1145 -1 for i := numTerms - 1; i >= 0; i-- {146 -1 if e.term[i] != 0 {147 -1 break148 -1 }149 -1150 -1 maxNonzeroTerm = i - 1151 -1 }152 -1153 -1 if maxNonzeroTerm < 0 {154 -1 return gfPoly{}155 -1 } else if maxNonzeroTerm < numTerms-1 {156 -1 e.term = e.term[0 : maxNonzeroTerm+1]157 -1 }158 -1159 -1 return e160 -1 }161 -1162 -1 func (e gfPoly) string(useIndexForm bool) string {163 -1 var str string164 -1 numTerms := e.numTerms()165 -1166 -1 for i := numTerms - 1; i >= 0; i-- {167 -1 if e.term[i] > 0 {168 -1 if len(str) > 0 {169 -1 str += " + "170 -1 }171 -1172 -1 if !useIndexForm {173 -1 str += fmt.Sprintf("%dx^%d", e.term[i], i)174 -1 } else {175 -1 str += fmt.Sprintf("a^%dx^%d", gfLogTable[e.term[i]], i)176 -1 }177 -1 }178 -1 }179 -1180 -1 if len(str) == 0 {181 -1 str = "0"182 -1 }183 -1184 -1 return str185 -1 }186 -1187 -1 // equals returns true if e == other.188 -1 func (e gfPoly) equals(other gfPoly) bool {189 -1 var minecPoly *gfPoly190 -1 var maxecPoly *gfPoly191 -1192 -1 if e.numTerms() > other.numTerms() {193 -1 minecPoly = &other194 -1 maxecPoly = &e195 -1 } else {196 -1 minecPoly = &e197 -1 maxecPoly = &other198 -1 }199 -1200 -1 numMinTerms := minecPoly.numTerms()201 -1 numMaxTerms := maxecPoly.numTerms()202 -1203 -1 for i := 0; i < numMinTerms; i++ {204 -1 if e.term[i] != other.term[i] {205 -1 return false206 -1 }207 -1 }208 -1209 -1 for i := numMinTerms; i < numMaxTerms; i++ {210 -1 if maxecPoly.term[i] != 0 {211 -1 return false212 -1 }213 -1 }214 -1215 -1 return true216 -1 }
diff --git a/reedsolomon/reed_solomon.go b/reedsolomon/reed_solomon.go
@@ -1,73 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 // Package reedsolomon provides error correction encoding for QR Code 2005.5 -1 //6 -1 // QR Code 2005 uses a Reed-Solomon error correcting code to detect and correct7 -1 // errors encountered during decoding.8 -1 //9 -1 // The generated RS codes are systematic, and consist of the input data with10 -1 // error correction bytes appended.11 -1 package reedsolomon12 -113 -1 import (14 -1 "log"15 -116 -1 bitset "github.com/skip2/go-qrcode/bitset"17 -1 )18 -119 -1 // Encode data for QR Code 2005 using the appropriate Reed-Solomon code.20 -1 //21 -1 // numECBytes is the number of error correction bytes to append, and is22 -1 // determined by the target QR Code's version and error correction level.23 -1 //24 -1 // ISO/IEC 18004 table 9 specifies the numECBytes required. e.g. a 1-L code has25 -1 // numECBytes=7.26 -1 func Encode(data *bitset.Bitset, numECBytes int) *bitset.Bitset {27 -1 // Create a polynomial representing |data|.28 -1 //29 -1 // The bytes are interpreted as the sequence of coefficients of a polynomial.30 -1 // The last byte's value becomes the x^0 coefficient, the second to last31 -1 // becomes the x^1 coefficient and so on.32 -1 ecpoly := newGFPolyFromData(data)33 -1 ecpoly = gfPolyMultiply(ecpoly, newGFPolyMonomial(gfOne, numECBytes))34 -135 -1 // Pick the generator polynomial.36 -1 generator := rsGeneratorPoly(numECBytes)37 -138 -1 // Generate the error correction bytes.39 -1 remainder := gfPolyRemainder(ecpoly, generator)40 -141 -1 // Combine the data & error correcting bytes.42 -1 // The mathematically correct answer is:43 -1 //44 -1 // result := gfPolyAdd(ecpoly, remainder).45 -1 //46 -1 // The encoding used by QR Code 2005 is slightly different this result: To47 -1 // preserve the original |data| bit sequence exactly, the data and remainder48 -1 // are combined manually below. This ensures any most significant zero bits49 -1 // are preserved (and not optimised away).50 -1 result := bitset.Clone(data)51 -1 result.AppendBytes(remainder.data(numECBytes))52 -153 -1 return result54 -1 }55 -156 -1 // rsGeneratorPoly returns the Reed-Solomon generator polynomial with |degree|.57 -1 //58 -1 // The generator polynomial is calculated as:59 -1 // (x + a^0)(x + a^1)...(x + a^degree-1)60 -1 func rsGeneratorPoly(degree int) gfPoly {61 -1 if degree < 2 {62 -1 log.Panic("degree < 2")63 -1 }64 -165 -1 generator := gfPoly{term: []gfElement{1}}66 -167 -1 for i := 0; i < degree; i++ {68 -1 nextPoly := gfPoly{term: []gfElement{gfExpTable[i], 1}}69 -1 generator = gfPolyMultiply(generator, nextPoly)70 -1 }71 -172 -1 return generator73 -1 }
diff --git a/regular_symbol.go b/regular_symbol.go
@@ -1,315 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 package qrcode5 -16 -1 import (7 -1 bitset "github.com/skip2/go-qrcode/bitset"8 -1 )9 -110 -1 type regularSymbol struct {11 -1 version qrCodeVersion12 -1 mask int13 -114 -1 data *bitset.Bitset15 -116 -1 symbol *symbol17 -1 size int18 -1 }19 -120 -1 // Abbreviated true/false.21 -1 const (22 -1 b0 = false23 -1 b1 = true24 -1 )25 -126 -1 var (27 -1 alignmentPatternCenter = [][]int{28 -1 {}, // Version 0 doesn't exist.29 -1 {}, // Version 1 doesn't use alignment patterns.30 -1 {6, 18},31 -1 {6, 22},32 -1 {6, 26},33 -1 {6, 30},34 -1 {6, 34},35 -1 {6, 22, 38},36 -1 {6, 24, 42},37 -1 {6, 26, 46},38 -1 {6, 28, 50},39 -1 {6, 30, 54},40 -1 {6, 32, 58},41 -1 {6, 34, 62},42 -1 {6, 26, 46, 66},43 -1 {6, 26, 48, 70},44 -1 {6, 26, 50, 74},45 -1 {6, 30, 54, 78},46 -1 {6, 30, 56, 82},47 -1 {6, 30, 58, 86},48 -1 {6, 34, 62, 90},49 -1 {6, 28, 50, 72, 94},50 -1 {6, 26, 50, 74, 98},51 -1 {6, 30, 54, 78, 102},52 -1 {6, 28, 54, 80, 106},53 -1 {6, 32, 58, 84, 110},54 -1 {6, 30, 58, 86, 114},55 -1 {6, 34, 62, 90, 118},56 -1 {6, 26, 50, 74, 98, 122},57 -1 {6, 30, 54, 78, 102, 126},58 -1 {6, 26, 52, 78, 104, 130},59 -1 {6, 30, 56, 82, 108, 134},60 -1 {6, 34, 60, 86, 112, 138},61 -1 {6, 30, 58, 86, 114, 142},62 -1 {6, 34, 62, 90, 118, 146},63 -1 {6, 30, 54, 78, 102, 126, 150},64 -1 {6, 24, 50, 76, 102, 128, 154},65 -1 {6, 28, 54, 80, 106, 132, 158},66 -1 {6, 32, 58, 84, 110, 136, 162},67 -1 {6, 26, 54, 82, 110, 138, 166},68 -1 {6, 30, 58, 86, 114, 142, 170},69 -1 }70 -171 -1 finderPattern = [][]bool{72 -1 {b1, b1, b1, b1, b1, b1, b1},73 -1 {b1, b0, b0, b0, b0, b0, b1},74 -1 {b1, b0, b1, b1, b1, b0, b1},75 -1 {b1, b0, b1, b1, b1, b0, b1},76 -1 {b1, b0, b1, b1, b1, b0, b1},77 -1 {b1, b0, b0, b0, b0, b0, b1},78 -1 {b1, b1, b1, b1, b1, b1, b1},79 -1 }80 -181 -1 finderPatternSize = 782 -183 -1 finderPatternHorizontalBorder = [][]bool{84 -1 {b0, b0, b0, b0, b0, b0, b0, b0},85 -1 }86 -187 -1 finderPatternVerticalBorder = [][]bool{88 -1 {b0},89 -1 {b0},90 -1 {b0},91 -1 {b0},92 -1 {b0},93 -1 {b0},94 -1 {b0},95 -1 {b0},96 -1 }97 -198 -1 alignmentPattern = [][]bool{99 -1 {b1, b1, b1, b1, b1},100 -1 {b1, b0, b0, b0, b1},101 -1 {b1, b0, b1, b0, b1},102 -1 {b1, b0, b0, b0, b1},103 -1 {b1, b1, b1, b1, b1},104 -1 }105 -1 )106 -1107 -1 func buildRegularSymbol(version qrCodeVersion, mask int,108 -1 data *bitset.Bitset, includeQuietZone bool) (*symbol, error) {109 -1110 -1 quietZoneSize := 0111 -1 if includeQuietZone {112 -1 quietZoneSize = version.quietZoneSize()113 -1 }114 -1115 -1 m := ®ularSymbol{116 -1 version: version,117 -1 mask: mask,118 -1 data: data,119 -1120 -1 symbol: newSymbol(version.symbolSize(), quietZoneSize),121 -1 size: version.symbolSize(),122 -1 }123 -1124 -1 m.addFinderPatterns()125 -1 m.addAlignmentPatterns()126 -1 m.addTimingPatterns()127 -1 m.addFormatInfo()128 -1 m.addVersionInfo()129 -1130 -1 ok, err := m.addData()131 -1 if !ok {132 -1 return nil, err133 -1 }134 -1135 -1 return m.symbol, nil136 -1 }137 -1138 -1 func (m *regularSymbol) addFinderPatterns() {139 -1 fpSize := finderPatternSize140 -1 fp := finderPattern141 -1 fpHBorder := finderPatternHorizontalBorder142 -1 fpVBorder := finderPatternVerticalBorder143 -1144 -1 // Top left Finder Pattern.145 -1 m.symbol.set2dPattern(0, 0, fp)146 -1 m.symbol.set2dPattern(0, fpSize, fpHBorder)147 -1 m.symbol.set2dPattern(fpSize, 0, fpVBorder)148 -1149 -1 // Top right Finder Pattern.150 -1 m.symbol.set2dPattern(m.size-fpSize, 0, fp)151 -1 m.symbol.set2dPattern(m.size-fpSize-1, fpSize, fpHBorder)152 -1 m.symbol.set2dPattern(m.size-fpSize-1, 0, fpVBorder)153 -1154 -1 // Bottom left Finder Pattern.155 -1 m.symbol.set2dPattern(0, m.size-fpSize, fp)156 -1 m.symbol.set2dPattern(0, m.size-fpSize-1, fpHBorder)157 -1 m.symbol.set2dPattern(fpSize, m.size-fpSize-1, fpVBorder)158 -1 }159 -1160 -1 func (m *regularSymbol) addAlignmentPatterns() {161 -1 for _, x := range alignmentPatternCenter[m.version.version] {162 -1 for _, y := range alignmentPatternCenter[m.version.version] {163 -1 if !m.symbol.empty(x, y) {164 -1 continue165 -1 }166 -1167 -1 m.symbol.set2dPattern(x-2, y-2, alignmentPattern)168 -1 }169 -1 }170 -1 }171 -1172 -1 func (m *regularSymbol) addTimingPatterns() {173 -1 value := true174 -1175 -1 for i := finderPatternSize + 1; i < m.size-finderPatternSize; i++ {176 -1 m.symbol.set(i, finderPatternSize-1, value)177 -1 m.symbol.set(finderPatternSize-1, i, value)178 -1179 -1 value = !value180 -1 }181 -1 }182 -1183 -1 func (m *regularSymbol) addFormatInfo() {184 -1 fpSize := finderPatternSize185 -1 l := formatInfoLengthBits - 1186 -1187 -1 f := m.version.formatInfo(m.mask)188 -1189 -1 // Bits 0-7, under the top right finder pattern.190 -1 for i := 0; i <= 7; i++ {191 -1 m.symbol.set(m.size-i-1, fpSize+1, f.At(l-i))192 -1 }193 -1194 -1 // Bits 0-5, right of the top left finder pattern.195 -1 for i := 0; i <= 5; i++ {196 -1 m.symbol.set(fpSize+1, i, f.At(l-i))197 -1 }198 -1199 -1 // Bits 6-8 on the corner of the top left finder pattern.200 -1 m.symbol.set(fpSize+1, fpSize, f.At(l-6))201 -1 m.symbol.set(fpSize+1, fpSize+1, f.At(l-7))202 -1 m.symbol.set(fpSize, fpSize+1, f.At(l-8))203 -1204 -1 // Bits 9-14 on the underside of the top left finder pattern.205 -1 for i := 9; i <= 14; i++ {206 -1 m.symbol.set(14-i, fpSize+1, f.At(l-i))207 -1 }208 -1209 -1 // Bits 8-14 on the right side of the bottom left finder pattern.210 -1 for i := 8; i <= 14; i++ {211 -1 m.symbol.set(fpSize+1, m.size-fpSize+i-8, f.At(l-i))212 -1 }213 -1214 -1 // Always dark symbol.215 -1 m.symbol.set(fpSize+1, m.size-fpSize-1, true)216 -1 }217 -1218 -1 func (m *regularSymbol) addVersionInfo() {219 -1 fpSize := finderPatternSize220 -1221 -1 v := m.version.versionInfo()222 -1 l := versionInfoLengthBits - 1223 -1224 -1 if v == nil {225 -1 return226 -1 }227 -1228 -1 for i := 0; i < v.Len(); i++ {229 -1 // Above the bottom left finder pattern.230 -1 m.symbol.set(i/3, m.size-fpSize-4+i%3, v.At(l-i))231 -1232 -1 // Left of the top right finder pattern.233 -1 m.symbol.set(m.size-fpSize-4+i%3, i/3, v.At(l-i))234 -1 }235 -1 }236 -1237 -1 type direction uint8238 -1239 -1 const (240 -1 up direction = iota241 -1 down242 -1 )243 -1244 -1 func (m *regularSymbol) addData() (bool, error) {245 -1 xOffset := 1246 -1 dir := up247 -1248 -1 x := m.size - 2249 -1 y := m.size - 1250 -1251 -1 for i := 0; i < m.data.Len(); i++ {252 -1 var mask bool253 -1 switch m.mask {254 -1 case 0:255 -1 mask = (y+x+xOffset)%2 == 0256 -1 case 1:257 -1 mask = y%2 == 0258 -1 case 2:259 -1 mask = (x+xOffset)%3 == 0260 -1 case 3:261 -1 mask = (y+x+xOffset)%3 == 0262 -1 case 4:263 -1 mask = (y/2+(x+xOffset)/3)%2 == 0264 -1 case 5:265 -1 mask = (y*(x+xOffset))%2+(y*(x+xOffset))%3 == 0266 -1 case 6:267 -1 mask = ((y*(x+xOffset))%2+((y*(x+xOffset))%3))%2 == 0268 -1 case 7:269 -1 mask = ((y+x+xOffset)%2+((y*(x+xOffset))%3))%2 == 0270 -1 }271 -1272 -1 // != is equivalent to XOR.273 -1 m.symbol.set(x+xOffset, y, mask != m.data.At(i))274 -1275 -1 if i == m.data.Len()-1 {276 -1 break277 -1 }278 -1279 -1 // Find next free bit in the symbol.280 -1 for {281 -1 if xOffset == 1 {282 -1 xOffset = 0283 -1 } else {284 -1 xOffset = 1285 -1286 -1 if dir == up {287 -1 if y > 0 {288 -1 y--289 -1 } else {290 -1 dir = down291 -1 x -= 2292 -1 }293 -1 } else {294 -1 if y < m.size-1 {295 -1 y++296 -1 } else {297 -1 dir = up298 -1 x -= 2299 -1 }300 -1 }301 -1 }302 -1303 -1 // Skip over the vertical timing pattern entirely.304 -1 if x == 5 {305 -1 x--306 -1 }307 -1308 -1 if m.symbol.empty(x+xOffset, y) {309 -1 break310 -1 }311 -1 }312 -1 }313 -1314 -1 return true, nil315 -1 }
diff --git a/render.go b/render.go
@@ -0,0 +1,186 @@
-1 1 package qrcode
-1 2
-1 3 type bitmap struct {
-1 4 module [][]bool
-1 5 isUsed [][]bool
-1 6 size int
-1 7 }
-1 8
-1 9 func newBitmap(size int) *bitmap {
-1 10 var b bitmap
-1 11
-1 12 b.module = make([][]bool, size)
-1 13 b.isUsed = make([][]bool, size)
-1 14
-1 15 for i := range b.module {
-1 16 b.module[i] = make([]bool, size)
-1 17 b.isUsed[i] = make([]bool, size)
-1 18 }
-1 19
-1 20 b.size = size
-1 21
-1 22 return &b
-1 23 }
-1 24
-1 25 func (b *bitmap) norm(x int, y int) (int, int) {
-1 26 return (x + b.size) % b.size, (y + b.size) % b.size
-1 27 }
-1 28
-1 29 func (b *bitmap) get(x int, y int) bool {
-1 30 x, y = b.norm(x, y)
-1 31 return b.module[y][x]
-1 32 }
-1 33
-1 34 func (b *bitmap) empty(x int, y int) bool {
-1 35 x, y = b.norm(x, y)
-1 36 return !b.isUsed[y][x]
-1 37 }
-1 38
-1 39 func (b *bitmap) set(x int, y int, v bool) {
-1 40 x, y = b.norm(x, y)
-1 41 b.module[y][x] = v
-1 42 b.isUsed[y][x] = true
-1 43 }
-1 44
-1 45 func (b *bitmap) rect(x0 int, y0 int, width int, height int, value bool) {
-1 46 for y := y0; y < y0+height; y++ {
-1 47 for x := x0; x < x0+width; x++ {
-1 48 b.set(x, y, value)
-1 49 }
-1 50 }
-1 51 }
-1 52
-1 53 func (b *bitmap) renderFinderPatterns() {
-1 54 // Top left Finder Pattern.
-1 55 b.rect(0, 0, 9, 9, false)
-1 56 b.rect(0, 0, 7, 7, true)
-1 57 b.rect(1, 1, 5, 5, false)
-1 58 b.rect(2, 2, 3, 3, true)
-1 59
-1 60 // Top right Finder Pattern.
-1 61 b.rect(-8, 0, 8, 9, false)
-1 62 b.rect(-7, 0, 7, 7, true)
-1 63 b.rect(-6, 1, 5, 5, false)
-1 64 b.rect(-5, 2, 3, 3, true)
-1 65
-1 66 // Bottom left Finder Pattern.
-1 67 b.rect(0, -8, 9, 8, false)
-1 68 b.rect(0, -7, 7, 7, true)
-1 69 b.rect(1, -6, 5, 5, false)
-1 70 b.rect(2, -5, 3, 3, true)
-1 71 }
-1 72
-1 73 func (b *bitmap) renderAlignmentPatterns(version *version) {
-1 74 for _, x := range version.alignmentPatternCenter {
-1 75 for _, y := range version.alignmentPatternCenter {
-1 76 if !b.empty(x, y) {
-1 77 continue
-1 78 }
-1 79
-1 80 b.rect(x-2, y-2, 5, 5, true)
-1 81 b.rect(x-1, y-1, 3, 3, false)
-1 82 b.set(x, y, true)
-1 83 }
-1 84 }
-1 85 }
-1 86
-1 87 func (b *bitmap) renderTimingPatterns() {
-1 88 value := true
-1 89
-1 90 for i := 7 + 1; i < b.size-7; i++ {
-1 91 b.set(i, 7-1, value)
-1 92 b.set(7-1, i, value)
-1 93 value = !value
-1 94 }
-1 95 }
-1 96
-1 97 func (b *bitmap) renderFormatInfo() {
-1 98 b.set(8, 1, true)
-1 99 b.set(8, 4, true)
-1 100 b.set(8, -5, true)
-1 101 b.set(8, -3, true)
-1 102 b.set(8, -1, true)
-1 103
-1 104 b.set(-2, 8, true)
-1 105 b.set(-5, 8, true)
-1 106 b.set(4, 8, true)
-1 107 b.set(2, 8, true)
-1 108 b.set(0, 8, true)
-1 109
-1 110 b.set(8, -8, true)
-1 111 }
-1 112
-1 113 func (b *bitmap) renderVersionInfo(v *version) {
-1 114 if v.version < 7 {
-1 115 return
-1 116 }
-1 117
-1 118 for i := 0; i < 18; i++ {
-1 119 b.set(i/3, -11+i%3, (v.bitSequence>>i)&1 == 1)
-1 120 b.set(-11+i%3, i/3, (v.bitSequence>>i)&1 == 1)
-1 121 }
-1 122 }
-1 123
-1 124 func (b *bitmap) renderData(data *Bitset) {
-1 125 xOffset := 1
-1 126 up := true
-1 127
-1 128 x := b.size - 2
-1 129 y := b.size - 1
-1 130
-1 131 for i := 0; i < data.Length; i++ {
-1 132 mask := (y+x+xOffset)%2 == 0
-1 133
-1 134 // != is equivalent to XOR.
-1 135 b.set(x+xOffset, y, mask != data.At(i))
-1 136
-1 137 if i == data.Length-1 {
-1 138 break
-1 139 }
-1 140
-1 141 // Find next free bit in the symbol.
-1 142 for {
-1 143 if xOffset == 1 {
-1 144 xOffset = 0
-1 145 } else {
-1 146 xOffset = 1
-1 147
-1 148 if up {
-1 149 if y > 0 {
-1 150 y--
-1 151 } else {
-1 152 up = false
-1 153 x -= 2
-1 154 }
-1 155 } else {
-1 156 if y < b.size-1 {
-1 157 y++
-1 158 } else {
-1 159 up = true
-1 160 x -= 2
-1 161 }
-1 162 }
-1 163 }
-1 164
-1 165 // Skip over the vertical timing pattern entirely.
-1 166 if x == 5 {
-1 167 x--
-1 168 }
-1 169
-1 170 if b.empty(x+xOffset, y) {
-1 171 break
-1 172 }
-1 173 }
-1 174 }
-1 175 }
-1 176
-1 177 func render(data *Bitset, version *version) *bitmap {
-1 178 b := newBitmap(version.bitmapSize())
-1 179 b.renderFinderPatterns()
-1 180 b.renderAlignmentPatterns(version)
-1 181 b.renderTimingPatterns()
-1 182 b.renderFormatInfo()
-1 183 b.renderVersionInfo(version)
-1 184 b.renderData(data)
-1 185 return b
-1 186 }
diff --git a/symbol.go b/symbol.go
@@ -1,309 +0,0 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 -1 package qrcode5 -16 -1 // symbol is a 2D array of bits representing a QR Code symbol.7 -1 //8 -1 // A symbol consists of size*size modules, with each module normally drawn as a9 -1 // black or white square. The symbol also has a border of quietZoneSize modules.10 -1 //11 -1 // A (fictional) size=2, quietZoneSize=1 QR Code looks like:12 -1 //13 -1 // +----+14 -1 // | |15 -1 // | ab |16 -1 // | cd |17 -1 // | |18 -1 // +----+19 -1 //20 -1 // For ease of implementation, the functions to set/get bits ignore the border,21 -1 // so (0,0)=a, (0,1)=b, (1,0)=c, and (1,1)=d. The entire symbol (including the22 -1 // border) is returned by bitmap().23 -1 //24 -1 type symbol struct {25 -1 // Value of module at [y][x]. True is set.26 -1 module [][]bool27 -128 -1 // True if the module at [y][x] is used (to either true or false).29 -1 // Used to identify unused modules.30 -1 isUsed [][]bool31 -132 -1 // Combined width/height of the symbol and quiet zones.33 -1 //34 -1 // size = symbolSize + 2*quietZoneSize.35 -1 size int36 -137 -1 // Width/height of the symbol only.38 -1 symbolSize int39 -140 -1 // Width/height of a single quiet zone.41 -1 quietZoneSize int42 -1 }43 -144 -1 // newSymbol constructs a symbol of size size*size, with a border of45 -1 // quietZoneSize.46 -1 func newSymbol(size int, quietZoneSize int) *symbol {47 -1 var m symbol48 -149 -1 m.module = make([][]bool, size+2*quietZoneSize)50 -1 m.isUsed = make([][]bool, size+2*quietZoneSize)51 -152 -1 for i := range m.module {53 -1 m.module[i] = make([]bool, size+2*quietZoneSize)54 -1 m.isUsed[i] = make([]bool, size+2*quietZoneSize)55 -1 }56 -157 -1 m.size = size + 2*quietZoneSize58 -1 m.symbolSize = size59 -1 m.quietZoneSize = quietZoneSize60 -161 -1 return &m62 -1 }63 -164 -1 // get returns the module value at (x, y).65 -1 func (m *symbol) get(x int, y int) (v bool) {66 -1 v = m.module[y+m.quietZoneSize][x+m.quietZoneSize]67 -1 return68 -1 }69 -170 -1 // empty returns true if the module at (x, y) has not been set (to either true71 -1 // or false).72 -1 func (m *symbol) empty(x int, y int) bool {73 -1 return !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize]74 -1 }75 -176 -1 // numEmptyModules returns the number of empty modules.77 -1 //78 -1 // Initially numEmptyModules is symbolSize * symbolSize. After every module has79 -1 // been set (to either true or false), the number of empty modules is zero.80 -1 func (m *symbol) numEmptyModules() int {81 -1 var count int82 -1 for y := 0; y < m.symbolSize; y++ {83 -1 for x := 0; x < m.symbolSize; x++ {84 -1 if !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] {85 -1 count++86 -1 }87 -1 }88 -1 }89 -190 -1 return count91 -1 }92 -193 -1 // set sets the module at (x, y) to v.94 -1 func (m *symbol) set(x int, y int, v bool) {95 -1 m.module[y+m.quietZoneSize][x+m.quietZoneSize] = v96 -1 m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] = true97 -1 }98 -199 -1 // set2dPattern sets a 2D array of modules, starting at (x, y).100 -1 func (m *symbol) set2dPattern(x int, y int, v [][]bool) {101 -1 for j, row := range v {102 -1 for i, value := range row {103 -1 m.set(x+i, y+j, value)104 -1 }105 -1 }106 -1 }107 -1108 -1 // bitmap returns the entire symbol, including the quiet zone.109 -1 func (m *symbol) bitmap() [][]bool {110 -1 module := make([][]bool, len(m.module))111 -1112 -1 for i := range m.module {113 -1 module[i] = m.module[i][:]114 -1 }115 -1116 -1 return module117 -1 }118 -1119 -1 // string returns a pictorial representation of the symbol, suitable for120 -1 // printing in a TTY.121 -1 func (m *symbol) string() string {122 -1 var result string123 -1124 -1 for _, row := range m.module {125 -1 for _, value := range row {126 -1 switch value {127 -1 case true:128 -1 result += " "129 -1 case false:130 -1 // Unicode 'FULL BLOCK' (U+2588).131 -1 result += "██"132 -1 }133 -1 }134 -1 result += "\n"135 -1 }136 -1137 -1 return result138 -1 }139 -1140 -1 // Constants used to weight penalty calculations. Specified by ISO/IEC141 -1 // 18004:2006.142 -1 const (143 -1 penaltyWeight1 = 3144 -1 penaltyWeight2 = 3145 -1 penaltyWeight3 = 40146 -1 penaltyWeight4 = 10147 -1 )148 -1149 -1 // penaltyScore returns the penalty score of the symbol. The penalty score150 -1 // consists of the sum of the four individual penalty types.151 -1 func (m *symbol) penaltyScore() int {152 -1 return m.penalty1() + m.penalty2() + m.penalty3() + m.penalty4()153 -1 }154 -1155 -1 // penalty1 returns the penalty score for "adjacent modules in row/column with156 -1 // same colour".157 -1 //158 -1 // The numbers of adjacent matching modules and scores are:159 -1 // 0-5: score = 0160 -1 // 6+ : score = penaltyWeight1 + (numAdjacentModules - 5)161 -1 func (m *symbol) penalty1() int {162 -1 penalty := 0163 -1164 -1 for x := 0; x < m.symbolSize; x++ {165 -1 lastValue := m.get(x, 0)166 -1 count := 1167 -1168 -1 for y := 1; y < m.symbolSize; y++ {169 -1 v := m.get(x, y)170 -1171 -1 if v != lastValue {172 -1 count = 1173 -1 lastValue = v174 -1 } else {175 -1 count++176 -1 if count == 6 {177 -1 penalty += penaltyWeight1 + 1178 -1 } else if count > 6 {179 -1 penalty++180 -1 }181 -1 }182 -1 }183 -1 }184 -1185 -1 for y := 0; y < m.symbolSize; y++ {186 -1 lastValue := m.get(0, y)187 -1 count := 1188 -1189 -1 for x := 1; x < m.symbolSize; x++ {190 -1 v := m.get(x, y)191 -1192 -1 if v != lastValue {193 -1 count = 1194 -1 lastValue = v195 -1 } else {196 -1 count++197 -1 if count == 6 {198 -1 penalty += penaltyWeight1 + 1199 -1 } else if count > 6 {200 -1 penalty++201 -1 }202 -1 }203 -1 }204 -1 }205 -1206 -1 return penalty207 -1 }208 -1209 -1 // penalty2 returns the penalty score for "block of modules in the same colour".210 -1 //211 -1 // m*n: score = penaltyWeight2 * (m-1) * (n-1).212 -1 func (m *symbol) penalty2() int {213 -1 penalty := 0214 -1215 -1 for y := 1; y < m.symbolSize; y++ {216 -1 for x := 1; x < m.symbolSize; x++ {217 -1 topLeft := m.get(x-1, y-1)218 -1 above := m.get(x, y-1)219 -1 left := m.get(x-1, y)220 -1 current := m.get(x, y)221 -1222 -1 if current == left && current == above && current == topLeft {223 -1 penalty++224 -1 }225 -1 }226 -1 }227 -1228 -1 return penalty * penaltyWeight2229 -1 }230 -1231 -1 // penalty3 returns the penalty score for "1:1:3:1:1 ratio232 -1 // (dark:light:dark:light:dark) pattern in row/column, preceded or followed by233 -1 // light area 4 modules wide".234 -1 //235 -1 // Existence of the pattern scores penaltyWeight3.236 -1 func (m *symbol) penalty3() int {237 -1 penalty := 0238 -1239 -1 for y := 0; y < m.symbolSize; y++ {240 -1 var bitBuffer int16 = 0x00241 -1242 -1 for x := 0; x < m.symbolSize; x++ {243 -1 bitBuffer <<= 1244 -1 if v := m.get(x, y); v {245 -1 bitBuffer |= 1246 -1 }247 -1248 -1 switch bitBuffer & 0x7ff {249 -1 // 0b000 0101 1101 or 0b10111010000250 -1 // 0x05d or 0x5d0251 -1 case 0x05d, 0x5d0:252 -1 penalty += penaltyWeight3253 -1 bitBuffer = 0xFF254 -1 default:255 -1 if x == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d {256 -1 penalty += penaltyWeight3257 -1 bitBuffer = 0xFF258 -1 }259 -1 }260 -1 }261 -1 }262 -1263 -1 for x := 0; x < m.symbolSize; x++ {264 -1 var bitBuffer int16 = 0x00265 -1266 -1 for y := 0; y < m.symbolSize; y++ {267 -1 bitBuffer <<= 1268 -1 if v := m.get(x, y); v {269 -1 bitBuffer |= 1270 -1 }271 -1272 -1 switch bitBuffer & 0x7ff {273 -1 // 0b000 0101 1101 or 0b10111010000274 -1 // 0x05d or 0x5d0275 -1 case 0x05d, 0x5d0:276 -1 penalty += penaltyWeight3277 -1 bitBuffer = 0xFF278 -1 default:279 -1 if y == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d {280 -1 penalty += penaltyWeight3281 -1 bitBuffer = 0xFF282 -1 }283 -1 }284 -1 }285 -1 }286 -1287 -1 return penalty288 -1 }289 -1290 -1 // penalty4 returns the penalty score...291 -1 func (m *symbol) penalty4() int {292 -1 numModules := m.symbolSize * m.symbolSize293 -1 numDarkModules := 0294 -1295 -1 for x := 0; x < m.symbolSize; x++ {296 -1 for y := 0; y < m.symbolSize; y++ {297 -1 if v := m.get(x, y); v {298 -1 numDarkModules++299 -1 }300 -1 }301 -1 }302 -1303 -1 numDarkModuleDeviation := numModules/2 - numDarkModules304 -1 if numDarkModuleDeviation < 0 {305 -1 numDarkModuleDeviation *= -1306 -1 }307 -1308 -1 return penaltyWeight4 * (numDarkModuleDeviation / (numModules / 20))309 -1 }
diff --git a/version.go b/version.go
@@ -1,3050 +1,421 @@1 -1 // go-qrcode2 -1 // Copyright 2014 Tom Harwood3 -14 1 package qrcode 5 26 -1 import (7 -1 "log"8 -19 -1 bitset "github.com/skip2/go-qrcode/bitset"10 -1 )11 -112 -1 // Error detection/recovery capacity.13 -1 //14 -1 // There are several levels of error detection/recovery capacity. Higher levels15 -1 // of error recovery are able to correct more errors, with the trade-off of16 -1 // increased symbol size.17 -1 type RecoveryLevel int18 -119 -1 const (20 -1 // Level L: 7% error recovery.21 -1 Low RecoveryLevel = iota22 -123 -1 // Level M: 15% error recovery. Good default choice.24 -1 Medium25 -126 -1 // Level Q: 25% error recovery.27 -1 High28 -129 -1 // Level H: 30% error recovery.30 -1 Highest31 -1 )32 -133 -1 // qrCodeVersion describes the data length and encoding order of a single QR34 -1 // Code version. There are 40 versions numbers x 4 recovery levels == 16035 -1 // possible qrCodeVersion structures.36 -1 type qrCodeVersion struct {37 -1 // Version number (1-40 inclusive).38 -1 version int39 -140 -1 // Error recovery level.41 -1 level RecoveryLevel42 -143 -1 dataEncoderType dataEncoderType44 -145 -1 // Encoded data can be split into multiple blocks. Each block contains data46 -1 // and error recovery bytes.47 -1 //48 -1 // Larger QR Codes contain more blocks.49 -1 block []block50 -151 -1 // Number of bits required to pad the combined data & error correction bit52 -1 // stream up to the symbol's full capacity.53 -1 numRemainderBits int-1 3 type group struct { -1 4 numBlocks int -1 5 numCodewords int -1 6 numDataCodewords int 54 7 } 55 856 -1 type block struct {57 -1 numBlocks int58 -159 -1 // Total codewords (numCodewords == numErrorCodewords+numDataCodewords).60 -1 numCodewords int61 -162 -1 // Number of data codewords.63 -1 numDataCodewords int-1 9 type version struct { -1 10 version int -1 11 groups []group -1 12 numRemainderBits int -1 13 alignmentPatternCenter []int -1 14 bitSequence uint32 64 15 } 65 1666 -1 var (67 -1 versions = []qrCodeVersion{68 -1 {69 -1 1,70 -1 Low,71 -1 dataEncoderType1To9,72 -1 []block{73 -1 {74 -1 1,75 -1 26,76 -1 19,77 -1 },78 -1 },79 -1 0,80 -1 },81 -1 {82 -1 1,83 -1 Medium,84 -1 dataEncoderType1To9,85 -1 []block{86 -1 {87 -1 1,88 -1 26,89 -1 16,90 -1 },91 -1 },92 -1 0,93 -1 },94 -1 {95 -1 1,96 -1 High,97 -1 dataEncoderType1To9,98 -1 []block{99 -1 {100 -1 1,101 -1 26,102 -1 13,103 -1 },104 -1 },105 -1 0,106 -1 },107 -1 {108 -1 1,109 -1 Highest,110 -1 dataEncoderType1To9,111 -1 []block{112 -1 {113 -1 1,114 -1 26,115 -1 9,116 -1 },117 -1 },118 -1 0,119 -1 },120 -1 {121 -1 2,122 -1 Low,123 -1 dataEncoderType1To9,124 -1 []block{125 -1 {126 -1 1,127 -1 44,128 -1 34,129 -1 },130 -1 },131 -1 7,132 -1 },133 -1 {134 -1 2,135 -1 Medium,136 -1 dataEncoderType1To9,137 -1 []block{138 -1 {139 -1 1,140 -1 44,141 -1 28,142 -1 },143 -1 },144 -1 7,145 -1 },146 -1 {147 -1 2,148 -1 High,149 -1 dataEncoderType1To9,150 -1 []block{151 -1 {152 -1 1,153 -1 44,154 -1 22,155 -1 },156 -1 },157 -1 7,158 -1 },159 -1 {160 -1 2,161 -1 Highest,162 -1 dataEncoderType1To9,163 -1 []block{164 -1 {165 -1 1,166 -1 44,167 -1 16,168 -1 },169 -1 },170 -1 7,171 -1 },172 -1 {173 -1 3,174 -1 Low,175 -1 dataEncoderType1To9,176 -1 []block{177 -1 {178 -1 1,179 -1 70,180 -1 55,181 -1 },182 -1 },183 -1 7,184 -1 },185 -1 {186 -1 3,187 -1 Medium,188 -1 dataEncoderType1To9,189 -1 []block{190 -1 {191 -1 1,192 -1 70,193 -1 44,194 -1 },195 -1 },196 -1 7,197 -1 },198 -1 {199 -1 3,200 -1 High,201 -1 dataEncoderType1To9,202 -1 []block{203 -1 {204 -1 2,205 -1 35,206 -1 17,207 -1 },208 -1 },209 -1 7,210 -1 },211 -1 {212 -1 3,213 -1 Highest,214 -1 dataEncoderType1To9,215 -1 []block{216 -1 {217 -1 2,218 -1 35,219 -1 13,220 -1 },221 -1 },222 -1 7,223 -1 },224 -1 {225 -1 4,226 -1 Low,227 -1 dataEncoderType1To9,228 -1 []block{229 -1 {230 -1 1,231 -1 100,232 -1 80,233 -1 },234 -1 },235 -1 7,236 -1 },237 -1 {238 -1 4,239 -1 Medium,240 -1 dataEncoderType1To9,241 -1 []block{242 -1 {243 -1 2,244 -1 50,245 -1 32,246 -1 },247 -1 },248 -1 7,249 -1 },250 -1 {251 -1 4,252 -1 High,253 -1 dataEncoderType1To9,254 -1 []block{255 -1 {256 -1 2,257 -1 50,258 -1 24,259 -1 },260 -1 },261 -1 7,262 -1 },263 -1 {264 -1 4,265 -1 Highest,266 -1 dataEncoderType1To9,267 -1 []block{268 -1 {269 -1 4,270 -1 25,271 -1 9,272 -1 },273 -1 },274 -1 7,275 -1 },276 -1 {277 -1 5,278 -1 Low,279 -1 dataEncoderType1To9,280 -1 []block{281 -1 {282 -1 1,283 -1 134,284 -1 108,285 -1 },286 -1 },287 -1 7,288 -1 },289 -1 {290 -1 5,291 -1 Medium,292 -1 dataEncoderType1To9,293 -1 []block{294 -1 {295 -1 2,296 -1 67,297 -1 43,298 -1 },299 -1 },300 -1 7,301 -1 },302 -1 {303 -1 5,304 -1 High,305 -1 dataEncoderType1To9,306 -1 []block{307 -1 {308 -1 2,309 -1 33,310 -1 15,311 -1 },312 -1 {313 -1 2,314 -1 34,315 -1 16,316 -1 },317 -1 },318 -1 7,319 -1 },320 -1 {321 -1 5,322 -1 Highest,323 -1 dataEncoderType1To9,324 -1 []block{325 -1 {326 -1 2,327 -1 33,328 -1 11,329 -1 },330 -1 {331 -1 2,332 -1 34,333 -1 12,334 -1 },335 -1 },336 -1 7,337 -1 },338 -1 {339 -1 6,340 -1 Low,341 -1 dataEncoderType1To9,342 -1 []block{343 -1 {344 -1 2,345 -1 86,346 -1 68,347 -1 },348 -1 },349 -1 7,350 -1 },351 -1 {352 -1 6,353 -1 Medium,354 -1 dataEncoderType1To9,355 -1 []block{356 -1 {357 -1 4,358 -1 43,359 -1 27,360 -1 },361 -1 },362 -1 7,363 -1 },364 -1 {365 -1 6,366 -1 High,367 -1 dataEncoderType1To9,368 -1 []block{369 -1 {370 -1 4,371 -1 43,372 -1 19,373 -1 },374 -1 },375 -1 7,376 -1 },377 -1 {378 -1 6,379 -1 Highest,380 -1 dataEncoderType1To9,381 -1 []block{382 -1 {383 -1 4,384 -1 43,385 -1 15,386 -1 },387 -1 },388 -1 7,389 -1 },390 -1 {391 -1 7,392 -1 Low,393 -1 dataEncoderType1To9,394 -1 []block{395 -1 {396 -1 2,397 -1 98,398 -1 78,399 -1 },400 -1 },401 -1 0,402 -1 },403 -1 {404 -1 7,405 -1 Medium,406 -1 dataEncoderType1To9,407 -1 []block{408 -1 {409 -1 4,410 -1 49,411 -1 31,412 -1 },413 -1 },414 -1 0,415 -1 },416 -1 {417 -1 7,418 -1 High,419 -1 dataEncoderType1To9,420 -1 []block{421 -1 {422 -1 2,423 -1 32,424 -1 14,425 -1 },426 -1 {427 -1 4,428 -1 33,429 -1 15,430 -1 },431 -1 },432 -1 0,433 -1 },434 -1 {435 -1 7,436 -1 Highest,437 -1 dataEncoderType1To9,438 -1 []block{439 -1 {440 -1 4,441 -1 39,442 -1 13,443 -1 },444 -1 {445 -1 1,446 -1 40,447 -1 14,448 -1 },449 -1 },450 -1 0,451 -1 },452 -1 {453 -1 8,454 -1 Low,455 -1 dataEncoderType1To9,456 -1 []block{457 -1 {458 -1 2,459 -1 121,460 -1 97,461 -1 },462 -1 },463 -1 0,464 -1 },465 -1 {466 -1 8,467 -1 Medium,468 -1 dataEncoderType1To9,469 -1 []block{470 -1 {471 -1 2,472 -1 60,473 -1 38,474 -1 },475 -1 {476 -1 2,477 -1 61,478 -1 39,479 -1 },480 -1 },481 -1 0,482 -1 },483 -1 {484 -1 8,485 -1 High,486 -1 dataEncoderType1To9,487 -1 []block{488 -1 {489 -1 4,490 -1 40,491 -1 18,492 -1 },493 -1 {494 -1 2,495 -1 41,496 -1 19,497 -1 },498 -1 },499 -1 0,500 -1 },501 -1 {502 -1 8,503 -1 Highest,504 -1 dataEncoderType1To9,505 -1 []block{506 -1 {507 -1 4,508 -1 40,509 -1 14,510 -1 },511 -1 {512 -1 2,513 -1 41,514 -1 15,515 -1 },516 -1 },517 -1 0,518 -1 },519 -1 {520 -1 9,521 -1 Low,522 -1 dataEncoderType1To9,523 -1 []block{524 -1 {525 -1 2,526 -1 146,527 -1 116,528 -1 },529 -1 },530 -1 0,531 -1 },532 -1 {533 -1 9,534 -1 Medium,535 -1 dataEncoderType1To9,536 -1 []block{537 -1 {538 -1 3,539 -1 58,540 -1 36,541 -1 },542 -1 {543 -1 2,544 -1 59,545 -1 37,546 -1 },547 -1 },548 -1 0,549 -1 },550 -1 {551 -1 9,552 -1 High,553 -1 dataEncoderType1To9,554 -1 []block{555 -1 {556 -1 4,557 -1 36,558 -1 16,559 -1 },560 -1 {561 -1 4,562 -1 37,563 -1 17,564 -1 },565 -1 },566 -1 0,567 -1 },568 -1 {569 -1 9,570 -1 Highest,571 -1 dataEncoderType1To9,572 -1 []block{573 -1 {574 -1 4,575 -1 36,576 -1 12,577 -1 },578 -1 {579 -1 4,580 -1 37,581 -1 13,582 -1 },583 -1 },584 -1 0,585 -1 },586 -1 {587 -1 10,588 -1 Low,589 -1 dataEncoderType10To26,590 -1 []block{591 -1 {592 -1 2,593 -1 86,594 -1 68,595 -1 },596 -1 {597 -1 2,598 -1 87,599 -1 69,600 -1 },601 -1 },602 -1 0,603 -1 },604 -1 {605 -1 10,606 -1 Medium,607 -1 dataEncoderType10To26,608 -1 []block{609 -1 {610 -1 4,611 -1 69,612 -1 43,613 -1 },614 -1 {615 -1 1,616 -1 70,617 -1 44,618 -1 },619 -1 },620 -1 0,621 -1 },622 -1 {623 -1 10,624 -1 High,625 -1 dataEncoderType10To26,626 -1 []block{627 -1 {628 -1 6,629 -1 43,630 -1 19,631 -1 },632 -1 {633 -1 2,634 -1 44,635 -1 20,636 -1 },637 -1 },638 -1 0,639 -1 },640 -1 {641 -1 10,642 -1 Highest,643 -1 dataEncoderType10To26,644 -1 []block{645 -1 {646 -1 6,647 -1 43,648 -1 15,649 -1 },650 -1 {651 -1 2,652 -1 44,653 -1 16,654 -1 },655 -1 },656 -1 0,657 -1 },658 -1 {659 -1 11,660 -1 Low,661 -1 dataEncoderType10To26,662 -1 []block{663 -1 {664 -1 4,665 -1 101,666 -1 81,667 -1 },668 -1 },669 -1 0,670 -1 },671 -1 {672 -1 11,673 -1 Medium,674 -1 dataEncoderType10To26,675 -1 []block{676 -1 {677 -1 1,678 -1 80,679 -1 50,680 -1 },681 -1 {682 -1 4,683 -1 81,684 -1 51,685 -1 },686 -1 },687 -1 0,688 -1 },689 -1 {690 -1 11,691 -1 High,692 -1 dataEncoderType10To26,693 -1 []block{694 -1 {695 -1 4,696 -1 50,697 -1 22,698 -1 },699 -1 {700 -1 4,701 -1 51,702 -1 23,703 -1 },704 -1 },705 -1 0,706 -1 },707 -1 {708 -1 11,709 -1 Highest,710 -1 dataEncoderType10To26,711 -1 []block{712 -1 {713 -1 3,714 -1 36,715 -1 12,716 -1 },717 -1 {718 -1 8,719 -1 37,720 -1 13,721 -1 },722 -1 },723 -1 0,724 -1 },725 -1 {726 -1 12,727 -1 Low,728 -1 dataEncoderType10To26,729 -1 []block{730 -1 {731 -1 2,732 -1 116,733 -1 92,734 -1 },735 -1 {736 -1 2,737 -1 117,738 -1 93,739 -1 },740 -1 },741 -1 0,742 -1 },743 -1 {744 -1 12,745 -1 Medium,746 -1 dataEncoderType10To26,747 -1 []block{748 -1 {749 -1 6,750 -1 58,751 -1 36,752 -1 },753 -1 {754 -1 2,755 -1 59,756 -1 37,757 -1 },758 -1 },759 -1 0,760 -1 },761 -1 {762 -1 12,763 -1 High,764 -1 dataEncoderType10To26,765 -1 []block{766 -1 {767 -1 4,768 -1 46,769 -1 20,770 -1 },771 -1 {772 -1 6,773 -1 47,774 -1 21,775 -1 },776 -1 },777 -1 0,778 -1 },779 -1 {780 -1 12,781 -1 Highest,782 -1 dataEncoderType10To26,783 -1 []block{784 -1 {785 -1 7,786 -1 42,787 -1 14,788 -1 },789 -1 {790 -1 4,791 -1 43,792 -1 15,793 -1 },794 -1 },795 -1 0,796 -1 },797 -1 {798 -1 13,799 -1 Low,800 -1 dataEncoderType10To26,801 -1 []block{802 -1 {803 -1 4,804 -1 133,805 -1 107,806 -1 },807 -1 },808 -1 0,809 -1 },810 -1 {811 -1 13,812 -1 Medium,813 -1 dataEncoderType10To26,814 -1 []block{815 -1 {816 -1 8,817 -1 59,818 -1 37,819 -1 },820 -1 {821 -1 1,822 -1 60,823 -1 38,824 -1 },825 -1 },826 -1 0,827 -1 },828 -1 {829 -1 13,830 -1 High,831 -1 dataEncoderType10To26,832 -1 []block{833 -1 {834 -1 8,835 -1 44,836 -1 20,837 -1 },838 -1 {839 -1 4,840 -1 45,841 -1 21,842 -1 },843 -1 },844 -1 0,845 -1 },846 -1 {847 -1 13,848 -1 Highest,849 -1 dataEncoderType10To26,850 -1 []block{851 -1 {852 -1 12,853 -1 33,854 -1 11,855 -1 },856 -1 {857 -1 4,858 -1 34,859 -1 12,860 -1 },861 -1 },862 -1 0,863 -1 },864 -1 {865 -1 14,866 -1 Low,867 -1 dataEncoderType10To26,868 -1 []block{869 -1 {870 -1 3,871 -1 145,872 -1 115,873 -1 },874 -1 {875 -1 1,876 -1 146,877 -1 116,878 -1 },879 -1 },880 -1 3,881 -1 },882 -1 {883 -1 14,884 -1 Medium,885 -1 dataEncoderType10To26,886 -1 []block{887 -1 {888 -1 4,889 -1 64,890 -1 40,891 -1 },892 -1 {893 -1 5,894 -1 65,895 -1 41,896 -1 },897 -1 },898 -1 3,899 -1 },900 -1 {901 -1 14,902 -1 High,903 -1 dataEncoderType10To26,904 -1 []block{905 -1 {906 -1 11,907 -1 36,908 -1 16,909 -1 },910 -1 {911 -1 5,912 -1 37,913 -1 17,914 -1 },915 -1 },916 -1 3,917 -1 },918 -1 {919 -1 14,920 -1 Highest,921 -1 dataEncoderType10To26,922 -1 []block{923 -1 {924 -1 11,925 -1 36,926 -1 12,927 -1 },928 -1 {929 -1 5,930 -1 37,931 -1 13,932 -1 },933 -1 },934 -1 3,935 -1 },936 -1 {937 -1 15,938 -1 Low,939 -1 dataEncoderType10To26,940 -1 []block{941 -1 {942 -1 5,943 -1 109,944 -1 87,945 -1 },946 -1 {947 -1 1,948 -1 110,949 -1 88,950 -1 },951 -1 },952 -1 3,953 -1 },954 -1 {955 -1 15,956 -1 Medium,957 -1 dataEncoderType10To26,958 -1 []block{959 -1 {960 -1 5,961 -1 65,962 -1 41,963 -1 },964 -1 {965 -1 5,966 -1 66,967 -1 42,968 -1 },969 -1 },970 -1 3,971 -1 },972 -1 {973 -1 15,974 -1 High,975 -1 dataEncoderType10To26,976 -1 []block{977 -1 {978 -1 5,979 -1 54,980 -1 24,981 -1 },982 -1 {983 -1 7,984 -1 55,985 -1 25,986 -1 },987 -1 },988 -1 3,989 -1 },990 -1 {991 -1 15,992 -1 Highest,993 -1 dataEncoderType10To26,994 -1 []block{995 -1 {996 -1 11,997 -1 36,998 -1 12,999 -1 },1000 -1 {1001 -1 7,1002 -1 37,1003 -1 13,1004 -1 },1005 -1 },1006 -1 3,1007 -1 },1008 -1 {1009 -1 16,1010 -1 Low,1011 -1 dataEncoderType10To26,1012 -1 []block{1013 -1 {1014 -1 5,1015 -1 122,1016 -1 98,1017 -1 },1018 -1 {1019 -1 1,1020 -1 123,1021 -1 99,1022 -1 },1023 -1 },1024 -1 3,1025 -1 },1026 -1 {1027 -1 16,1028 -1 Medium,1029 -1 dataEncoderType10To26,1030 -1 []block{1031 -1 {1032 -1 7,1033 -1 73,1034 -1 45,1035 -1 },1036 -1 {1037 -1 3,1038 -1 74,1039 -1 46,1040 -1 },1041 -1 },1042 -1 3,1043 -1 },1044 -1 {1045 -1 16,1046 -1 High,1047 -1 dataEncoderType10To26,1048 -1 []block{1049 -1 {1050 -1 15,1051 -1 43,1052 -1 19,1053 -1 },1054 -1 {1055 -1 2,1056 -1 44,1057 -1 20,1058 -1 },1059 -1 },1060 -1 3,1061 -1 },1062 -1 {1063 -1 16,1064 -1 Highest,1065 -1 dataEncoderType10To26,1066 -1 []block{1067 -1 {1068 -1 3,1069 -1 45,1070 -1 15,1071 -1 },1072 -1 {1073 -1 13,1074 -1 46,1075 -1 16,1076 -1 },1077 -1 },1078 -1 3,1079 -1 },1080 -1 {1081 -1 17,1082 -1 Low,1083 -1 dataEncoderType10To26,1084 -1 []block{1085 -1 {1086 -1 1,1087 -1 135,1088 -1 107,1089 -1 },1090 -1 {1091 -1 5,1092 -1 136,1093 -1 108,1094 -1 },1095 -1 },1096 -1 3,1097 -1 },1098 -1 {1099 -1 17,1100 -1 Medium,1101 -1 dataEncoderType10To26,1102 -1 []block{1103 -1 {1104 -1 10,1105 -1 74,1106 -1 46,1107 -1 },1108 -1 {1109 -1 1,1110 -1 75,1111 -1 47,1112 -1 },1113 -1 },1114 -1 3,1115 -1 },1116 -1 {1117 -1 17,1118 -1 High,1119 -1 dataEncoderType10To26,1120 -1 []block{1121 -1 {1122 -1 1,1123 -1 50,1124 -1 22,1125 -1 },1126 -1 {1127 -1 15,1128 -1 51,1129 -1 23,1130 -1 },1131 -1 },1132 -1 3,1133 -1 },1134 -1 {1135 -1 17,1136 -1 Highest,1137 -1 dataEncoderType10To26,1138 -1 []block{1139 -1 {1140 -1 2,1141 -1 42,1142 -1 14,1143 -1 },1144 -1 {1145 -1 17,1146 -1 43,1147 -1 15,1148 -1 },1149 -1 },1150 -1 3,1151 -1 },1152 -1 {1153 -1 18,1154 -1 Low,1155 -1 dataEncoderType10To26,1156 -1 []block{1157 -1 {1158 -1 5,1159 -1 150,1160 -1 120,1161 -1 },1162 -1 {1163 -1 1,1164 -1 151,1165 -1 121,1166 -1 },1167 -1 },1168 -1 3,1169 -1 },1170 -1 {1171 -1 18,1172 -1 Medium,1173 -1 dataEncoderType10To26,1174 -1 []block{1175 -1 {1176 -1 9,1177 -1 69,1178 -1 43,1179 -1 },1180 -1 {1181 -1 4,1182 -1 70,1183 -1 44,1184 -1 },1185 -1 },1186 -1 3,1187 -1 },1188 -1 {1189 -1 18,1190 -1 High,1191 -1 dataEncoderType10To26,1192 -1 []block{1193 -1 {1194 -1 17,1195 -1 50,1196 -1 22,1197 -1 },1198 -1 {1199 -1 1,1200 -1 51,1201 -1 23,1202 -1 },1203 -1 },1204 -1 3,1205 -1 },1206 -1 {1207 -1 18,1208 -1 Highest,1209 -1 dataEncoderType10To26,1210 -1 []block{1211 -1 {1212 -1 2,1213 -1 42,1214 -1 14,1215 -1 },1216 -1 {1217 -1 19,1218 -1 43,1219 -1 15,1220 -1 },1221 -1 },1222 -1 3,1223 -1 },1224 -1 {1225 -1 19,1226 -1 Low,1227 -1 dataEncoderType10To26,1228 -1 []block{1229 -1 {1230 -1 3,1231 -1 141,1232 -1 113,1233 -1 },1234 -1 {1235 -1 4,1236 -1 142,1237 -1 114,1238 -1 },1239 -1 },1240 -1 3,1241 -1 },1242 -1 {1243 -1 19,1244 -1 Medium,1245 -1 dataEncoderType10To26,1246 -1 []block{1247 -1 {1248 -1 3,1249 -1 70,1250 -1 44,1251 -1 },1252 -1 {1253 -1 11,1254 -1 71,1255 -1 45,1256 -1 },1257 -1 },1258 -1 3,1259 -1 },1260 -1 {1261 -1 19,1262 -1 High,1263 -1 dataEncoderType10To26,1264 -1 []block{1265 -1 {1266 -1 17,1267 -1 47,1268 -1 21,1269 -1 },1270 -1 {1271 -1 4,1272 -1 48,1273 -1 22,1274 -1 },1275 -1 },1276 -1 3,1277 -1 },1278 -1 {1279 -1 19,1280 -1 Highest,1281 -1 dataEncoderType10To26,1282 -1 []block{1283 -1 {1284 -1 9,1285 -1 39,1286 -1 13,1287 -1 },1288 -1 {1289 -1 16,1290 -1 40,1291 -1 14,1292 -1 },1293 -1 },1294 -1 3,1295 -1 },1296 -1 {1297 -1 20,1298 -1 Low,1299 -1 dataEncoderType10To26,1300 -1 []block{1301 -1 {1302 -1 3,1303 -1 135,1304 -1 107,1305 -1 },1306 -1 {1307 -1 5,1308 -1 136,1309 -1 108,1310 -1 },1311 -1 },1312 -1 3,1313 -1 },1314 -1 {1315 -1 20,1316 -1 Medium,1317 -1 dataEncoderType10To26,1318 -1 []block{1319 -1 {1320 -1 3,1321 -1 67,1322 -1 41,1323 -1 },1324 -1 {1325 -1 13,1326 -1 68,1327 -1 42,1328 -1 },1329 -1 },1330 -1 3,1331 -1 },1332 -1 {1333 -1 20,1334 -1 High,1335 -1 dataEncoderType10To26,1336 -1 []block{1337 -1 {1338 -1 15,1339 -1 54,1340 -1 24,1341 -1 },1342 -1 {1343 -1 5,1344 -1 55,1345 -1 25,1346 -1 },1347 -1 },1348 -1 3,1349 -1 },1350 -1 {1351 -1 20,1352 -1 Highest,1353 -1 dataEncoderType10To26,1354 -1 []block{1355 -1 {1356 -1 15,1357 -1 43,1358 -1 15,1359 -1 },1360 -1 {1361 -1 10,1362 -1 44,1363 -1 16,1364 -1 },1365 -1 },1366 -1 3,1367 -1 },1368 -1 {1369 -1 21,1370 -1 Low,1371 -1 dataEncoderType10To26,1372 -1 []block{1373 -1 {1374 -1 4,1375 -1 144,1376 -1 116,1377 -1 },1378 -1 {1379 -1 4,1380 -1 145,1381 -1 117,1382 -1 },1383 -1 },1384 -1 4,1385 -1 },1386 -1 {1387 -1 21,1388 -1 Medium,1389 -1 dataEncoderType10To26,1390 -1 []block{1391 -1 {1392 -1 17,1393 -1 68,1394 -1 42,1395 -1 },1396 -1 },1397 -1 4,1398 -1 },1399 -1 {1400 -1 21,1401 -1 High,1402 -1 dataEncoderType10To26,1403 -1 []block{1404 -1 {1405 -1 17,1406 -1 50,1407 -1 22,1408 -1 },1409 -1 {1410 -1 6,1411 -1 51,1412 -1 23,1413 -1 },1414 -1 },1415 -1 4,1416 -1 },1417 -1 {1418 -1 21,1419 -1 Highest,1420 -1 dataEncoderType10To26,1421 -1 []block{1422 -1 {1423 -1 19,1424 -1 46,1425 -1 16,1426 -1 },1427 -1 {1428 -1 6,1429 -1 47,1430 -1 17,1431 -1 },1432 -1 },1433 -1 4,1434 -1 },1435 -1 {1436 -1 22,1437 -1 Low,1438 -1 dataEncoderType10To26,1439 -1 []block{1440 -1 {1441 -1 2,1442 -1 139,1443 -1 111,1444 -1 },1445 -1 {1446 -1 7,1447 -1 140,1448 -1 112,1449 -1 },1450 -1 },1451 -1 4,1452 -1 },1453 -1 {1454 -1 22,1455 -1 Medium,1456 -1 dataEncoderType10To26,1457 -1 []block{1458 -1 {1459 -1 17,1460 -1 74,1461 -1 46,1462 -1 },1463 -1 },1464 -1 4,1465 -1 },1466 -1 {1467 -1 22,1468 -1 High,1469 -1 dataEncoderType10To26,1470 -1 []block{1471 -1 {1472 -1 7,1473 -1 54,1474 -1 24,1475 -1 },1476 -1 {1477 -1 16,1478 -1 55,1479 -1 25,1480 -1 },1481 -1 },1482 -1 4,1483 -1 },1484 -1 {1485 -1 22,1486 -1 Highest,1487 -1 dataEncoderType10To26,1488 -1 []block{1489 -1 {1490 -1 34,1491 -1 37,1492 -1 13,1493 -1 },1494 -1 },1495 -1 4,1496 -1 },1497 -1 {1498 -1 23,1499 -1 Low,1500 -1 dataEncoderType10To26,1501 -1 []block{1502 -1 {1503 -1 4,1504 -1 151,1505 -1 121,1506 -1 },1507 -1 {1508 -1 5,1509 -1 152,1510 -1 122,1511 -1 },1512 -1 },1513 -1 4,1514 -1 },1515 -1 {1516 -1 23,1517 -1 Medium,1518 -1 dataEncoderType10To26,1519 -1 []block{1520 -1 {1521 -1 4,1522 -1 75,1523 -1 47,1524 -1 },1525 -1 {1526 -1 14,1527 -1 76,1528 -1 48,1529 -1 },1530 -1 },1531 -1 4,1532 -1 },1533 -1 {1534 -1 23,1535 -1 High,1536 -1 dataEncoderType10To26,1537 -1 []block{1538 -1 {1539 -1 11,1540 -1 54,1541 -1 24,1542 -1 },1543 -1 {1544 -1 14,1545 -1 55,1546 -1 25,1547 -1 },1548 -1 },1549 -1 4,1550 -1 },1551 -1 {1552 -1 23,1553 -1 Highest,1554 -1 dataEncoderType10To26,1555 -1 []block{1556 -1 {1557 -1 16,1558 -1 45,1559 -1 15,1560 -1 },1561 -1 {1562 -1 14,1563 -1 46,1564 -1 16,1565 -1 },1566 -1 },1567 -1 4,1568 -1 },1569 -1 {1570 -1 24,1571 -1 Low,1572 -1 dataEncoderType10To26,1573 -1 []block{1574 -1 {1575 -1 6,1576 -1 147,1577 -1 117,1578 -1 },1579 -1 {1580 -1 4,1581 -1 148,1582 -1 118,1583 -1 },1584 -1 },1585 -1 4,1586 -1 },1587 -1 {1588 -1 24,1589 -1 Medium,1590 -1 dataEncoderType10To26,1591 -1 []block{1592 -1 {1593 -1 6,1594 -1 73,1595 -1 45,1596 -1 },1597 -1 {1598 -1 14,1599 -1 74,1600 -1 46,1601 -1 },1602 -1 },1603 -1 4,1604 -1 },1605 -1 {1606 -1 24,1607 -1 High,1608 -1 dataEncoderType10To26,1609 -1 []block{1610 -1 {1611 -1 11,1612 -1 54,1613 -1 24,1614 -1 },1615 -1 {1616 -1 16,1617 -1 55,1618 -1 25,1619 -1 },1620 -1 },1621 -1 4,1622 -1 },1623 -1 {1624 -1 24,1625 -1 Highest,1626 -1 dataEncoderType10To26,1627 -1 []block{1628 -1 {1629 -1 30,1630 -1 46,1631 -1 16,1632 -1 },1633 -1 {1634 -1 2,1635 -1 47,1636 -1 17,1637 -1 },1638 -1 },1639 -1 4,1640 -1 },1641 -1 {1642 -1 25,1643 -1 Low,1644 -1 dataEncoderType10To26,1645 -1 []block{1646 -1 {1647 -1 8,1648 -1 132,1649 -1 106,1650 -1 },1651 -1 {1652 -1 4,1653 -1 133,1654 -1 107,1655 -1 },1656 -1 },1657 -1 4,1658 -1 },1659 -1 {1660 -1 25,1661 -1 Medium,1662 -1 dataEncoderType10To26,1663 -1 []block{1664 -1 {1665 -1 8,1666 -1 75,1667 -1 47,1668 -1 },1669 -1 {1670 -1 13,1671 -1 76,1672 -1 48,1673 -1 },1674 -1 },1675 -1 4,1676 -1 },1677 -1 {1678 -1 25,1679 -1 High,1680 -1 dataEncoderType10To26,1681 -1 []block{1682 -1 {1683 -1 7,1684 -1 54,1685 -1 24,1686 -1 },1687 -1 {1688 -1 22,1689 -1 55,1690 -1 25,1691 -1 },1692 -1 },1693 -1 4,1694 -1 },1695 -1 {1696 -1 25,1697 -1 Highest,1698 -1 dataEncoderType10To26,1699 -1 []block{1700 -1 {1701 -1 22,1702 -1 45,1703 -1 15,1704 -1 },1705 -1 {1706 -1 13,1707 -1 46,1708 -1 16,1709 -1 },1710 -1 },1711 -1 4,1712 -1 },1713 -1 {1714 -1 26,1715 -1 Low,1716 -1 dataEncoderType10To26,1717 -1 []block{1718 -1 {1719 -1 10,1720 -1 142,1721 -1 114,1722 -1 },1723 -1 {1724 -1 2,1725 -1 143,1726 -1 115,1727 -1 },1728 -1 },1729 -1 4,1730 -1 },1731 -1 {1732 -1 26,1733 -1 Medium,1734 -1 dataEncoderType10To26,1735 -1 []block{1736 -1 {1737 -1 19,1738 -1 74,1739 -1 46,1740 -1 },1741 -1 {1742 -1 4,1743 -1 75,1744 -1 47,1745 -1 },1746 -1 },1747 -1 4,1748 -1 },1749 -1 {1750 -1 26,1751 -1 High,1752 -1 dataEncoderType10To26,1753 -1 []block{1754 -1 {1755 -1 28,1756 -1 50,1757 -1 22,1758 -1 },1759 -1 {1760 -1 6,1761 -1 51,1762 -1 23,1763 -1 },1764 -1 },1765 -1 4,1766 -1 },1767 -1 {1768 -1 26,1769 -1 Highest,1770 -1 dataEncoderType10To26,1771 -1 []block{1772 -1 {1773 -1 33,1774 -1 46,1775 -1 16,1776 -1 },1777 -1 {1778 -1 4,1779 -1 47,1780 -1 17,1781 -1 },1782 -1 },1783 -1 4,1784 -1 },1785 -1 {1786 -1 27,1787 -1 Low,1788 -1 dataEncoderType27To40,1789 -1 []block{1790 -1 {1791 -1 8,1792 -1 152,1793 -1 122,1794 -1 },1795 -1 {1796 -1 4,1797 -1 153,1798 -1 123,1799 -1 },1800 -1 },1801 -1 4,1802 -1 },1803 -1 {1804 -1 27,1805 -1 Medium,1806 -1 dataEncoderType27To40,1807 -1 []block{1808 -1 {1809 -1 22,1810 -1 73,1811 -1 45,1812 -1 },1813 -1 {1814 -1 3,1815 -1 74,1816 -1 46,1817 -1 },1818 -1 },1819 -1 4,1820 -1 },1821 -1 {1822 -1 27,1823 -1 High,1824 -1 dataEncoderType27To40,1825 -1 []block{1826 -1 {1827 -1 8,1828 -1 53,1829 -1 23,1830 -1 },1831 -1 {1832 -1 26,1833 -1 54,1834 -1 24,1835 -1 },1836 -1 },1837 -1 4,1838 -1 },1839 -1 {1840 -1 27,1841 -1 Highest,1842 -1 dataEncoderType27To40,1843 -1 []block{1844 -1 {1845 -1 12,1846 -1 45,1847 -1 15,1848 -1 },1849 -1 {1850 -1 28,1851 -1 46,1852 -1 16,1853 -1 },1854 -1 },1855 -1 4,1856 -1 },1857 -1 {1858 -1 28,1859 -1 Low,1860 -1 dataEncoderType27To40,1861 -1 []block{1862 -1 {1863 -1 3,1864 -1 147,1865 -1 117,1866 -1 },1867 -1 {1868 -1 10,1869 -1 148,1870 -1 118,1871 -1 },1872 -1 },1873 -1 3,1874 -1 },1875 -1 {1876 -1 28,1877 -1 Medium,1878 -1 dataEncoderType27To40,1879 -1 []block{1880 -1 {1881 -1 3,1882 -1 73,1883 -1 45,1884 -1 },1885 -1 {1886 -1 23,1887 -1 74,1888 -1 46,1889 -1 },1890 -1 },1891 -1 3,1892 -1 },1893 -1 {1894 -1 28,1895 -1 High,1896 -1 dataEncoderType27To40,1897 -1 []block{1898 -1 {1899 -1 4,1900 -1 54,1901 -1 24,1902 -1 },1903 -1 {1904 -1 31,1905 -1 55,1906 -1 25,1907 -1 },1908 -1 },1909 -1 3,1910 -1 },1911 -1 {1912 -1 28,1913 -1 Highest,1914 -1 dataEncoderType27To40,1915 -1 []block{1916 -1 {1917 -1 11,1918 -1 45,1919 -1 15,1920 -1 },1921 -1 {1922 -1 31,1923 -1 46,1924 -1 16,1925 -1 },1926 -1 },1927 -1 3,1928 -1 },1929 -1 {1930 -1 29,1931 -1 Low,1932 -1 dataEncoderType27To40,1933 -1 []block{1934 -1 {1935 -1 7,1936 -1 146,1937 -1 116,1938 -1 },1939 -1 {1940 -1 7,1941 -1 147,1942 -1 117,1943 -1 },1944 -1 },1945 -1 3,1946 -1 },1947 -1 {1948 -1 29,1949 -1 Medium,1950 -1 dataEncoderType27To40,1951 -1 []block{1952 -1 {1953 -1 21,1954 -1 73,1955 -1 45,1956 -1 },1957 -1 {1958 -1 7,1959 -1 74,1960 -1 46,1961 -1 },1962 -1 },1963 -1 3,1964 -1 },1965 -1 {1966 -1 29,1967 -1 High,1968 -1 dataEncoderType27To40,1969 -1 []block{1970 -1 {1971 -1 1,1972 -1 53,1973 -1 23,1974 -1 },1975 -1 {1976 -1 37,1977 -1 54,1978 -1 24,1979 -1 },1980 -1 },1981 -1 3,1982 -1 },1983 -1 {1984 -1 29,1985 -1 Highest,1986 -1 dataEncoderType27To40,1987 -1 []block{1988 -1 {1989 -1 19,1990 -1 45,1991 -1 15,1992 -1 },1993 -1 {1994 -1 26,1995 -1 46,1996 -1 16,1997 -1 },1998 -1 },1999 -1 3,2000 -1 },2001 -1 {2002 -1 30,2003 -1 Low,2004 -1 dataEncoderType27To40,2005 -1 []block{2006 -1 {2007 -1 5,2008 -1 145,2009 -1 115,2010 -1 },2011 -1 {2012 -1 10,2013 -1 146,2014 -1 116,2015 -1 },2016 -1 },2017 -1 3,2018 -1 },2019 -1 {2020 -1 30,2021 -1 Medium,2022 -1 dataEncoderType27To40,2023 -1 []block{2024 -1 {2025 -1 19,2026 -1 75,2027 -1 47,2028 -1 },2029 -1 {2030 -1 10,2031 -1 76,2032 -1 48,2033 -1 },2034 -1 },2035 -1 3,2036 -1 },2037 -1 {2038 -1 30,2039 -1 High,2040 -1 dataEncoderType27To40,2041 -1 []block{2042 -1 {2043 -1 15,2044 -1 54,2045 -1 24,2046 -1 },2047 -1 {2048 -1 25,2049 -1 55,2050 -1 25,2051 -1 },2052 -1 },2053 -1 3,2054 -1 },2055 -1 {2056 -1 30,2057 -1 Highest,2058 -1 dataEncoderType27To40,2059 -1 []block{2060 -1 {2061 -1 23,2062 -1 45,2063 -1 15,2064 -1 },2065 -1 {2066 -1 25,2067 -1 46,2068 -1 16,2069 -1 },2070 -1 },2071 -1 3,2072 -1 },2073 -1 {2074 -1 31,2075 -1 Low,2076 -1 dataEncoderType27To40,2077 -1 []block{2078 -1 {2079 -1 13,2080 -1 145,2081 -1 115,2082 -1 },2083 -1 {2084 -1 3,2085 -1 146,2086 -1 116,2087 -1 },2088 -1 },2089 -1 3,2090 -1 },2091 -1 {2092 -1 31,2093 -1 Medium,2094 -1 dataEncoderType27To40,2095 -1 []block{2096 -1 {2097 -1 2,2098 -1 74,2099 -1 46,2100 -1 },2101 -1 {2102 -1 29,2103 -1 75,2104 -1 47,2105 -1 },2106 -1 },2107 -1 3,2108 -1 },2109 -1 {2110 -1 31,2111 -1 High,2112 -1 dataEncoderType27To40,2113 -1 []block{2114 -1 {2115 -1 42,2116 -1 54,2117 -1 24,2118 -1 },2119 -1 {2120 -1 1,2121 -1 55,2122 -1 25,2123 -1 },2124 -1 },2125 -1 3,2126 -1 },2127 -1 {2128 -1 31,2129 -1 Highest,2130 -1 dataEncoderType27To40,2131 -1 []block{2132 -1 {2133 -1 23,2134 -1 45,2135 -1 15,2136 -1 },2137 -1 {2138 -1 28,2139 -1 46,2140 -1 16,2141 -1 },2142 -1 },2143 -1 3,2144 -1 },2145 -1 {2146 -1 32,2147 -1 Low,2148 -1 dataEncoderType27To40,2149 -1 []block{2150 -1 {2151 -1 17,2152 -1 145,2153 -1 115,2154 -1 },2155 -1 },2156 -1 3,2157 -1 },2158 -1 {2159 -1 32,2160 -1 Medium,2161 -1 dataEncoderType27To40,2162 -1 []block{2163 -1 {2164 -1 10,2165 -1 74,2166 -1 46,2167 -1 },2168 -1 {2169 -1 23,2170 -1 75,2171 -1 47,2172 -1 },2173 -1 },2174 -1 3,2175 -1 },2176 -1 {2177 -1 32,2178 -1 High,2179 -1 dataEncoderType27To40,2180 -1 []block{2181 -1 {2182 -1 10,2183 -1 54,2184 -1 24,2185 -1 },2186 -1 {2187 -1 35,2188 -1 55,2189 -1 25,2190 -1 },2191 -1 },2192 -1 3,2193 -1 },2194 -1 {2195 -1 32,2196 -1 Highest,2197 -1 dataEncoderType27To40,2198 -1 []block{2199 -1 {2200 -1 19,2201 -1 45,2202 -1 15,2203 -1 },2204 -1 {2205 -1 35,2206 -1 46,2207 -1 16,2208 -1 },2209 -1 },2210 -1 3,2211 -1 },2212 -1 {2213 -1 33,2214 -1 Low,2215 -1 dataEncoderType27To40,2216 -1 []block{2217 -1 {2218 -1 17,2219 -1 145,2220 -1 115,2221 -1 },2222 -1 {2223 -1 1,2224 -1 146,2225 -1 116,2226 -1 },2227 -1 },2228 -1 3,2229 -1 },2230 -1 {2231 -1 33,2232 -1 Medium,2233 -1 dataEncoderType27To40,2234 -1 []block{2235 -1 {2236 -1 14,2237 -1 74,2238 -1 46,2239 -1 },2240 -1 {2241 -1 21,2242 -1 75,2243 -1 47,2244 -1 },2245 -1 },2246 -1 3,2247 -1 },2248 -1 {2249 -1 33,2250 -1 High,2251 -1 dataEncoderType27To40,2252 -1 []block{2253 -1 {2254 -1 29,2255 -1 54,2256 -1 24,2257 -1 },2258 -1 {2259 -1 19,2260 -1 55,2261 -1 25,2262 -1 },2263 -1 },2264 -1 3,2265 -1 },2266 -1 {2267 -1 33,2268 -1 Highest,2269 -1 dataEncoderType27To40,2270 -1 []block{2271 -1 {2272 -1 11,2273 -1 45,2274 -1 15,2275 -1 },2276 -1 {2277 -1 46,2278 -1 46,2279 -1 16,2280 -1 },2281 -1 },2282 -1 3,2283 -1 },2284 -1 {2285 -1 34,2286 -1 Low,2287 -1 dataEncoderType27To40,2288 -1 []block{2289 -1 {2290 -1 13,2291 -1 145,2292 -1 115,2293 -1 },2294 -1 {2295 -1 6,2296 -1 146,2297 -1 116,2298 -1 },2299 -1 },2300 -1 3,2301 -1 },2302 -1 {2303 -1 34,2304 -1 Medium,2305 -1 dataEncoderType27To40,2306 -1 []block{2307 -1 {2308 -1 14,2309 -1 74,2310 -1 46,2311 -1 },2312 -1 {2313 -1 23,2314 -1 75,2315 -1 47,2316 -1 },2317 -1 },2318 -1 3,2319 -1 },2320 -1 {2321 -1 34,2322 -1 High,2323 -1 dataEncoderType27To40,2324 -1 []block{2325 -1 {2326 -1 44,2327 -1 54,2328 -1 24,2329 -1 },2330 -1 {2331 -1 7,2332 -1 55,2333 -1 25,2334 -1 },2335 -1 },2336 -1 3,2337 -1 },2338 -1 {2339 -1 34,2340 -1 Highest,2341 -1 dataEncoderType27To40,2342 -1 []block{2343 -1 {2344 -1 59,2345 -1 46,2346 -1 16,2347 -1 },2348 -1 {2349 -1 1,2350 -1 47,2351 -1 17,2352 -1 },2353 -1 },2354 -1 3,2355 -1 },2356 -1 {2357 -1 35,2358 -1 Low,2359 -1 dataEncoderType27To40,2360 -1 []block{2361 -1 {2362 -1 12,2363 -1 151,2364 -1 121,2365 -1 },2366 -1 {2367 -1 7,2368 -1 152,2369 -1 122,2370 -1 },2371 -1 },2372 -1 0,2373 -1 },2374 -1 {2375 -1 35,2376 -1 Medium,2377 -1 dataEncoderType27To40,2378 -1 []block{2379 -1 {2380 -1 12,2381 -1 75,2382 -1 47,2383 -1 },2384 -1 {2385 -1 26,2386 -1 76,2387 -1 48,2388 -1 },2389 -1 },2390 -1 0,2391 -1 },2392 -1 {2393 -1 35,2394 -1 High,2395 -1 dataEncoderType27To40,2396 -1 []block{2397 -1 {2398 -1 39,2399 -1 54,2400 -1 24,2401 -1 },2402 -1 {2403 -1 14,2404 -1 55,2405 -1 25,2406 -1 },2407 -1 },2408 -1 0,2409 -1 },2410 -1 {2411 -1 35,2412 -1 Highest,2413 -1 dataEncoderType27To40,2414 -1 []block{2415 -1 {2416 -1 22,2417 -1 45,2418 -1 15,2419 -1 },2420 -1 {2421 -1 41,2422 -1 46,2423 -1 16,2424 -1 },2425 -1 },2426 -1 0,2427 -1 },2428 -1 {2429 -1 36,2430 -1 Low,2431 -1 dataEncoderType27To40,2432 -1 []block{2433 -1 {2434 -1 6,2435 -1 151,2436 -1 121,2437 -1 },2438 -1 {2439 -1 14,2440 -1 152,2441 -1 122,2442 -1 },2443 -1 },2444 -1 0,2445 -1 },2446 -1 {2447 -1 36,2448 -1 Medium,2449 -1 dataEncoderType27To40,2450 -1 []block{2451 -1 {2452 -1 6,2453 -1 75,2454 -1 47,2455 -1 },2456 -1 {2457 -1 34,2458 -1 76,2459 -1 48,2460 -1 },2461 -1 },2462 -1 0,2463 -1 },2464 -1 {2465 -1 36,2466 -1 High,2467 -1 dataEncoderType27To40,2468 -1 []block{2469 -1 {2470 -1 46,2471 -1 54,2472 -1 24,2473 -1 },2474 -1 {2475 -1 10,2476 -1 55,2477 -1 25,2478 -1 },2479 -1 },2480 -1 0,2481 -1 },2482 -1 {2483 -1 36,2484 -1 Highest,2485 -1 dataEncoderType27To40,2486 -1 []block{2487 -1 {2488 -1 2,2489 -1 45,2490 -1 15,2491 -1 },2492 -1 {2493 -1 64,2494 -1 46,2495 -1 16,2496 -1 },2497 -1 },2498 -1 0,2499 -1 },2500 -1 {2501 -1 37,2502 -1 Low,2503 -1 dataEncoderType27To40,2504 -1 []block{2505 -1 {2506 -1 17,2507 -1 152,2508 -1 122,2509 -1 },2510 -1 {2511 -1 4,2512 -1 153,2513 -1 123,2514 -1 },2515 -1 },2516 -1 0,2517 -1 },2518 -1 {2519 -1 37,2520 -1 Medium,2521 -1 dataEncoderType27To40,2522 -1 []block{2523 -1 {2524 -1 29,2525 -1 74,2526 -1 46,2527 -1 },2528 -1 {2529 -1 14,2530 -1 75,2531 -1 47,2532 -1 },2533 -1 },2534 -1 0,2535 -1 },2536 -1 {2537 -1 37,2538 -1 High,2539 -1 dataEncoderType27To40,2540 -1 []block{2541 -1 {2542 -1 49,2543 -1 54,2544 -1 24,2545 -1 },2546 -1 {2547 -1 10,2548 -1 55,2549 -1 25,2550 -1 },2551 -1 },2552 -1 0,2553 -1 },2554 -1 {2555 -1 37,2556 -1 Highest,2557 -1 dataEncoderType27To40,2558 -1 []block{2559 -1 {2560 -1 24,2561 -1 45,2562 -1 15,2563 -1 },2564 -1 {2565 -1 46,2566 -1 46,2567 -1 16,2568 -1 },2569 -1 },2570 -1 0,2571 -1 },2572 -1 {2573 -1 38,2574 -1 Low,2575 -1 dataEncoderType27To40,2576 -1 []block{2577 -1 {2578 -1 4,2579 -1 152,2580 -1 122,2581 -1 },2582 -1 {2583 -1 18,2584 -1 153,2585 -1 123,2586 -1 },2587 -1 },2588 -1 0,2589 -1 },2590 -1 {2591 -1 38,2592 -1 Medium,2593 -1 dataEncoderType27To40,2594 -1 []block{2595 -1 {2596 -1 13,2597 -1 74,2598 -1 46,2599 -1 },2600 -1 {2601 -1 32,2602 -1 75,2603 -1 47,2604 -1 },2605 -1 },2606 -1 0,2607 -1 },2608 -1 {2609 -1 38,2610 -1 High,2611 -1 dataEncoderType27To40,2612 -1 []block{2613 -1 {2614 -1 48,2615 -1 54,2616 -1 24,2617 -1 },2618 -1 {2619 -1 14,2620 -1 55,2621 -1 25,2622 -1 },2623 -1 },2624 -1 0,2625 -1 },2626 -1 {2627 -1 38,2628 -1 Highest,2629 -1 dataEncoderType27To40,2630 -1 []block{2631 -1 {2632 -1 42,2633 -1 45,2634 -1 15,2635 -1 },2636 -1 {2637 -1 32,2638 -1 46,2639 -1 16,2640 -1 },2641 -1 },2642 -1 0,2643 -1 },2644 -1 {2645 -1 39,2646 -1 Low,2647 -1 dataEncoderType27To40,2648 -1 []block{2649 -1 {2650 -1 20,2651 -1 147,2652 -1 117,2653 -1 },2654 -1 {2655 -1 4,2656 -1 148,2657 -1 118,2658 -1 },2659 -1 },2660 -1 0,2661 -1 },2662 -1 {2663 -1 39,2664 -1 Medium,2665 -1 dataEncoderType27To40,2666 -1 []block{2667 -1 {2668 -1 40,2669 -1 75,2670 -1 47,2671 -1 },2672 -1 {2673 -1 7,2674 -1 76,2675 -1 48,2676 -1 },2677 -1 },2678 -1 0,2679 -1 },2680 -1 {2681 -1 39,2682 -1 High,2683 -1 dataEncoderType27To40,2684 -1 []block{2685 -1 {2686 -1 43,2687 -1 54,2688 -1 24,2689 -1 },2690 -1 {2691 -1 22,2692 -1 55,2693 -1 25,2694 -1 },2695 -1 },2696 -1 0,2697 -1 },2698 -1 {2699 -1 39,2700 -1 Highest,2701 -1 dataEncoderType27To40,2702 -1 []block{2703 -1 {2704 -1 10,2705 -1 45,2706 -1 15,2707 -1 },2708 -1 {2709 -1 67,2710 -1 46,2711 -1 16,2712 -1 },2713 -1 },2714 -1 0,2715 -1 },2716 -1 {2717 -1 40,2718 -1 Low,2719 -1 dataEncoderType27To40,2720 -1 []block{2721 -1 {2722 -1 19,2723 -1 148,2724 -1 118,2725 -1 },2726 -1 {2727 -1 6,2728 -1 149,2729 -1 119,2730 -1 },2731 -1 },2732 -1 0,2733 -1 },2734 -1 {2735 -1 40,2736 -1 Medium,2737 -1 dataEncoderType27To40,2738 -1 []block{2739 -1 {2740 -1 18,2741 -1 75,2742 -1 47,2743 -1 },2744 -1 {2745 -1 31,2746 -1 76,2747 -1 48,2748 -1 },2749 -1 },2750 -1 0,2751 -1 },2752 -1 {2753 -1 40,2754 -1 High,2755 -1 dataEncoderType27To40,2756 -1 []block{2757 -1 {2758 -1 34,2759 -1 54,2760 -1 24,2761 -1 },2762 -1 {2763 -1 34,2764 -1 55,2765 -1 25,2766 -1 },2767 -1 },2768 -1 0,2769 -1 },2770 -1 {2771 -1 40,2772 -1 Highest,2773 -1 dataEncoderType27To40,2774 -1 []block{2775 -1 {2776 -1 20,2777 -1 45,2778 -1 15,2779 -1 },2780 -1 {2781 -1 61,2782 -1 46,2783 -1 16,2784 -1 },2785 -1 },2786 -1 0,2787 -1 },-1 17 func (v version) numDataBits() int { -1 18 numDataBits := 0 -1 19 for _, g := range v.groups { -1 20 numDataBits += 8 * g.numBlocks * g.numDataCodewords 2788 21 }2789 -1 )-1 22 return numDataBits -1 23 } 2790 242791 -1 var (2792 -1 // Each QR Code contains a 15-bit Format Information value. The 15 bits2793 -1 // consist of 5 data bits concatenated with 10 error correction bits.2794 -1 //2795 -1 // The 5 data bits consist of:2796 -1 // - 2 bits for the error correction level (L=01, M=00, G=11, H=10).2797 -1 // - 3 bits for the data mask pattern identifier.2798 -1 //2799 -1 // formatBitSequence is a mapping from the 5 data bits to the completed 15-bit2800 -1 // Format Information value.2801 -1 //2802 -1 // For example, a QR Code using error correction level L, and data mask2803 -1 // pattern identifier 001:2804 -1 //2805 -1 // 01 | 001 = 01001 = 0x92806 -1 // formatBitSequence[0x9].qrCode = 0x72f3 = 1110010111100112807 -1 formatBitSequence = []struct {2808 -1 regular uint322809 -1 micro uint322810 -1 }{2811 -1 {0x5412, 0x4445},2812 -1 {0x5125, 0x4172},2813 -1 {0x5e7c, 0x4e2b},2814 -1 {0x5b4b, 0x4b1c},2815 -1 {0x45f9, 0x55ae},2816 -1 {0x40ce, 0x5099},2817 -1 {0x4f97, 0x5fc0},2818 -1 {0x4aa0, 0x5af7},2819 -1 {0x77c4, 0x6793},2820 -1 {0x72f3, 0x62a4},2821 -1 {0x7daa, 0x6dfd},2822 -1 {0x789d, 0x68ca},2823 -1 {0x662f, 0x7678},2824 -1 {0x6318, 0x734f},2825 -1 {0x6c41, 0x7c16},2826 -1 {0x6976, 0x7921},2827 -1 {0x1689, 0x06de},2828 -1 {0x13be, 0x03e9},2829 -1 {0x1ce7, 0x0cb0},2830 -1 {0x19d0, 0x0987},2831 -1 {0x0762, 0x1735},2832 -1 {0x0255, 0x1202},2833 -1 {0x0d0c, 0x1d5b},2834 -1 {0x083b, 0x186c},2835 -1 {0x355f, 0x2508},2836 -1 {0x3068, 0x203f},2837 -1 {0x3f31, 0x2f66},2838 -1 {0x3a06, 0x2a51},2839 -1 {0x24b4, 0x34e3},2840 -1 {0x2183, 0x31d4},2841 -1 {0x2eda, 0x3e8d},2842 -1 {0x2bed, 0x3bba},2843 -1 }-1 25 func (v version) bitmapSize() int { -1 26 return 17 + v.version*4 -1 27 } 2844 282845 -1 // QR Codes version 7 and higher contain an 18-bit Version Information value,2846 -1 // consisting of a 6 data bits and 12 error correction bits.2847 -1 //2848 -1 // versionBitSequence is a mapping from QR Code version to the completed2849 -1 // 18-bit Version Information value.2850 -1 //2851 -1 // For example, a QR code of version 7:2852 -1 // versionBitSequence[0x7] = 0x07c94 = 0001111100100101002853 -1 versionBitSequence = []uint32{2854 -1 0x00000,-1 29 var versions = []version{ -1 30 { -1 31 1, -1 32 []group{ -1 33 {1, 26, 16}, -1 34 }, -1 35 0, -1 36 []int{}, 2855 37 0x00000, -1 38 }, -1 39 { -1 40 2, -1 41 []group{ -1 42 {1, 44, 28}, -1 43 }, -1 44 7, -1 45 []int{6, 18}, 2856 46 0x00000, -1 47 }, -1 48 { -1 49 3, -1 50 []group{ -1 51 {1, 70, 44}, -1 52 }, -1 53 7, -1 54 []int{6, 22}, 2857 55 0x00000, -1 56 }, -1 57 { -1 58 4, -1 59 []group{ -1 60 {2, 50, 32}, -1 61 }, -1 62 7, -1 63 []int{6, 26}, 2858 64 0x00000, -1 65 }, -1 66 { -1 67 5, -1 68 []group{ -1 69 {2, 67, 43}, -1 70 }, -1 71 7, -1 72 []int{6, 30}, 2859 73 0x00000, -1 74 }, -1 75 { -1 76 6, -1 77 []group{ -1 78 {4, 43, 27}, -1 79 }, -1 80 7, -1 81 []int{6, 34}, 2860 82 0x00000, -1 83 }, -1 84 { -1 85 7, -1 86 []group{ -1 87 {4, 49, 31}, -1 88 }, -1 89 0, -1 90 []int{6, 22, 38}, 2861 91 0x07c94, -1 92 }, -1 93 { -1 94 8, -1 95 []group{ -1 96 {2, 60, 38}, -1 97 {2, 61, 39}, -1 98 }, -1 99 0, -1 100 []int{6, 24, 42}, 2862 101 0x085bc, -1 102 }, -1 103 { -1 104 9, -1 105 []group{ -1 106 {3, 58, 36}, -1 107 {2, 59, 37}, -1 108 }, -1 109 0, -1 110 []int{6, 26, 46}, 2863 111 0x09a99, -1 112 }, -1 113 { -1 114 10, -1 115 []group{ -1 116 {4, 69, 43}, -1 117 {1, 70, 44}, -1 118 }, -1 119 0, -1 120 []int{6, 28, 50}, 2864 121 0x0a4d3, -1 122 }, -1 123 { -1 124 11, -1 125 []group{ -1 126 {1, 80, 50}, -1 127 {4, 81, 51}, -1 128 }, -1 129 0, -1 130 []int{6, 30, 54}, 2865 131 0x0bbf6, -1 132 }, -1 133 { -1 134 12, -1 135 []group{ -1 136 {6, 58, 36}, -1 137 {2, 59, 37}, -1 138 }, -1 139 0, -1 140 []int{6, 32, 58}, 2866 141 0x0c762, -1 142 }, -1 143 { -1 144 13, -1 145 []group{ -1 146 {8, 59, 37}, -1 147 {1, 60, 38}, -1 148 }, -1 149 0, -1 150 []int{6, 34, 62}, 2867 151 0x0d847, -1 152 }, -1 153 { -1 154 14, -1 155 []group{ -1 156 {4, 64, 40}, -1 157 {5, 65, 41}, -1 158 }, -1 159 3, -1 160 []int{6, 26, 46, 66}, 2868 161 0x0e60d, -1 162 }, -1 163 { -1 164 15, -1 165 []group{ -1 166 {5, 65, 41}, -1 167 {5, 66, 42}, -1 168 }, -1 169 3, -1 170 []int{6, 26, 48, 70}, 2869 171 0x0f928, -1 172 }, -1 173 { -1 174 16, -1 175 []group{ -1 176 {7, 73, 45}, -1 177 {3, 74, 46}, -1 178 }, -1 179 3, -1 180 []int{6, 26, 50, 74}, 2870 181 0x10b78, -1 182 }, -1 183 { -1 184 17, -1 185 []group{ -1 186 {10, 74, 46}, -1 187 {1, 75, 47}, -1 188 }, -1 189 3, -1 190 []int{6, 30, 54, 78}, 2871 191 0x1145d, -1 192 }, -1 193 { -1 194 18, -1 195 []group{ -1 196 {9, 69, 43}, -1 197 {4, 70, 44}, -1 198 }, -1 199 3, -1 200 []int{6, 30, 56, 82}, 2872 201 0x12a17, -1 202 }, -1 203 { -1 204 19, -1 205 []group{ -1 206 {3, 70, 44}, -1 207 {11, 71, 45}, -1 208 }, -1 209 3, -1 210 []int{6, 30, 58, 86}, 2873 211 0x13532, -1 212 }, -1 213 { -1 214 20, -1 215 []group{ -1 216 {3, 67, 41}, -1 217 {13, 68, 42}, -1 218 }, -1 219 3, -1 220 []int{6, 34, 62, 90}, 2874 221 0x149a6, -1 222 }, -1 223 { -1 224 21, -1 225 []group{ -1 226 {17, 68, 42}, -1 227 }, -1 228 4, -1 229 []int{6, 28, 50, 72, 94}, 2875 230 0x15683, -1 231 }, -1 232 { -1 233 22, -1 234 []group{ -1 235 {17, 74, 46}, -1 236 }, -1 237 4, -1 238 []int{6, 26, 50, 74, 98}, 2876 239 0x168c9, -1 240 }, -1 241 { -1 242 23, -1 243 []group{ -1 244 {4, 75, 47}, -1 245 {14, 76, 48}, -1 246 }, -1 247 4, -1 248 []int{6, 30, 54, 78, 102}, 2877 249 0x177ec, -1 250 }, -1 251 { -1 252 24, -1 253 []group{ -1 254 {6, 73, 45}, -1 255 {14, 74, 46}, -1 256 }, -1 257 4, -1 258 []int{6, 28, 54, 80, 106}, 2878 259 0x18ec4, -1 260 }, -1 261 { -1 262 25, -1 263 []group{ -1 264 {8, 75, 47}, -1 265 {13, 76, 48}, -1 266 }, -1 267 4, -1 268 []int{6, 32, 58, 84, 110}, 2879 269 0x191e1, -1 270 }, -1 271 { -1 272 26, -1 273 []group{ -1 274 {19, 74, 46}, -1 275 {4, 75, 47}, -1 276 }, -1 277 4, -1 278 []int{6, 30, 58, 86, 114}, 2880 279 0x1afab, -1 280 }, -1 281 { -1 282 27, -1 283 []group{ -1 284 {22, 73, 45}, -1 285 {3, 74, 46}, -1 286 }, -1 287 4, -1 288 []int{6, 34, 62, 90, 118}, 2881 289 0x1b08e, -1 290 }, -1 291 { -1 292 28, -1 293 []group{ -1 294 {3, 73, 45}, -1 295 {23, 74, 46}, -1 296 }, -1 297 3, -1 298 []int{6, 26, 50, 74, 98, 122}, 2882 299 0x1cc1a, -1 300 }, -1 301 { -1 302 29, -1 303 []group{ -1 304 {21, 73, 45}, -1 305 {7, 74, 46}, -1 306 }, -1 307 3, -1 308 []int{6, 30, 54, 78, 102, 126}, 2883 309 0x1d33f, -1 310 }, -1 311 { -1 312 30, -1 313 []group{ -1 314 {19, 75, 47}, -1 315 {10, 76, 48}, -1 316 }, -1 317 3, -1 318 []int{6, 26, 52, 78, 104, 130}, 2884 319 0x1ed75, -1 320 }, -1 321 { -1 322 31, -1 323 []group{ -1 324 {2, 74, 46}, -1 325 {29, 75, 47}, -1 326 }, -1 327 3, -1 328 []int{6, 30, 56, 82, 108, 134}, 2885 329 0x1f250, -1 330 }, -1 331 { -1 332 32, -1 333 []group{ -1 334 {10, 74, 46}, -1 335 {23, 75, 47}, -1 336 }, -1 337 3, -1 338 []int{6, 34, 60, 86, 112, 138}, 2886 339 0x209d5, -1 340 }, -1 341 { -1 342 33, -1 343 []group{ -1 344 {14, 74, 46}, -1 345 {21, 75, 47}, -1 346 }, -1 347 3, -1 348 []int{6, 30, 58, 86, 114, 142}, 2887 349 0x216f0, -1 350 }, -1 351 { -1 352 34, -1 353 []group{ -1 354 {14, 74, 46}, -1 355 {23, 75, 47}, -1 356 }, -1 357 3, -1 358 []int{6, 34, 62, 90, 118, 146}, 2888 359 0x228ba, -1 360 }, -1 361 { -1 362 35, -1 363 []group{ -1 364 {12, 75, 47}, -1 365 {26, 76, 48}, -1 366 }, -1 367 0, -1 368 []int{6, 30, 54, 78, 102, 126, 150}, 2889 369 0x2379f, -1 370 }, -1 371 { -1 372 36, -1 373 []group{ -1 374 {6, 75, 47}, -1 375 {34, 76, 48}, -1 376 }, -1 377 0, -1 378 []int{6, 24, 50, 76, 102, 128, 154}, 2890 379 0x24b0b, -1 380 }, -1 381 { -1 382 37, -1 383 []group{ -1 384 {29, 74, 46}, -1 385 {14, 75, 47}, -1 386 }, -1 387 0, -1 388 []int{6, 28, 54, 80, 106, 132, 158}, 2891 389 0x2542e, -1 390 }, -1 391 { -1 392 38, -1 393 []group{ -1 394 {13, 74, 46}, -1 395 {32, 75, 47}, -1 396 }, -1 397 0, -1 398 []int{6, 32, 58, 84, 110, 136, 162}, 2892 399 0x26a64, -1 400 }, -1 401 { -1 402 39, -1 403 []group{ -1 404 {40, 75, 47}, -1 405 {7, 76, 48}, -1 406 }, -1 407 0, -1 408 []int{6, 26, 54, 82, 110, 138, 166}, 2893 409 0x27541, -1 410 }, -1 411 { -1 412 40, -1 413 []group{ -1 414 {18, 75, 47}, -1 415 {31, 76, 48}, -1 416 }, -1 417 0, -1 418 []int{6, 30, 58, 86, 114, 142, 170}, 2894 419 0x28c69,2895 -1 }2896 -1 )2897 -12898 -1 const (2899 -1 formatInfoLengthBits = 152900 -1 versionInfoLengthBits = 182901 -1 )2902 -12903 -1 // formatInfo returns the 15-bit Format Information value for a QR2904 -1 // code.2905 -1 func (v qrCodeVersion) formatInfo(maskPattern int) *bitset.Bitset {2906 -1 formatID := 02907 -12908 -1 switch v.level {2909 -1 case Low:2910 -1 formatID = 0x08 // 0b010002911 -1 case Medium:2912 -1 formatID = 0x00 // 0b000002913 -1 case High:2914 -1 formatID = 0x18 // 0b110002915 -1 case Highest:2916 -1 formatID = 0x10 // 0b100002917 -1 default:2918 -1 log.Panicf("Invalid level %d", v.level)2919 -1 }2920 -12921 -1 if maskPattern < 0 || maskPattern > 7 {2922 -1 log.Panicf("Invalid maskPattern %d", maskPattern)2923 -1 }2924 -12925 -1 formatID |= maskPattern & 0x72926 -12927 -1 result := bitset.New()2928 -12929 -1 result.AppendUint32(formatBitSequence[formatID].regular, formatInfoLengthBits)2930 -12931 -1 return result2932 -1 }2933 -12934 -1 // versionInfo returns the 18-bit Version Information value for a QR Code.2935 -1 //2936 -1 // Version Information is applicable only to QR Codes versions 7-40 inclusive.2937 -1 // nil is returned if Version Information is not required.2938 -1 func (v qrCodeVersion) versionInfo() *bitset.Bitset {2939 -1 if v.version < 7 {2940 -1 return nil2941 -1 }2942 -12943 -1 result := bitset.New()2944 -1 result.AppendUint32(versionBitSequence[v.version], 18)2945 -12946 -1 return result2947 -1 }2948 -12949 -1 // numDataBits returns the data capacity in bits.2950 -1 func (v qrCodeVersion) numDataBits() int {2951 -1 numDataBits := 02952 -1 for _, b := range v.block {2953 -1 numDataBits += 8 * b.numBlocks * b.numDataCodewords // 8 bits in a byte2954 -1 }2955 -12956 -1 return numDataBits2957 -1 }2958 -12959 -1 // chooseQRCodeVersion chooses the most suitable QR Code version for a stated2960 -1 // data length in bits, the error recovery level required, and the data encoder2961 -1 // used.2962 -1 //2963 -1 // The chosen QR Code version is the smallest version able to fit numDataBits2964 -1 // and the optional terminator bits required by the specified encoder.2965 -1 //2966 -1 // On success the chosen QR Code version is returned.2967 -1 func chooseQRCodeVersion(level RecoveryLevel, encoder *dataEncoder, numDataBits int) *qrCodeVersion {2968 -1 var chosenVersion *qrCodeVersion2969 -12970 -1 for _, v := range versions {2971 -1 if v.level != level {2972 -1 continue2973 -1 } else if v.version < encoder.minVersion {2974 -1 continue2975 -1 } else if v.version > encoder.maxVersion {2976 -1 break2977 -1 }2978 -12979 -1 numFreeBits := v.numDataBits() - numDataBits2980 -12981 -1 if numFreeBits >= 0 {2982 -1 chosenVersion = &v2983 -1 break2984 -1 }2985 -1 }2986 -12987 -1 return chosenVersion2988 -1 }2989 -12990 -1 func (v qrCodeVersion) numTerminatorBitsRequired(numDataBits int) int {2991 -1 numFreeBits := v.numDataBits() - numDataBits2992 -12993 -1 var numTerminatorBits int2994 -12995 -1 switch {2996 -1 case numFreeBits >= 4:2997 -1 numTerminatorBits = 42998 -1 default:2999 -1 numTerminatorBits = numFreeBits3000 -1 }3001 -13002 -1 return numTerminatorBits3003 -1 }3004 -13005 -1 // numBlocks returns the number of blocks.3006 -1 func (v qrCodeVersion) numBlocks() int {3007 -1 numBlocks := 03008 -13009 -1 for _, b := range v.block {3010 -1 numBlocks += b.numBlocks3011 -1 }3012 -13013 -1 return numBlocks3014 -1 }3015 -13016 -1 // numBitsToPadToCodeword returns the number of bits required to pad data of3017 -1 // length numDataBits upto the nearest codeword size.3018 -1 func (v qrCodeVersion) numBitsToPadToCodeword(numDataBits int) int {3019 -1 if numDataBits == v.numDataBits() {3020 -1 return 03021 -1 }3022 -13023 -1 return (8 - numDataBits%8) % 83024 -1 }3025 -13026 -1 // symbolSize returns the size of the QR Code symbol in number of modules (which3027 -1 // is both the width and height, since QR codes are square). The QR Code has3028 -1 // size symbolSize() x symbolSize() pixels. This does not include the quiet3029 -1 // zone.3030 -1 func (v qrCodeVersion) symbolSize() int {3031 -1 return 21 + (v.version-1)*43032 -1 }3033 -13034 -1 // quietZoneSize returns the number of pixels of border space on each side of3035 -1 // the QR Code. The quiet space assists with decoding.3036 -1 func (v qrCodeVersion) quietZoneSize() int {3037 -1 return 43038 -1 }3039 -13040 -1 // getQRCodeVersion returns the QR Code version by version number and recovery3041 -1 // level. Returns nil if the requested combination is not defined.3042 -1 func getQRCodeVersion(level RecoveryLevel, version int) *qrCodeVersion {3043 -1 for _, v := range versions {3044 -1 if v.level == level && v.version == version {3045 -1 return &v3046 -1 }3047 -1 }3048 -13049 -1 return nil-1 420 }, 3050 421 }