1 package qrcode
2
3 import (
4 "bytes"
5 "errors"
6 "image"
7 "image/color"
8 "math"
9 "strconv"
10 )
11
12 var positionAdjustPatternTable = [][]int{
13 {},
14 {}, // version 1
15 {6, 18},
16 {6, 22},
17 {6, 26},
18 {6, 30}, // version 5
19 {6, 34},
20 {6, 22, 38},
21 {6, 24, 42},
22 {6, 26, 46},
23 {6, 28, 50}, // version 10
24 {6, 30, 54},
25 {6, 32, 58},
26 {6, 34, 62},
27 {6, 26, 46, 66},
28 {6, 26, 48, 70},
29 {6, 26, 50, 74},
30 {6, 30, 54, 78},
31 {6, 30, 56, 82},
32 {6, 30, 58, 86},
33 {6, 34, 62, 90}, // version 20
34 {6, 28, 50, 72, 94},
35 {6, 26, 50, 74, 98},
36 {6, 30, 54, 78, 102},
37 {6, 28, 54, 80, 106},
38 {6, 32, 58, 84, 110},
39 {6, 30, 58, 86, 114},
40 {6, 34, 62, 90, 118},
41 {6, 26, 50, 74, 98, 122},
42 {6, 30, 54, 78, 102, 126},
43 {6, 26, 52, 78, 104, 130}, // version 30
44 {6, 30, 56, 82, 108, 134},
45 {6, 34, 60, 86, 112, 138},
46 {6, 30, 58, 86, 114, 142},
47 {6, 34, 62, 90, 118, 146},
48 {6, 30, 54, 78, 102, 126, 150},
49 {6, 24, 50, 76, 102, 128, 154},
50 {6, 28, 54, 80, 106, 132, 158},
51 {6, 32, 58, 84, 110, 136, 162},
52 {6, 26, 54, 82, 110, 138, 166},
53 {6, 30, 58, 86, 114, 142, 170}} // version 40
54
55 type ECLevel int
56
57 const (
58 ECLevelL ECLevel = 1 << iota
59 ECLevelM ECLevel = 1 << iota
60 ECLevelQ ECLevel = 1 << iota
61 ECLevelH ECLevel = 1 << iota
62 )
63
64 var typeInformationTable = map[ECLevel][]int{
65 ECLevelL: {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976},
66 ECLevelM: {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0},
67 ECLevelQ: {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed},
68 ECLevelH: {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b},
69 }
70
71 var versionInformationTable = []int{
72 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
73 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
74 0x177ec, 0x18ec4, 0x191e1, 0x1Afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ef75,
75 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
76 0x27541, 0x28c69,
77 }
78
79 var errorCorrectionTable = []map[ECLevel][]int{
80 // ec code word per block
81 // block 1 count
82 // block 1 data code words
83 // block 2 count
84 // block 2 data code words
85 {},
86 {ECLevelL: {7, 1, 19, 0, 0}, ECLevelM: {10, 1, 16, 0, 0}, ECLevelQ: {13, 1, 13, 0, 0}, ECLevelH: {17, 1, 9, 0, 0}}, // version 1
87 {ECLevelL: {10, 1, 34, 0, 0}, ECLevelM: {16, 1, 28, 0, 0}, ECLevelQ: {22, 1, 22, 0, 0}, ECLevelH: {28, 1, 16, 0, 0}},
88 {ECLevelL: {15, 1, 55, 0, 0}, ECLevelM: {26, 1, 44, 0, 0}, ECLevelQ: {18, 2, 17, 0, 0}, ECLevelH: {22, 2, 13, 0, 0}},
89 {ECLevelL: {20, 1, 80, 0, 0}, ECLevelM: {18, 2, 32, 0, 0}, ECLevelQ: {26, 2, 24, 0, 0}, ECLevelH: {16, 4, 9, 0, 0}},
90 {ECLevelL: {26, 1, 108, 0, 0}, ECLevelM: {24, 2, 43, 0, 0}, ECLevelQ: {18, 2, 15, 2, 16}, ECLevelH: {22, 2, 11, 2, 12}}, // version 5
91 {ECLevelL: {18, 2, 68, 0, 0}, ECLevelM: {16, 4, 27, 0, 0}, ECLevelQ: {24, 4, 19, 0, 0}, ECLevelH: {28, 4, 15, 0, 0}},
92 {ECLevelL: {20, 2, 78, 0, 0}, ECLevelM: {18, 4, 31, 0, 0}, ECLevelQ: {18, 2, 14, 4, 15}, ECLevelH: {26, 4, 13, 1, 14}},
93 {ECLevelL: {24, 2, 97, 0, 0}, ECLevelM: {22, 2, 38, 2, 39}, ECLevelQ: {22, 4, 18, 2, 19}, ECLevelH: {26, 4, 14, 2, 15}},
94 {ECLevelL: {30, 2, 116, 0, 0}, ECLevelM: {22, 3, 36, 2, 37}, ECLevelQ: {20, 4, 16, 4, 17}, ECLevelH: {24, 4, 12, 4, 13}},
95 {ECLevelL: {18, 2, 68, 2, 69}, ECLevelM: {26, 4, 43, 1, 44}, ECLevelQ: {24, 6, 19, 2, 20}, ECLevelH: {28, 6, 15, 2, 16}}, // version 10
96 {ECLevelL: {20, 4, 81, 0, 0}, ECLevelM: {31, 1, 50, 4, 51}, ECLevelQ: {28, 4, 22, 4, 23}, ECLevelH: {24, 3, 12, 8, 13}},
97 {ECLevelL: {24, 2, 92, 2, 93}, ECLevelM: {22, 6, 36, 2, 37}, ECLevelQ: {26, 4, 20, 6, 21}, ECLevelH: {28, 7, 14, 4, 15}},
98 {ECLevelL: {26, 4, 107, 0, 0}, ECLevelM: {22, 8, 37, 1, 38}, ECLevelQ: {24, 8, 20, 4, 21}, ECLevelH: {22, 12, 11, 4, 12}},
99 {ECLevelL: {30, 3, 115, 1, 116}, ECLevelM: {24, 4, 40, 5, 41}, ECLevelQ: {20, 11, 16, 5, 17}, ECLevelH: {24, 11, 12, 5, 13}},
100 {ECLevelL: {22, 5, 87, 1, 88}, ECLevelM: {24, 5, 41, 5, 42}, ECLevelQ: {30, 5, 24, 7, 25}, ECLevelH: {30, 5, 24, 7, 25}},
101 {ECLevelL: {24, 5, 98, 1, 99}, ECLevelM: {28, 7, 45, 3, 46}, ECLevelQ: {24, 15, 19, 2, 20}, ECLevelH: {30, 3, 15, 13, 16}},
102 {ECLevelL: {28, 1, 107, 5, 108}, ECLevelM: {28, 10, 46, 1, 47}, ECLevelQ: {28, 1, 22, 15, 23}, ECLevelH: {28, 2, 14, 17, 15}},
103 {ECLevelL: {30, 5, 120, 1, 121}, ECLevelM: {26, 9, 43, 4, 44}, ECLevelQ: {28, 17, 22, 1, 23}, ECLevelH: {28, 2, 14, 19, 15}},
104 {ECLevelL: {28, 3, 113, 4, 114}, ECLevelM: {26, 3, 44, 11, 45}, ECLevelQ: {26, 17, 21, 4, 22}, ECLevelH: {26, 9, 13, 16, 14}},
105 {ECLevelL: {28, 3, 107, 6, 108}, ECLevelM: {26, 3, 41, 13, 42}, ECLevelQ: {30, 15, 24, 5, 25}, ECLevelH: {28, 15, 15, 10, 16}}, // version 20
106 {ECLevelL: {28, 4, 116, 4, 117}, ECLevelM: {26, 17, 42, 0, 0}, ECLevelQ: {28, 17, 22, 6, 23}, ECLevelH: {30, 19, 16, 6, 17}},
107 {ECLevelL: {28, 2, 111, 7, 112}, ECLevelM: {28, 17, 46, 0, 0}, ECLevelQ: {30, 7, 24, 16, 25}, ECLevelH: {24, 34, 13, 0, 0}},
108 {ECLevelL: {30, 4, 121, 5, 122}, ECLevelM: {28, 4, 47, 14, 48}, ECLevelQ: {30, 11, 24, 14, 25}, ECLevelH: {30, 16, 15, 14, 16}},
109 {ECLevelL: {30, 6, 117, 4, 118}, ECLevelM: {28, 6, 45, 14, 46}, ECLevelQ: {30, 11, 24, 16, 25}, ECLevelH: {30, 30, 16, 2, 17}},
110 {ECLevelL: {26, 8, 106, 4, 107}, ECLevelM: {28, 8, 47, 13, 48}, ECLevelQ: {230, 7, 24, 22, 25}, ECLevelH: {30, 22, 15, 13, 16}},
111 {ECLevelL: {28, 10, 114, 2, 115}, ECLevelM: {28, 19, 46, 4, 47}, ECLevelQ: {28, 28, 22, 6, 23}, ECLevelH: {30, 33, 16, 4, 17}},
112 {ECLevelL: {30, 8, 122, 4, 123}, ECLevelM: {28, 22, 45, 3, 46}, ECLevelQ: {30, 8, 23, 26, 24}, ECLevelH: {30, 12, 15, 28, 16}},
113 {ECLevelL: {30, 3, 117, 10, 118}, ECLevelM: {28, 3, 45, 23, 46}, ECLevelQ: {30, 4, 24, 31, 25}, ECLevelH: {30, 11, 15, 31, 16}},
114 {ECLevelL: {30, 7, 116, 7, 117}, ECLevelM: {28, 21, 45, 7, 46}, ECLevelQ: {30, 1, 23, 37, 24}, ECLevelH: {30, 19, 15, 26, 16}},
115 {ECLevelL: {30, 5, 115, 10, 116}, ECLevelM: {28, 19, 47, 10, 48}, ECLevelQ: {30, 15, 24, 25, 25}, ECLevelH: {30, 23, 15, 25, 16}}, // version 30
116 {ECLevelL: {30, 13, 115, 3, 116}, ECLevelM: {28, 2, 46, 29, 47}, ECLevelQ: {30, 42, 24, 1, 25}, ECLevelH: {30, 23, 15, 28, 16}},
117 {ECLevelL: {30, 17, 115, 0, 0}, ECLevelM: {28, 10, 46, 23, 47}, ECLevelQ: {30, 10, 24, 35, 25}, ECLevelH: {30, 19, 15, 35, 16}},
118 {ECLevelL: {30, 17, 115, 1, 116}, ECLevelM: {28, 14, 46, 21, 47}, ECLevelQ: {30, 29, 24, 19, 25}, ECLevelH: {30, 11, 15, 46, 16}},
119 {ECLevelL: {30, 13, 115, 6, 116}, ECLevelM: {28, 14, 46, 13, 47}, ECLevelQ: {30, 44, 24, 7, 25}, ECLevelH: {30, 59, 16, 1, 17}},
120 {ECLevelL: {30, 12, 121, 7, 122}, ECLevelM: {28, 12, 47, 26, 48}, ECLevelQ: {30, 39, 24, 14, 25}, ECLevelH: {30, 22, 15, 41, 16}},
121 {ECLevelL: {30, 6, 121, 14, 122}, ECLevelM: {28, 6, 47, 34, 48}, ECLevelQ: {30, 46, 24, 10, 25}, ECLevelH: {30, 2, 15, 64, 16}},
122 {ECLevelL: {30, 17, 122, 4, 123}, ECLevelM: {28, 29, 46, 14, 47}, ECLevelQ: {30, 49, 24, 10, 25}, ECLevelH: {30, 24, 15, 46, 16}},
123 {ECLevelL: {30, 4, 122, 18, 123}, ECLevelM: {28, 13, 46, 32, 47}, ECLevelQ: {30, 48, 24, 14, 25}, ECLevelH: {30, 42, 15, 32, 16}},
124 {ECLevelL: {30, 20, 117, 4, 118}, ECLevelM: {28, 40, 47, 7, 48}, ECLevelQ: {30, 43, 24, 22, 25}, ECLevelH: {30, 10, 15, 67, 16}},
125 {ECLevelL: {30, 19, 118, 6, 119}, ECLevelM: {28, 18, 47, 31, 48}, ECLevelQ: {30, 34, 24, 34, 25}, ECLevelH: {30, 20, 15, 61, 16}}, // version 40
126 }
127
128 // Galois field antilog to log convertion table
129 var int2exp = []int{
130 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
131 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
132 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
133 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
134 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
135 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
136 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
137 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
138 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
139 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
140 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
141 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
142 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
143 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
144 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
145 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
146 }
147
148 // Galois field log to antilog convertion table
149 var exp2int = []int{
150 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
151 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
152 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
153 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
154 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
155 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
156 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
157 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
158 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
159 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
160 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
161 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
162 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
163 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
164 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
165 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00,
166 }
167
168 var alphanumTable = map[byte]int{
169 '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
170 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19,
171 'K': 20, 'L': 21, 'M': 22, 'N': 23, 'O': 24, 'P': 25, 'Q': 26, 'R': 27, 'S': 28, 'T': 29,
172 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 'Z': 35, ' ': 36, '$': 37, '%': 38, '*': 39,
173 '+': 40, '-': 41, '.': 42, '/': 43, ':': 44,
174 }
175
176 // Errors introduced by this package
177 var (
178 errInvalidVersion = errors.New("goqr: invalid qrcode version (1-40)")
179 errInvalidLevel = errors.New("goqr: invalid qrcode error correctionlevel (ECLevelL,M,Q,H)")
180 errInvalidModuleSize = errors.New("goqr: invalid qrcode module size (>=1)")
181 errInvalidQuietZoneWidth = errors.New("goqr: invalid qrcode quiet zone width (>=0)")
182 errInvalidDataSize = errors.New("goqr: invalid data size")
183 )
184
185 type Qrcode struct {
186 Version int // qrcode version 1-40 (0:auto)
187 Level ECLevel // error correction Level (0:auto)
188 mode string //
189 module [][]int // 2-D matrix [row][col] ( +-1 : data, +-2 : pattern )
190 data string // data to encode
191 ModuleSize int // module size (default 1)
192 QuietZoneWidth int // quiet zone width
193 encodedData []byte // encoded data
194 penalty []int // calculated mask penalty (0-7)
195 }
196
197 func Encode(data string, version int, level ECLevel, moduleSize int) (image.Image, error) {
198
199 qr := new(Qrcode)
200 qr.data = data
201 qr.Version = version
202 qr.Level = level
203 qr.ModuleSize = moduleSize
204 qr.QuietZoneWidth = 4
205
206 return qr.Encode()
207 }
208
209 // Module count on a side
210 func (qr *Qrcode) len() int { return qr.Version*4 + (7+1)*2 + 1 }
211
212 func (qr *Qrcode) Encode() (image.Image, error) {
213
214 // check version
215 if qr.Version < 0 || 40 < qr.Version {
216 return nil, errInvalidVersion
217 }
218
219 // check level
220 if qr.Level != 0 && len(errorCorrectionTable[1][qr.Level]) == 0 {
221 return nil, errInvalidLevel
222 }
223
224 // check module size
225 if qr.ModuleSize < 1 {
226 return nil, errInvalidModuleSize
227 }
228
229 // check quiet zone width
230 if qr.QuietZoneWidth < 0 {
231 return nil, errInvalidQuietZoneWidth
232 }
233
234 // set encoding mode (kanji mode not supported)
235 qr.selectMode()
236
237 // set version & level
238 qr.selectVersionLevel()
239 if qr.Version == 0 || qr.Level == 0 {
240 return nil, errInvalidDataSize
241 }
242
243 // initialize qrcode
244 for i := 0; i < qr.len(); i++ {
245 s := make([]int, qr.len())
246 qr.module = append(qr.module, s)
247 }
248
249 // place pattern to qr.module
250 qr.placePatterns()
251
252 // encode data -> qr.encodedData
253 qr.encodeData()
254
255 // place encoded data to qr.module
256 qr.mapData()
257
258 // mask
259 qr.maskData()
260
261 // [][]int to [][]bool
262 module := make([][]bool, 0)
263 for _, row := range qr.module {
264 r := make([]bool, qr.len())
265 for c, cell := range row {
266 if cell > 0 {
267 r[c] = true
268 } else {
269 r[c] = false
270 }
271 }
272 module = append(module, r)
273 }
274
275 // quiet zone
276 for i := 0; i < qr.QuietZoneWidth; i++ {
277 module = append(module, make([]bool, qr.len()))
278 module = append([][]bool{make([]bool, qr.len())}, module...)
279 }
280 for i, row := range module {
281 row = append(make([]bool, qr.QuietZoneWidth), row...)
282 row = append(row, make([]bool, qr.QuietZoneWidth)...)
283 module[i] = row
284 }
285
286 // module size
287 if qr.ModuleSize > 1 {
288 l := len(module) * qr.ModuleSize
289 m := make([][]bool, l)
290
291 for i := 0; i < l; i++ {
292 m[i] = make([]bool, l)
293 }
294
295 for r, row := range module {
296 for c, cell := range row {
297 if !cell {
298 continue
299 }
300 for x := 0; x < qr.ModuleSize; x++ {
301 for y := 0; y < qr.ModuleSize; y++ {
302 m[r*qr.ModuleSize+x][c*qr.ModuleSize+y] = true
303 }
304 }
305 }
306 }
307 module = m
308 }
309
310 rgba := image.NewRGBA(image.Rect(0, 0, len(module), len(module)))
311
312 for r, row := range module {
313 for c, cell := range row {
314 if cell {
315 rgba.SetRGBA(c, r, color.RGBA{A: 255, R: 0, G: 0, B: 0})
316 } else {
317 rgba.SetRGBA(c, r, color.RGBA{})
318 }
319 }
320 }
321
322 return rgba, nil
323 }
324
325 // qrcode version information table
326 func (qr *Qrcode) table() []int { return errorCorrectionTable[qr.Version][qr.Level] }
327 func (qr *Qrcode) ecCodeWords() int { return qr.table()[0] }
328 func (qr *Qrcode) dataCodeWords() []int { return []int{qr.table()[2], qr.table()[4]} }
329 func (qr *Qrcode) blkCount() []int { return []int{qr.table()[1], qr.table()[3]} }
330
331 // total code words
332 func (qr *Qrcode) totalCodeWords() int {
333 table := qr.table()
334 return (table[0]+table[2])*table[1] + (table[0]+table[4])*table[3]
335 }
336
337 // total data code words
338 func (qr *Qrcode) totalDataCodeWords() int {
339 table := qr.table()
340 return table[1]*table[2] + table[3]*table[4]
341 }
342
343 // total data code bits
344 func (qr *Qrcode) totalDataCodeBits() int {
345 return qr.totalDataCodeWords() * 8
346 }
347
348 func (qr *Qrcode) selectMode() {
349 qr.mode = "numeric"
350 for _, c := range qr.data {
351 if c >= '0' && c <= '9' {
352 continue
353 }
354 if alphanumTable[byte(c)] != 0 {
355 qr.mode = "alphanum"
356 continue
357 }
358 qr.mode = "8bitbyte"
359 return
360 }
361 }
362
363 func (qr *Qrcode) selectVersionLevel() {
364 firstVer, lastVer := 1, 40
365 errorCorrectionLevel := []ECLevel{ECLevelH, ECLevelQ, ECLevelM, ECLevelL}
366
367 if qr.Version > 0 {
368 firstVer, lastVer = qr.Version, qr.Version
369 }
370
371 if qr.Level > 0 {
372 errorCorrectionLevel = []ECLevel{qr.Level}
373 }
374
375 for i := firstVer; i <= lastVer; i++ {
376 for _, j := range errorCorrectionLevel {
377 if maxDataSize(i, j, qr.mode) >= len(qr.data) {
378 qr.Version, qr.Level = i, j
379 return
380 }
381 }
382 }
383 qr.Version, qr.Level = 0, 0
384 }
385
386 func (qr *Qrcode) setTypeBits(mask int) {
387 qr.module = setTypeBits(qr.module, qr.Level, mask)
388 }
389
390 func (qr *Qrcode) placePatterns() {
391
392 isBlank := func(r, c int) bool { return qr.module[r][c] == 0 }
393
394 // finder pattern
395 for _, p := range [3][2]int{{0, 0}, {qr.len() - 7, 0}, {0, qr.len() - 7}} {
396 for r := -1; r <= 7; r++ {
397 if p[0]+r < 0 || qr.len() <= p[0]+r {
398 continue
399 }
400 for c := -1; c <= 7; c++ {
401 if p[1]+c < 0 || qr.len() <= p[1]+c {
402 continue
403 }
404 if (0 <= r && r < 7 && (c == 0 || c == 6)) ||
405 (0 <= c && c < 7 && (r == 0 || r == 6)) ||
406 (2 <= r && r < 5 && 2 <= c && c < 5) {
407 qr.module[p[0]+r][p[1]+c] = 2
408 } else {
409 qr.module[p[0]+r][p[1]+c] = -2
410 }
411 }
412 }
413 }
414
415 // alignment pattern
416 pat := positionAdjustPatternTable[qr.Version]
417
418 for i := 0; i < len(pat); i++ {
419 for j := 0; j < len(pat); j++ {
420 row, col := pat[i], pat[j]
421 if !isBlank(row, col) {
422 continue
423 }
424
425 for r := -2; r <= 2; r++ {
426 for c := -2; c <= 2; c++ {
427 if r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0) {
428 qr.module[row+r][col+c] = 2
429 } else {
430 qr.module[row+r][col+c] = -2
431 }
432 }
433 }
434 }
435 }
436
437 // timing pattern
438 for i := 0; i < qr.len(); i++ {
439 if !isBlank(i, 6) {
440 continue
441 }
442 if i%2 == 0 {
443 qr.module[i][6] = -2
444 } else {
445 qr.module[i][6] = 2
446 }
447 }
448 for i := 0; i < qr.len(); i++ {
449 if !isBlank(6, i) {
450 continue
451 }
452 if i%2 == 0 {
453 qr.module[6][i] = -2
454 } else {
455 qr.module[6][i] = 2
456 }
457 }
458
459 // version information
460 if qr.Version >= 7 {
461 versionBits := versionInformationTable[qr.Version-7]
462
463 for j := 0; j < 6; j++ {
464 for k := qr.len() - 11; k < qr.len()-8; k++ {
465 if (versionBits & 1) > 0 {
466 qr.module[k][j] = 2
467 qr.module[j][k] = 2
468 } else {
469 qr.module[k][j] = -2
470 qr.module[j][k] = -2
471 }
472 versionBits = versionBits >> 1
473 }
474 }
475 }
476
477 // single bit
478 qr.module[qr.len()-8][8] = 2
479
480 // dummy format infomation (mask v0)
481 qr.setTypeBits(0)
482
483 }
484
485 func (qr *Qrcode) mapData() {
486
487 // byte slice to bit slice
488 bitbuf := new(bitBuffer)
489 for _, b := range qr.encodedData {
490 bitbuf.appendByte(b)
491 }
492
493 // reminder bits
494 switch qr.Version {
495 case 2, 3, 4, 5, 6:
496 bitbuf.append(0, 7)
497 case 14, 15, 16, 17, 18, 19, 20, 28, 29, 30, 31, 32, 33, 34:
498 bitbuf.append(0, 3)
499 case 21, 22, 23, 24, 25, 26, 27:
500 bitbuf.append(0, 4)
501 }
502
503 r := qr.len() - 1 // row
504 c := qr.len() - 1 // column
505 v := 1 // direction 1:up, -1:down
506 h := 1 // 1:right, -1:left
507 i := 0 // index
508
509 for {
510 if qr.module[r][c] == 0 {
511 if bitbuf.get(i) == true {
512 qr.module[r][c] = 1
513 } else {
514 qr.module[r][c] = -1
515 }
516 i++
517 }
518 if i >= bitbuf.len() {
519 break
520 }
521 if c == 6 { // skip
522 c--
523 h = 1
524 } else if h == 1 { // right
525 if c != 0 {
526 c--
527 h *= -1
528 }
529 } else { // left
530 if (v > 0 && r == 0) || (v < 0 && r == qr.len()-1) {
531 v *= -1
532 c--
533 h *= -1
534 } else {
535 c++
536 h *= -1
537 r -= v
538 }
539 }
540 }
541 }
542
543 func (qr *Qrcode) maskData() {
544
545 qr.penalty = make([]int, 8)
546 c := make(chan int, 8) // channel
547
548 for i := 0; i < 8; i++ {
549 // Penalty
550 go qr.calcPenalty(i, c)
551 }
552
553 for k := 0; k < 8; k++ {
554 <-c
555 }
556
557 mask := 0
558 min := qr.penalty[0]
559
560 for i := 1; i < 8; i++ {
561 if qr.penalty[i] < min {
562 min = qr.penalty[i]
563 mask = i
564 }
565 }
566
567 qr.setTypeBits(mask)
568 qr.module = maskData(mask, qr.module)
569 }
570
571 func (qr *Qrcode) errorCorrectionCode(data []byte, block, blockIndex int, c chan int) {
572
573 eccw := qr.ecCodeWords() // ec code word per block
574 totalBlkCount := qr.blkCount()[0] + qr.blkCount()[1] // total blocks
575 dcw := qr.totalDataCodeWords() // total data code words
576
577 // message polynominal
578 msg := polynominal{}
579 for i := 0; i < len(data); i++ {
580 x := len(data) + eccw - 1 - i
581 msg[x] = int2exp[data[i]]
582 }
583
584 // generator polynominal
585 gen := polynominal{0: 0}
586 for i := 0; i < eccw; i++ {
587 p := polynominal{1: 0, 0: i}
588 gen = gen.multiply(p)
589 }
590
591 // error collection code words
592 for i := len(data) - 1; i >= 0; i-- {
593 p := polynominal{i: msg[i+eccw]}
594 g := gen.multiply(p)
595 msg = msg.xor(g)
596 delete(msg, i+eccw)
597 }
598
599 ec := make([]byte, eccw)
600 for i := 0; i < eccw; i++ {
601 ec[i] = byte(exp2int[msg[eccw-1-i]])
602 }
603
604 for i, v := range data {
605 j := blockIndex + i*totalBlkCount
606 if j >= dcw {
607 j -= qr.blkCount()[0]
608 }
609 qr.encodedData[j] = v
610 }
611
612 for i, v := range ec {
613 qr.encodedData[dcw+blockIndex+i*totalBlkCount] = v
614 }
615
616 c <- 1
617 }
618
619 func (qr *Qrcode) encodeData() {
620
621 // total data code words
622 dcw := qr.totalDataCodeWords()
623
624 // total code words
625 cw := qr.totalCodeWords()
626
627 // total blocks
628 totalBlkCount := qr.blkCount()[0] + qr.blkCount()[1]
629
630 // encode data
631 var bytebuf *bytes.Buffer
632 switch qr.mode {
633 case "numeric":
634 bytebuf = bytes.NewBuffer(qr.encodeNumeric())
635 case "alphanum":
636 bytebuf = bytes.NewBuffer(qr.encodeAlphanum())
637 default: // default
638 bytebuf = bytes.NewBuffer(qr.encodeByte())
639 }
640
641 // pad codeword
642 for bytebuf.Len() < dcw {
643 bytebuf.WriteByte(0xEC)
644 if bytebuf.Len() < dcw {
645 bytebuf.WriteByte(0x11)
646 }
647 }
648
649 // 1. split encoded data into blocks
650 // 2. generate error correction code for each block
651 // 3. reallocate data
652 qr.encodedData = make([]byte, cw)
653
654 // goroutine
655 c := make(chan int, totalBlkCount)
656
657 for i, k := 0, 0; i < 2; i++ { // rs block 1, 2
658 for j := 0; j < qr.blkCount()[i]; j, k = j+1, k+1 {
659 go qr.errorCorrectionCode(bytebuf.Next(qr.dataCodeWords()[i]), i, k, c)
660 }
661 }
662
663 // wait
664 for k := 0; k < totalBlkCount; k++ {
665 <-c
666 }
667 }
668
669 // encode data ( numeric mode )
670 func (qr *Qrcode) encodeNumeric() []byte {
671
672 // working bit array
673 bitbuf := new(bitBuffer)
674
675 // mode indicator
676 bitbuf.append(1, 4)
677
678 // character count indicator
679 switch {
680 case qr.Version <= 9:
681 bitbuf.append(len(qr.data), 10)
682 case qr.Version <= 26:
683 bitbuf.append(len(qr.data), 12)
684 default:
685 bitbuf.append(len(qr.data), 14)
686 }
687
688 // string to bitstream
689 bytebuf := bytes.NewBufferString(qr.data)
690 for b := bytebuf.Next(3); len(b) > 0; b = bytebuf.Next(3) {
691 switch len(b) {
692 case 2:
693 n, _ := strconv.Atoi(string(b))
694 bitbuf.append(n, 7)
695 case 1:
696 n, _ := strconv.Atoi(string(b))
697 bitbuf.append(n, 4)
698 default: // 3
699 n, _ := strconv.Atoi(string(b))
700 bitbuf.append(n, 10)
701 }
702 }
703
704 // terminator
705 for i := 0; i < 4 && bitbuf.len() < qr.totalDataCodeBits(); i++ {
706 bitbuf.append(0, 1)
707 }
708
709 return bitbuf.bytes()
710
711 }
712
713 // encode data ( alphanumeric mode )
714 func (qr *Qrcode) encodeAlphanum() []byte {
715
716 // working bit array
717 bitbuf := new(bitBuffer)
718
719 // mode indicator
720 bitbuf.append(1<<1, 4)
721
722 // character count indicator
723 switch {
724 case qr.Version <= 9:
725 bitbuf.append(len(qr.data), 9)
726 case qr.Version <= 26:
727 bitbuf.append(len(qr.data), 11)
728 default:
729 bitbuf.append(len(qr.data), 13)
730 }
731
732 // string to bitstream
733 bytebuf := bytes.NewBufferString(qr.data)
734 for b := bytebuf.Next(2); len(b) > 0; b = bytebuf.Next(2) {
735 switch len(b) {
736 case 1:
737 bitbuf.append(alphanumTable[b[0]], 6)
738 default: // 2
739 bitbuf.append(alphanumTable[b[0]]*45+alphanumTable[b[1]], 11)
740 }
741 }
742
743 // terminator
744 for i := 0; i < 4 && bitbuf.len() < qr.totalDataCodeBits(); i++ {
745 bitbuf.append(0, 1)
746 }
747
748 return bitbuf.bytes()
749 }
750
751 // encode data ( 8bitbyte mode )
752 func (qr *Qrcode) encodeByte() []byte {
753
754 // working bit array
755 bitbuf := new(bitBuffer)
756
757 // mode indicator
758 bitbuf.append(1<<2, 4)
759
760 // character count indicator
761 switch {
762 case qr.Version <= 9:
763 bitbuf.append(len(qr.data), 8)
764 case qr.Version <= 26:
765 bitbuf.append(len(qr.data), 16)
766 default:
767 bitbuf.append(len(qr.data), 16)
768 }
769
770 // string to bitstream
771 bytebuf := bytes.NewBufferString(qr.data)
772 for c, e := bytebuf.ReadByte(); e == nil; c, e = bytebuf.ReadByte() {
773 bitbuf.appendByte(c)
774 }
775
776 // terminator
777 bitbuf.append(0, 4)
778
779 return bitbuf.bytes()
780 }
781
782 func (qr *Qrcode) calcPenalty(mask int, c chan int) {
783
784 penalty := 0
785
786 module := maskData(mask, setTypeBits(qr.module, qr.Level, mask))
787
788 isColored := func(r, c int) bool { return module[r][c] > 0 }
789
790 // Rule #1: five or more same colored pixels
791 for r := 0; r < qr.len(); r++ { // horizontal scan
792 for i := 0; i < qr.len()-1; i++ {
793 for j := 1; ; j++ {
794 if !(j < qr.len()-i &&
795 isColored(r, i) == isColored(r, i+j)) {
796 i += j - 1
797 break
798 }
799 if j == 4 {
800 penalty += 3
801 }
802 if j > 4 {
803 penalty++
804 }
805 }
806 }
807 }
808
809 for c := 0; c < qr.len(); c++ { // vertical scan
810 for i := 0; i < qr.len()-1; i++ {
811 for j := 1; ; j++ {
812 if !(j < qr.len()-i &&
813 isColored(i, c) == isColored(i+j, c)) {
814 i += j - 1
815 break
816 }
817 if j == 4 {
818 penalty += 3
819 }
820 if j > 4 {
821 penalty++
822 }
823 }
824 }
825 }
826
827 // Rule #2: 2x2 block of same-colored pixels
828 for r := 0; r < qr.len()-1; r++ {
829 for c := 0; c < qr.len()-1; c++ {
830 if isColored(r, c) == isColored(r+1, c) &&
831 isColored(r, c) == isColored(r, c+1) &&
832 isColored(r, c) == isColored(r+1, c+1) {
833 penalty += 3
834 }
835 }
836 }
837
838 // Rule #3: o-x-o-o-o-x-o that have four light pixels on either or both sides
839 for r := 0; r < qr.len(); r++ {
840 for c := 0; c < qr.len()-6; c++ {
841 if isColored(r, c) && !isColored(r, c+1) && isColored(r, c+2) &&
842 isColored(r, c+3) && isColored(r, c+4) && !isColored(r, c+5) &&
843 isColored(r, c+6) {
844 if c < qr.len()-10 &&
845 !isColored(r, c+7) && !isColored(r, c+8) &&
846 !isColored(r, c+9) && !isColored(r, c+10) {
847 penalty += 40
848 } else if c >= 4 &&
849 !isColored(r, c-1) && !isColored(r, c-2) &&
850 !isColored(r, c-3) && !isColored(r, c-4) {
851 penalty += 40
852 }
853 c += 4
854 }
855 }
856 }
857
858 for c := 0; c < qr.len(); c++ {
859 for r := 0; r < qr.len()-6; r++ {
860 if isColored(r, c) && !isColored(r+1, c) && isColored(r+2, c) &&
861 isColored(r+3, c) && isColored(r+4, c) && !isColored(r+5, c) &&
862 isColored(r+6, c) {
863 if r < qr.len()-10 &&
864 !isColored(r+7, c) && !isColored(r+8, c) &&
865 !isColored(r+9, c) && !isColored(r+10, c) {
866 penalty += 40
867 } else if r >= 4 &&
868 !isColored(r-1, c) && !isColored(r-2, c) &&
869 !isColored(r-3, c) && !isColored(r-4, c) {
870 penalty += 40
871 }
872 r += 4
873 }
874 }
875 }
876
877 // Rule #4: Color Ratio
878 total := 0.0
879 black := 0.0
880
881 for r, row := range module {
882 for c := range row {
883 if isColored(r, c) {
884 black++
885 }
886 total++
887 }
888 }
889 penalty += int(float64(int(math.Abs(black/total*100-50))) / 5 * 10)
890
891 qr.penalty[mask] = penalty
892
893 c <- 1
894 }
895
896 func maskData(mask int, data [][]int) [][]int {
897
898 // mask 0-7
899 maskFuncs := map[int]func(int, int) bool{
900 0: func(row, col int) bool { return (row+col)%2 == 0 },
901 1: func(row, col int) bool { return row%2 == 0 },
902 2: func(row, col int) bool { return col%3 == 0 },
903 3: func(row, col int) bool { return (row+col)%3 == 0 },
904 4: func(row, col int) bool { return (row/2+col/3)%2 == 0 },
905 5: func(row, col int) bool { return row*col%2+row*col%3 == 0 },
906 6: func(row, col int) bool { return (row*col%2+row*col%3)%2 == 0 },
907 7: func(row, col int) bool { return (row*col%3+(row+col)%2)%2 == 0 },
908 }
909
910 // copy
911 module := make([][]int, 0)
912 for _, row := range data {
913 c := make([]int, len(row))
914 copy(c, row)
915 module = append(module, c)
916 }
917
918 for r, row := range module {
919 for c := range row {
920 if !(module[r][c] == 1 || module[r][c] == -1) {
921 continue
922 }
923 if maskFuncs[mask](r, c) {
924 module[r][c] *= -1
925 }
926 }
927 }
928 return module
929 }
930
931 func setTypeBits(data [][]int, level ECLevel, mask int) [][]int {
932
933 module := make([][]int, 0)
934 for _, row := range data {
935 c := make([]int, len(row))
936 copy(c, row)
937 module = append(module, c)
938 }
939
940 bits := new(bitBuffer)
941 bits.append(typeInformationTable[level][mask], 15)
942
943 length := len(module)
944
945 for i, b := range *bits {
946 bit := 2
947 if b {
948 bit = 2
949 } else {
950 bit = -2
951 }
952
953 switch {
954 case i < 6:
955 module[8][i] = bit
956 module[length-1-i][8] = bit
957 case i == 6:
958 module[8][i+1] = bit
959 module[length-1-i][8] = bit
960 case i == 7:
961 module[8][length-15+i] = bit
962 module[8][8] = bit
963 case i == 8:
964 module[8][length-15+i] = bit
965 module[7][8] = bit
966 case i == 9:
967 module[8][length-15+i] = bit
968 module[5][8] = bit
969 case i > 9:
970 module[8][length-15+i] = bit
971 module[(7*2)-i][8] = bit
972 }
973 }
974 return module
975 }
976
977 func maxDataSize(version int, level ECLevel, mode string) (max int) {
978
979 table := errorCorrectionTable[version][level]
980 dcw := table[1]*table[2] + table[3]*table[4]
981
982 switch mode {
983 case "numeric":
984 bitsCount := dcw*8 - 4 // mode bits(4 bits)
985
986 switch { // data length bits
987 case version <= 9:
988 bitsCount -= 10
989 case version <= 26:
990 bitsCount -= 12
991 default:
992 bitsCount -= 14
993 }
994
995 max = bitsCount / 10 * 3 // 10bits for 3 chars
996 if bitsCount%10 >= 7 { // 7bits for 2 chars
997 max += 2
998 } else if bitsCount%10 >= 4 { // 4bits for 1 chars
999 max++
1000 }
1001 case "alphanum":
1002 bitsCount := dcw*8 - 4 // mode bits(4 bits)
1003
1004 switch { // data length bits
1005 case version <= 9:
1006 bitsCount -= 9
1007 case version <= 26:
1008 bitsCount -= 11
1009 default:
1010 bitsCount -= 13
1011 }
1012
1013 max = bitsCount / 11 * 2 // 11bits for 2 characters
1014 if bitsCount%11 >= 6 {
1015 max++
1016 }
1017 case "8bitbyte":
1018 max = dcw - 1 // mode(4bit) + terminal(4bit) = 1byte
1019
1020 switch { // data length bits
1021 case version <= 9:
1022 max -= 1
1023 default:
1024 max -= 2
1025 }
1026 }
1027 return
1028 }
1029
1030 // bitBuffer
1031 type bitBuffer []bool
1032
1033 func (p *bitBuffer) len() int {
1034 return len(*p)
1035 }
1036
1037 func (p *bitBuffer) append(c, l int) {
1038 for i := 0; i < l; i++ {
1039 if c&(1<<uint(l-i-1)) > 0 {
1040 *p = append(*p, true)
1041 } else {
1042 *p = append(*p, false)
1043 }
1044 }
1045 }
1046
1047 func (p *bitBuffer) get(i int) bool {
1048 return (*p)[i]
1049 }
1050
1051 func (p *bitBuffer) appendByte(b byte) {
1052 p.append(int(b), 8)
1053 }
1054
1055 func (p *bitBuffer) bytes() []byte {
1056
1057 // copy
1058 s := make(bitBuffer, p.len())
1059 copy(s, *p)
1060
1061 for s.len()%8 != 0 {
1062 s.append(0, 1)
1063 }
1064
1065 l := len(s) / 8
1066 bytebuf := bytes.NewBuffer([]byte{})
1067
1068 for i := 0; i < l; i++ {
1069 bits := s[(i * 8):(i*8 + 8)]
1070 c := byte(0)
1071 for j := 0; j < 8; j++ {
1072 if bits[j] {
1073 c += 1 << uint(8-j-1)
1074 }
1075 }
1076 bytebuf.WriteByte(c)
1077 }
1078 return bytebuf.Bytes()
1079 }
1080
1081 // polynominal ( Galois field 256 )
1082 // used to calculate error correction code
1083 // (a^x)*(x^25) + (a^y)*(x^24) + (a^z)*(x^23) + .... => {25:x,24:y,23:z,.....}
1084 type polynominal map[int]int
1085
1086 func (p0 polynominal) multiply(p1 polynominal) polynominal {
1087 poly := polynominal{}
1088 for x1, a1 := range p1 {
1089 for x0, a0 := range p0 {
1090 x := x1 + x0
1091 for x >= 255 {
1092 x -= 255
1093 x = (x >> 8) + (x & 255)
1094 }
1095 a := a1 + a0
1096 for a >= 255 {
1097 a -= 255
1098 a = (a >> 8) + (a & 255)
1099 }
1100 if poly[x] == 0 {
1101 poly[x] = exp2int[a]
1102 } else {
1103 anti := poly[x] ^ exp2int[a]
1104 poly[x] = anti
1105 }
1106 }
1107 }
1108 for x, a := range poly {
1109 poly[x] = int2exp[a]
1110 }
1111 return poly
1112 }
1113
1114 func (p0 polynominal) xor(p1 polynominal) polynominal {
1115 poly := polynominal{}
1116 for x0, a0 := range p0 {
1117 poly[x0] = exp2int[a0]
1118 }
1119 for x1, a1 := range p1 {
1120 if poly[x1] == 0 {
1121 poly[x1] = exp2int[a1]
1122 } else {
1123 poly[x1] = poly[x1] ^ exp2int[a1]
1124 }
1125 }
1126 for x, a := range poly {
1127 poly[x] = int2exp[a]
1128 }
1129 return poly
1130 }
1131