hy-app 0.6.6 → 0.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1235 +1,1244 @@
1
1
  let QRCode = {}
2
- ;(function () {
3
- /**
4
- * 获取单个字符的utf8编码
5
- * unicode BMP平面约65535个字符
6
- * @param {num} code
7
- * return {array}
8
- */
9
- function unicodeFormat8(code) {
10
- // 1 byte
11
- var c0, c1, c2
12
- if (code < 128) {
13
- return [code]
14
- // 2 bytes
15
- } else if (code < 2048) {
16
- c0 = 192 + (code >> 6)
17
- c1 = 128 + (code & 63)
18
- return [c0, c1]
19
- // 3 bytes
20
- } else {
21
- c0 = 224 + (code >> 12)
22
- c1 = 128 + ((code >> 6) & 63)
23
- c2 = 128 + (code & 63)
24
- return [c0, c1, c2]
25
- }
26
- }
27
- /**
28
- * 获取字符串的utf8编码字节串
29
- * @param {string} string
30
- * @return {array}
31
- */
32
- function getUTF8Bytes(string) {
33
- var utf8codes = []
34
- for (var i = 0; i < string.length; i++) {
35
- var code = string.charCodeAt(i)
36
- var utf8 = unicodeFormat8(code)
37
- for (var j = 0; j < utf8.length; j++) {
38
- utf8codes.push(utf8[j])
39
- }
40
- }
41
- return utf8codes
42
- }
43
- /**
44
- * 二维码算法实现
45
- * @param {string} data 要编码的信息字符串
46
- * @param {num} errorCorrectLevel 纠错等级
47
- */
48
- function QRCodeAlg(data, errorCorrectLevel) {
49
- this.typeNumber = -1 //版本
50
- this.errorCorrectLevel = errorCorrectLevel
51
- this.modules = null //二维矩阵,存放最终结果
52
- this.moduleCount = 0 //矩阵大小
53
- this.dataCache = null //数据缓存
54
- this.rsBlocks = null //版本数据信息
55
- this.totalDataCount = -1 //可使用的数据量
56
- this.data = data
57
- this.utf8bytes = getUTF8Bytes(data)
58
- this.make()
59
- }
60
- QRCodeAlg.prototype = {
61
- constructor: QRCodeAlg,
62
- /**
63
- * 获取二维码矩阵大小
64
- * @return {num} 矩阵大小
65
- */
66
- getModuleCount: function () {
67
- return this.moduleCount
68
- },
69
- /**
70
- * 编码
71
- */
72
- make: function () {
73
- this.getRightType()
74
- this.dataCache = this.createData()
75
- this.createQrcode()
76
- },
2
+ ; (function () {
77
3
  /**
78
- * 设置二位矩阵功能图形
79
- * @param {bool} test 表示是否在寻找最好掩膜阶段
80
- * @param {num} maskPattern 掩膜的版本
4
+ * 获取单个字符的utf8编码
5
+ * unicode BMP平面约65535个字符
6
+ * @param {num} code
7
+ * return {array}
81
8
  */
82
- makeImpl: function (maskPattern) {
83
- this.moduleCount = this.typeNumber * 4 + 17
84
- this.modules = new Array(this.moduleCount)
85
- for (var row = 0; row < this.moduleCount; row++) {
86
- this.modules[row] = new Array(this.moduleCount)
87
- }
88
- this.setupPositionProbePattern(0, 0)
89
- this.setupPositionProbePattern(this.moduleCount - 7, 0)
90
- this.setupPositionProbePattern(0, this.moduleCount - 7)
91
- this.setupPositionAdjustPattern()
92
- this.setupTimingPattern()
93
- this.setupTypeInfo(true, maskPattern)
94
- if (this.typeNumber >= 7) {
95
- this.setupTypeNumber(true)
9
+ function unicodeFormat8(code) {
10
+ // 1 byte
11
+ var c0, c1, c2
12
+ if (code < 128) {
13
+ return [code]
14
+ // 2 bytes
15
+ } else if (code < 2048) {
16
+ c0 = 192 + (code >> 6)
17
+ c1 = 128 + (code & 63)
18
+ return [c0, c1]
19
+ // 3 bytes
20
+ } else {
21
+ c0 = 224 + (code >> 12)
22
+ c1 = 128 + ((code >> 6) & 63)
23
+ c2 = 128 + (code & 63)
24
+ return [c0, c1, c2]
96
25
  }
97
- this.mapData(this.dataCache, maskPattern)
98
- },
26
+ }
99
27
  /**
100
- * 设置二维码的位置探测图形
101
- * @param {num} row 探测图形的中心横坐标
102
- * @param {num} col 探测图形的中心纵坐标
28
+ * 获取字符串的utf8编码字节串
29
+ * @param {string} string
30
+ * @return {array}
103
31
  */
104
- setupPositionProbePattern: function (row, col) {
105
- for (var r = -1; r <= 7; r++) {
106
- if (row + r <= -1 || this.moduleCount <= row + r) continue
107
- for (var c = -1; c <= 7; c++) {
108
- if (col + c <= -1 || this.moduleCount <= col + c) continue
109
- if (
110
- (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
- (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
- (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
- ) {
114
- this.modules[row + r][col + c] = true
115
- } else {
116
- this.modules[row + r][col + c] = false
117
- }
32
+ function getUTF8Bytes(string) {
33
+ var utf8codes = []
34
+ for (var i = 0; i < string.length; i++) {
35
+ var code = string.charCodeAt(i)
36
+ var utf8 = unicodeFormat8(code)
37
+ for (var j = 0; j < utf8.length; j++) {
38
+ utf8codes.push(utf8[j])
118
39
  }
119
40
  }
120
- },
41
+ return utf8codes
42
+ }
121
43
  /**
122
- * 创建二维码
123
- * @return {[type]} [description]
44
+ * 二维码算法实现
45
+ * @param {string} data 要编码的信息字符串
46
+ * @param {num} errorCorrectLevel 纠错等级
124
47
  */
125
- createQrcode: function () {
126
- var minLostPoint = 0
127
- var pattern = 0
128
- var bestModules = null
129
- for (var i = 0; i < 8; i++) {
130
- this.makeImpl(i)
131
- var lostPoint = QRUtil.getLostPoint(this)
132
- if (i == 0 || minLostPoint > lostPoint) {
133
- minLostPoint = lostPoint
134
- pattern = i
135
- bestModules = this.modules
48
+ function QRCodeAlg(data, errorCorrectLevel) {
49
+ this.typeNumber = -1 //版本
50
+ this.errorCorrectLevel = errorCorrectLevel
51
+ this.modules = null //二维矩阵,存放最终结果
52
+ this.moduleCount = 0 //矩阵大小
53
+ this.dataCache = null //数据缓存
54
+ this.rsBlocks = null //版本数据信息
55
+ this.totalDataCount = -1 //可使用的数据量
56
+ this.data = data
57
+ this.utf8bytes = getUTF8Bytes(data)
58
+ this.make()
59
+ }
60
+ QRCodeAlg.prototype = {
61
+ constructor: QRCodeAlg,
62
+ /**
63
+ * 获取二维码矩阵大小
64
+ * @return {num} 矩阵大小
65
+ */
66
+ getModuleCount: function () {
67
+ return this.moduleCount
68
+ },
69
+ /**
70
+ * 编码
71
+ */
72
+ make: function () {
73
+ this.getRightType()
74
+ this.dataCache = this.createData()
75
+ this.createQrcode()
76
+ },
77
+ /**
78
+ * 设置二位矩阵功能图形
79
+ * @param {bool} test 表示是否在寻找最好掩膜阶段
80
+ * @param {num} maskPattern 掩膜的版本
81
+ */
82
+ makeImpl: function (maskPattern) {
83
+ this.moduleCount = this.typeNumber * 4 + 17
84
+ this.modules = new Array(this.moduleCount)
85
+ for (var row = 0; row < this.moduleCount; row++) {
86
+ this.modules[row] = new Array(this.moduleCount)
136
87
  }
137
- }
138
- this.modules = bestModules
139
- this.setupTypeInfo(false, pattern)
140
- if (this.typeNumber >= 7) {
141
- this.setupTypeNumber(false)
142
- }
143
- },
144
- /**
145
- * 设置定位图形
146
- * @return {[type]} [description]
147
- */
148
- setupTimingPattern: function () {
149
- for (var r = 8; r < this.moduleCount - 8; r++) {
150
- if (this.modules[r][6] != null) {
151
- continue
88
+ this.setupPositionProbePattern(0, 0)
89
+ this.setupPositionProbePattern(this.moduleCount - 7, 0)
90
+ this.setupPositionProbePattern(0, this.moduleCount - 7)
91
+ this.setupPositionAdjustPattern()
92
+ this.setupTimingPattern()
93
+ this.setupTypeInfo(true, maskPattern)
94
+ if (this.typeNumber >= 7) {
95
+ this.setupTypeNumber(true)
152
96
  }
153
- this.modules[r][6] = r % 2 == 0
154
- if (this.modules[6][r] != null) {
155
- continue
97
+ this.mapData(this.dataCache, maskPattern)
98
+ },
99
+ /**
100
+ * 设置二维码的位置探测图形
101
+ * @param {num} row 探测图形的中心横坐标
102
+ * @param {num} col 探测图形的中心纵坐标
103
+ */
104
+ setupPositionProbePattern: function (row, col) {
105
+ for (var r = -1; r <= 7; r++) {
106
+ if (row + r <= -1 || this.moduleCount <= row + r) continue
107
+ for (var c = -1; c <= 7; c++) {
108
+ if (col + c <= -1 || this.moduleCount <= col + c) continue
109
+ if (
110
+ (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
+ (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
+ (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
+ ) {
114
+ this.modules[row + r][col + c] = true
115
+ } else {
116
+ this.modules[row + r][col + c] = false
117
+ }
118
+ }
156
119
  }
157
- this.modules[6][r] = r % 2 == 0
158
- }
159
- },
160
- /**
161
- * 设置矫正图形
162
- * @return {[type]} [description]
163
- */
164
- setupPositionAdjustPattern: function () {
165
- var pos = QRUtil.getPatternPosition(this.typeNumber)
166
- for (var i = 0; i < pos.length; i++) {
167
- for (var j = 0; j < pos.length; j++) {
168
- var row = pos[i]
169
- var col = pos[j]
170
- if (this.modules[row][col] != null) {
120
+ },
121
+ /**
122
+ * 创建二维码
123
+ * @return {[type]} [description]
124
+ */
125
+ createQrcode: function () {
126
+ var minLostPoint = 0
127
+ var pattern = 0
128
+ var bestModules = null
129
+ for (var i = 0; i < 8; i++) {
130
+ this.makeImpl(i)
131
+ var lostPoint = QRUtil.getLostPoint(this)
132
+ if (i == 0 || minLostPoint > lostPoint) {
133
+ minLostPoint = lostPoint
134
+ pattern = i
135
+ bestModules = this.modules
136
+ }
137
+ }
138
+ this.modules = bestModules
139
+ this.setupTypeInfo(false, pattern)
140
+ if (this.typeNumber >= 7) {
141
+ this.setupTypeNumber(false)
142
+ }
143
+ },
144
+ /**
145
+ * 设置定位图形
146
+ * @return {[type]} [description]
147
+ */
148
+ setupTimingPattern: function () {
149
+ for (var r = 8; r < this.moduleCount - 8; r++) {
150
+ if (this.modules[r][6] != null) {
151
+ continue
152
+ }
153
+ this.modules[r][6] = r % 2 == 0
154
+ if (this.modules[6][r] != null) {
171
155
  continue
172
156
  }
173
- for (var r = -2; r <= 2; r++) {
174
- for (var c = -2; c <= 2; c++) {
175
- if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
176
- this.modules[row + r][col + c] = true
177
- } else {
178
- this.modules[row + r][col + c] = false
157
+ this.modules[6][r] = r % 2 == 0
158
+ }
159
+ },
160
+ /**
161
+ * 设置矫正图形
162
+ * @return {[type]} [description]
163
+ */
164
+ setupPositionAdjustPattern: function () {
165
+ var pos = QRUtil.getPatternPosition(this.typeNumber)
166
+ for (var i = 0; i < pos.length; i++) {
167
+ for (var j = 0; j < pos.length; j++) {
168
+ var row = pos[i]
169
+ var col = pos[j]
170
+ if (this.modules[row][col] != null) {
171
+ continue
172
+ }
173
+ for (var r = -2; r <= 2; r++) {
174
+ for (var c = -2; c <= 2; c++) {
175
+ if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
176
+ this.modules[row + r][col + c] = true
177
+ } else {
178
+ this.modules[row + r][col + c] = false
179
+ }
179
180
  }
180
181
  }
181
182
  }
182
183
  }
183
- }
184
- },
185
- /**
186
- * 设置版本信息(7以上版本才有)
187
- * @param {bool} test 是否处于判断最佳掩膜阶段
188
- * @return {[type]} [description]
189
- */
190
- setupTypeNumber: function (test) {
191
- var bits = QRUtil.getBCHTypeNumber(this.typeNumber)
192
- for (var i = 0; i < 18; i++) {
193
- var mod = !test && ((bits >> i) & 1) == 1
194
- this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
195
- this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
196
- }
197
- },
198
- /**
199
- * 设置格式信息(纠错等级和掩膜版本)
200
- * @param {bool} test
201
- * @param {num} maskPattern 掩膜版本
202
- * @return {}
203
- */
204
- setupTypeInfo: function (test, maskPattern) {
205
- var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern
206
- var bits = QRUtil.getBCHTypeInfo(data)
207
- // vertical
208
- for (var i = 0; i < 15; i++) {
209
- var mod = !test && ((bits >> i) & 1) == 1
210
- if (i < 6) {
211
- this.modules[i][8] = mod
212
- } else if (i < 8) {
213
- this.modules[i + 1][8] = mod
214
- } else {
215
- this.modules[this.moduleCount - 15 + i][8] = mod
216
- }
217
- // horizontal
218
- var mod = !test && ((bits >> i) & 1) == 1
219
- if (i < 8) {
220
- this.modules[8][this.moduleCount - i - 1] = mod
221
- } else if (i < 9) {
222
- this.modules[8][15 - i - 1 + 1] = mod
223
- } else {
224
- this.modules[8][15 - i - 1] = mod
184
+ },
185
+ /**
186
+ * 设置版本信息(7以上版本才有)
187
+ * @param {bool} test 是否处于判断最佳掩膜阶段
188
+ * @return {[type]} [description]
189
+ */
190
+ setupTypeNumber: function (test) {
191
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber)
192
+ for (var i = 0; i < 18; i++) {
193
+ var mod = !test && ((bits >> i) & 1) == 1
194
+ this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
195
+ this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
225
196
  }
226
- }
227
- // fixed module
228
- this.modules[this.moduleCount - 8][8] = !test
229
- },
230
- /**
231
- * 数据编码
232
- * @return {[type]} [description]
233
- */
234
- createData: function () {
235
- var buffer = new QRBitBuffer()
236
- var lengthBits = this.typeNumber > 9 ? 16 : 8
237
- buffer.put(4, 4) //添加模式
238
- buffer.put(this.utf8bytes.length, lengthBits)
239
- for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
240
- buffer.put(this.utf8bytes[i], 8)
241
- }
242
- if (buffer.length + 4 <= this.totalDataCount * 8) {
243
- buffer.put(0, 4)
244
- }
245
- // padding
246
- while (buffer.length % 8 != 0) {
247
- buffer.putBit(false)
248
- }
249
- // padding
250
- while (true) {
251
- if (buffer.length >= this.totalDataCount * 8) {
252
- break
197
+ },
198
+ /**
199
+ * 设置格式信息(纠错等级和掩膜版本)
200
+ * @param {bool} test
201
+ * @param {num} maskPattern 掩膜版本
202
+ * @return {}
203
+ */
204
+ setupTypeInfo: function (test, maskPattern) {
205
+ var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern
206
+ var bits = QRUtil.getBCHTypeInfo(data)
207
+ // vertical
208
+ for (var i = 0; i < 15; i++) {
209
+ var mod = !test && ((bits >> i) & 1) == 1
210
+ if (i < 6) {
211
+ this.modules[i][8] = mod
212
+ } else if (i < 8) {
213
+ this.modules[i + 1][8] = mod
214
+ } else {
215
+ this.modules[this.moduleCount - 15 + i][8] = mod
216
+ }
217
+ // horizontal
218
+ var mod = !test && ((bits >> i) & 1) == 1
219
+ if (i < 8) {
220
+ this.modules[8][this.moduleCount - i - 1] = mod
221
+ } else if (i < 9) {
222
+ this.modules[8][15 - i - 1 + 1] = mod
223
+ } else {
224
+ this.modules[8][15 - i - 1] = mod
225
+ }
253
226
  }
254
- buffer.put(QRCodeAlg.PAD0, 8)
255
- if (buffer.length >= this.totalDataCount * 8) {
256
- break
227
+ // fixed module
228
+ this.modules[this.moduleCount - 8][8] = !test
229
+ },
230
+ /**
231
+ * 数据编码
232
+ * @return {[type]} [description]
233
+ */
234
+ createData: function () {
235
+ var buffer = new QRBitBuffer()
236
+ var lengthBits = this.typeNumber > 9 ? 16 : 8
237
+ buffer.put(4, 4) //添加模式
238
+ buffer.put(this.utf8bytes.length, lengthBits)
239
+ for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
240
+ buffer.put(this.utf8bytes[i], 8)
257
241
  }
258
- buffer.put(QRCodeAlg.PAD1, 8)
259
- }
260
- return this.createBytes(buffer)
261
- },
262
- /**
263
- * 纠错码编码
264
- * @param {buffer} buffer 数据编码
265
- * @return {[type]}
266
- */
267
- createBytes: function (buffer) {
268
- var offset = 0
269
- var maxDcCount = 0
270
- var maxEcCount = 0
271
- var length = this.rsBlock.length / 3
272
- var rsBlocks = new Array()
273
- for (var i = 0; i < length; i++) {
274
- var count = this.rsBlock[i * 3 + 0]
275
- var totalCount = this.rsBlock[i * 3 + 1]
276
- var dataCount = this.rsBlock[i * 3 + 2]
277
- for (var j = 0; j < count; j++) {
278
- rsBlocks.push([dataCount, totalCount])
242
+ if (buffer.length + 4 <= this.totalDataCount * 8) {
243
+ buffer.put(0, 4)
279
244
  }
280
- }
281
- var dcdata = new Array(rsBlocks.length)
282
- var ecdata = new Array(rsBlocks.length)
283
- for (var r = 0; r < rsBlocks.length; r++) {
284
- var dcCount = rsBlocks[r][0]
285
- var ecCount = rsBlocks[r][1] - dcCount
286
- maxDcCount = Math.max(maxDcCount, dcCount)
287
- maxEcCount = Math.max(maxEcCount, ecCount)
288
- dcdata[r] = new Array(dcCount)
289
- for (var i = 0; i < dcdata[r].length; i++) {
290
- dcdata[r][i] = 0xff & buffer.buffer[i + offset]
245
+ // padding
246
+ while (buffer.length % 8 != 0) {
247
+ buffer.putBit(false)
291
248
  }
292
- offset += dcCount
293
- var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
294
- var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
295
- var modPoly = rawPoly.mod(rsPoly)
296
- ecdata[r] = new Array(rsPoly.getLength() - 1)
297
- for (var i = 0; i < ecdata[r].length; i++) {
298
- var modIndex = i + modPoly.getLength() - ecdata[r].length
299
- ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
249
+ // padding
250
+ while (true) {
251
+ if (buffer.length >= this.totalDataCount * 8) {
252
+ break
253
+ }
254
+ buffer.put(QRCodeAlg.PAD0, 8)
255
+ if (buffer.length >= this.totalDataCount * 8) {
256
+ break
257
+ }
258
+ buffer.put(QRCodeAlg.PAD1, 8)
300
259
  }
301
- }
302
- var data = new Array(this.totalDataCount)
303
- var index = 0
304
- for (var i = 0; i < maxDcCount; i++) {
305
- for (var r = 0; r < rsBlocks.length; r++) {
306
- if (i < dcdata[r].length) {
307
- data[index++] = dcdata[r][i]
260
+ return this.createBytes(buffer)
261
+ },
262
+ /**
263
+ * 纠错码编码
264
+ * @param {buffer} buffer 数据编码
265
+ * @return {[type]}
266
+ */
267
+ createBytes: function (buffer) {
268
+ var offset = 0
269
+ var maxDcCount = 0
270
+ var maxEcCount = 0
271
+ var length = this.rsBlock.length / 3
272
+ var rsBlocks = new Array()
273
+ for (var i = 0; i < length; i++) {
274
+ var count = this.rsBlock[i * 3 + 0]
275
+ var totalCount = this.rsBlock[i * 3 + 1]
276
+ var dataCount = this.rsBlock[i * 3 + 2]
277
+ for (var j = 0; j < count; j++) {
278
+ rsBlocks.push([dataCount, totalCount])
308
279
  }
309
280
  }
310
- }
311
- for (var i = 0; i < maxEcCount; i++) {
281
+ var dcdata = new Array(rsBlocks.length)
282
+ var ecdata = new Array(rsBlocks.length)
312
283
  for (var r = 0; r < rsBlocks.length; r++) {
313
- if (i < ecdata[r].length) {
314
- data[index++] = ecdata[r][i]
284
+ var dcCount = rsBlocks[r][0]
285
+ var ecCount = rsBlocks[r][1] - dcCount
286
+ maxDcCount = Math.max(maxDcCount, dcCount)
287
+ maxEcCount = Math.max(maxEcCount, ecCount)
288
+ dcdata[r] = new Array(dcCount)
289
+ for (var i = 0; i < dcdata[r].length; i++) {
290
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset]
291
+ }
292
+ offset += dcCount
293
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
294
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
295
+ var modPoly = rawPoly.mod(rsPoly)
296
+ ecdata[r] = new Array(rsPoly.getLength() - 1)
297
+ for (var i = 0; i < ecdata[r].length; i++) {
298
+ var modIndex = i + modPoly.getLength() - ecdata[r].length
299
+ ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
315
300
  }
316
301
  }
317
- }
318
- return data
319
- },
320
- /**
321
- * 布置模块,构建最终信息
322
- * @param {} data
323
- * @param {} maskPattern
324
- * @return {}
325
- */
326
- mapData: function (data, maskPattern) {
327
- var inc = -1
328
- var row = this.moduleCount - 1
329
- var bitIndex = 7
330
- var byteIndex = 0
331
- for (var col = this.moduleCount - 1; col > 0; col -= 2) {
332
- if (col == 6) col--
333
- while (true) {
334
- for (var c = 0; c < 2; c++) {
335
- if (this.modules[row][col - c] == null) {
336
- var dark = false
337
- if (byteIndex < data.length) {
338
- dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
339
- }
340
- var mask = QRUtil.getMask(maskPattern, row, col - c)
341
- if (mask) {
342
- dark = !dark
343
- }
344
- this.modules[row][col - c] = dark
345
- bitIndex--
346
- if (bitIndex == -1) {
347
- byteIndex++
348
- bitIndex = 7
349
- }
302
+ var data = new Array(this.totalDataCount)
303
+ var index = 0
304
+ for (var i = 0; i < maxDcCount; i++) {
305
+ for (var r = 0; r < rsBlocks.length; r++) {
306
+ if (i < dcdata[r].length) {
307
+ data[index++] = dcdata[r][i]
350
308
  }
351
309
  }
352
- row += inc
353
- if (row < 0 || this.moduleCount <= row) {
354
- row -= inc
355
- inc = -inc
356
- break
310
+ }
311
+ for (var i = 0; i < maxEcCount; i++) {
312
+ for (var r = 0; r < rsBlocks.length; r++) {
313
+ if (i < ecdata[r].length) {
314
+ data[index++] = ecdata[r][i]
315
+ }
357
316
  }
358
317
  }
359
- }
360
- }
361
- }
362
- /**
363
- * 填充字段
364
- */
365
- QRCodeAlg.PAD0 = 0xec
366
- QRCodeAlg.PAD1 = 0x11
367
- //---------------------------------------------------------------------
368
- // 纠错等级对应的编码
369
- //---------------------------------------------------------------------
370
- var QRErrorCorrectLevel = [1, 0, 3, 2]
371
- //---------------------------------------------------------------------
372
- // 掩膜版本
373
- //---------------------------------------------------------------------
374
- var QRMaskPattern = {
375
- PATTERN000: 0,
376
- PATTERN001: 1,
377
- PATTERN010: 2,
378
- PATTERN011: 3,
379
- PATTERN100: 4,
380
- PATTERN101: 5,
381
- PATTERN110: 6,
382
- PATTERN111: 7
383
- }
384
- //---------------------------------------------------------------------
385
- // 工具类
386
- //---------------------------------------------------------------------
387
- var QRUtil = {
388
- /*
389
- 每个版本矫正图形的位置
390
- */
391
- PATTERN_POSITION_TABLE: [
392
- [],
393
- [6, 18],
394
- [6, 22],
395
- [6, 26],
396
- [6, 30],
397
- [6, 34],
398
- [6, 22, 38],
399
- [6, 24, 42],
400
- [6, 26, 46],
401
- [6, 28, 50],
402
- [6, 30, 54],
403
- [6, 32, 58],
404
- [6, 34, 62],
405
- [6, 26, 46, 66],
406
- [6, 26, 48, 70],
407
- [6, 26, 50, 74],
408
- [6, 30, 54, 78],
409
- [6, 30, 56, 82],
410
- [6, 30, 58, 86],
411
- [6, 34, 62, 90],
412
- [6, 28, 50, 72, 94],
413
- [6, 26, 50, 74, 98],
414
- [6, 30, 54, 78, 102],
415
- [6, 28, 54, 80, 106],
416
- [6, 32, 58, 84, 110],
417
- [6, 30, 58, 86, 114],
418
- [6, 34, 62, 90, 118],
419
- [6, 26, 50, 74, 98, 122],
420
- [6, 30, 54, 78, 102, 126],
421
- [6, 26, 52, 78, 104, 130],
422
- [6, 30, 56, 82, 108, 134],
423
- [6, 34, 60, 86, 112, 138],
424
- [6, 30, 58, 86, 114, 142],
425
- [6, 34, 62, 90, 118, 146],
426
- [6, 30, 54, 78, 102, 126, 150],
427
- [6, 24, 50, 76, 102, 128, 154],
428
- [6, 28, 54, 80, 106, 132, 158],
429
- [6, 32, 58, 84, 110, 136, 162],
430
- [6, 26, 54, 82, 110, 138, 166],
431
- [6, 30, 58, 86, 114, 142, 170]
432
- ],
433
- G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
434
- G18:
435
- (1 << 12) |
436
- (1 << 11) |
437
- (1 << 10) |
438
- (1 << 9) |
439
- (1 << 8) |
440
- (1 << 5) |
441
- (1 << 2) |
442
- (1 << 0),
443
- G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
444
- /*
445
- BCH编码格式信息
446
- */
447
- getBCHTypeInfo: function (data) {
448
- var d = data << 10
449
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
450
- d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
451
- }
452
- return ((data << 10) | d) ^ QRUtil.G15_MASK
453
- },
454
- /*
455
- BCH编码版本信息
456
- */
457
- getBCHTypeNumber: function (data) {
458
- var d = data << 12
459
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
460
- d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
461
- }
462
- return (data << 12) | d
463
- },
464
- /*
465
- 获取BCH位信息
318
+ return data
319
+ },
320
+ /**
321
+ * 布置模块,构建最终信息
322
+ * @param {} data
323
+ * @param {} maskPattern
324
+ * @return {}
466
325
  */
467
- getBCHDigit: function (data) {
468
- var digit = 0
469
- while (data != 0) {
470
- digit++
471
- data >>>= 1
472
- }
473
- return digit
474
- },
475
- /*
476
- 获取版本对应的矫正图形位置
477
- */
478
- getPatternPosition: function (typeNumber) {
479
- return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
480
- },
481
- /*
482
- 掩膜算法
483
- */
484
- getMask: function (maskPattern, i, j) {
485
- switch (maskPattern) {
486
- case QRMaskPattern.PATTERN000:
487
- return (i + j) % 2 == 0
488
- case QRMaskPattern.PATTERN001:
489
- return i % 2 == 0
490
- case QRMaskPattern.PATTERN010:
491
- return j % 3 == 0
492
- case QRMaskPattern.PATTERN011:
493
- return (i + j) % 3 == 0
494
- case QRMaskPattern.PATTERN100:
495
- return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
496
- case QRMaskPattern.PATTERN101:
497
- return ((i * j) % 2) + ((i * j) % 3) == 0
498
- case QRMaskPattern.PATTERN110:
499
- return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
500
- case QRMaskPattern.PATTERN111:
501
- return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
502
- default:
503
- throw new Error('bad maskPattern:' + maskPattern)
504
- }
505
- },
506
- /*
507
- 获取RS的纠错多项式
508
- */
509
- getErrorCorrectPolynomial: function (errorCorrectLength) {
510
- var a = new QRPolynomial([1], 0)
511
- for (var i = 0; i < errorCorrectLength; i++) {
512
- a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
513
- }
514
- return a
515
- },
516
- /*
517
- 获取评价
518
- */
519
- getLostPoint: function (qrCode) {
520
- var moduleCount = qrCode.getModuleCount(),
521
- lostPoint = 0,
522
- darkCount = 0
523
- for (var row = 0; row < moduleCount; row++) {
524
- var sameCount = 0
525
- var head = qrCode.modules[row][0]
526
- for (var col = 0; col < moduleCount; col++) {
527
- var current = qrCode.modules[row][col]
528
- //level 3 评价
529
- if (col < moduleCount - 6) {
530
- if (
531
- current &&
532
- !qrCode.modules[row][col + 1] &&
533
- qrCode.modules[row][col + 2] &&
534
- qrCode.modules[row][col + 3] &&
535
- qrCode.modules[row][col + 4] &&
536
- !qrCode.modules[row][col + 5] &&
537
- qrCode.modules[row][col + 6]
538
- ) {
539
- if (col < moduleCount - 10) {
540
- if (
541
- qrCode.modules[row][col + 7] &&
542
- qrCode.modules[row][col + 8] &&
543
- qrCode.modules[row][col + 9] &&
544
- qrCode.modules[row][col + 10]
545
- ) {
546
- lostPoint += 40
326
+ mapData: function (data, maskPattern) {
327
+ var inc = -1
328
+ var row = this.moduleCount - 1
329
+ var bitIndex = 7
330
+ var byteIndex = 0
331
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
332
+ if (col == 6) col--
333
+ while (true) {
334
+ for (var c = 0; c < 2; c++) {
335
+ if (this.modules[row][col - c] == null) {
336
+ var dark = false
337
+ if (byteIndex < data.length) {
338
+ dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
547
339
  }
548
- } else if (col > 3) {
549
- if (
550
- qrCode.modules[row][col - 1] &&
551
- qrCode.modules[row][col - 2] &&
552
- qrCode.modules[row][col - 3] &&
553
- qrCode.modules[row][col - 4]
554
- ) {
555
- lostPoint += 40
340
+ var mask = QRUtil.getMask(maskPattern, row, col - c)
341
+ if (mask) {
342
+ dark = !dark
343
+ }
344
+ this.modules[row][col - c] = dark
345
+ bitIndex--
346
+ if (bitIndex == -1) {
347
+ byteIndex++
348
+ bitIndex = 7
556
349
  }
557
350
  }
558
351
  }
559
- }
560
- //level 2 评价
561
- if (row < moduleCount - 1 && col < moduleCount - 1) {
562
- var count = 0
563
- if (current) count++
564
- if (qrCode.modules[row + 1][col]) count++
565
- if (qrCode.modules[row][col + 1]) count++
566
- if (qrCode.modules[row + 1][col + 1]) count++
567
- if (count == 0 || count == 4) {
568
- lostPoint += 3
569
- }
570
- }
571
- //level 1 评价
572
- if (head ^ current) {
573
- sameCount++
574
- } else {
575
- head = current
576
- if (sameCount >= 5) {
577
- lostPoint += 3 + sameCount - 5
352
+ row += inc
353
+ if (row < 0 || this.moduleCount <= row) {
354
+ row -= inc
355
+ inc = -inc
356
+ break
578
357
  }
579
- sameCount = 1
580
- }
581
- //level 4 评价
582
- if (current) {
583
- darkCount++
584
358
  }
585
359
  }
586
360
  }
587
- for (var col = 0; col < moduleCount; col++) {
588
- var sameCount = 0
589
- var head = qrCode.modules[0][col]
361
+ }
362
+ /**
363
+ * 填充字段
364
+ */
365
+ QRCodeAlg.PAD0 = 0xec
366
+ QRCodeAlg.PAD1 = 0x11
367
+ //---------------------------------------------------------------------
368
+ // 纠错等级对应的编码
369
+ //---------------------------------------------------------------------
370
+ var QRErrorCorrectLevel = [1, 0, 3, 2]
371
+ //---------------------------------------------------------------------
372
+ // 掩膜版本
373
+ //---------------------------------------------------------------------
374
+ var QRMaskPattern = {
375
+ PATTERN000: 0,
376
+ PATTERN001: 1,
377
+ PATTERN010: 2,
378
+ PATTERN011: 3,
379
+ PATTERN100: 4,
380
+ PATTERN101: 5,
381
+ PATTERN110: 6,
382
+ PATTERN111: 7
383
+ }
384
+ //---------------------------------------------------------------------
385
+ // 工具类
386
+ //---------------------------------------------------------------------
387
+ var QRUtil = {
388
+ /*
389
+ 每个版本矫正图形的位置
390
+ */
391
+ PATTERN_POSITION_TABLE: [
392
+ [],
393
+ [6, 18],
394
+ [6, 22],
395
+ [6, 26],
396
+ [6, 30],
397
+ [6, 34],
398
+ [6, 22, 38],
399
+ [6, 24, 42],
400
+ [6, 26, 46],
401
+ [6, 28, 50],
402
+ [6, 30, 54],
403
+ [6, 32, 58],
404
+ [6, 34, 62],
405
+ [6, 26, 46, 66],
406
+ [6, 26, 48, 70],
407
+ [6, 26, 50, 74],
408
+ [6, 30, 54, 78],
409
+ [6, 30, 56, 82],
410
+ [6, 30, 58, 86],
411
+ [6, 34, 62, 90],
412
+ [6, 28, 50, 72, 94],
413
+ [6, 26, 50, 74, 98],
414
+ [6, 30, 54, 78, 102],
415
+ [6, 28, 54, 80, 106],
416
+ [6, 32, 58, 84, 110],
417
+ [6, 30, 58, 86, 114],
418
+ [6, 34, 62, 90, 118],
419
+ [6, 26, 50, 74, 98, 122],
420
+ [6, 30, 54, 78, 102, 126],
421
+ [6, 26, 52, 78, 104, 130],
422
+ [6, 30, 56, 82, 108, 134],
423
+ [6, 34, 60, 86, 112, 138],
424
+ [6, 30, 58, 86, 114, 142],
425
+ [6, 34, 62, 90, 118, 146],
426
+ [6, 30, 54, 78, 102, 126, 150],
427
+ [6, 24, 50, 76, 102, 128, 154],
428
+ [6, 28, 54, 80, 106, 132, 158],
429
+ [6, 32, 58, 84, 110, 136, 162],
430
+ [6, 26, 54, 82, 110, 138, 166],
431
+ [6, 30, 58, 86, 114, 142, 170]
432
+ ],
433
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
434
+ G18:
435
+ (1 << 12) |
436
+ (1 << 11) |
437
+ (1 << 10) |
438
+ (1 << 9) |
439
+ (1 << 8) |
440
+ (1 << 5) |
441
+ (1 << 2) |
442
+ (1 << 0),
443
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
444
+ /*
445
+ BCH编码格式信息
446
+ */
447
+ getBCHTypeInfo: function (data) {
448
+ var d = data << 10
449
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
450
+ d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
451
+ }
452
+ return ((data << 10) | d) ^ QRUtil.G15_MASK
453
+ },
454
+ /*
455
+ BCH编码版本信息
456
+ */
457
+ getBCHTypeNumber: function (data) {
458
+ var d = data << 12
459
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
460
+ d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
461
+ }
462
+ return (data << 12) | d
463
+ },
464
+ /*
465
+ 获取BCH位信息
466
+ */
467
+ getBCHDigit: function (data) {
468
+ var digit = 0
469
+ while (data != 0) {
470
+ digit++
471
+ data >>>= 1
472
+ }
473
+ return digit
474
+ },
475
+ /*
476
+ 获取版本对应的矫正图形位置
477
+ */
478
+ getPatternPosition: function (typeNumber) {
479
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
480
+ },
481
+ /*
482
+ 掩膜算法
483
+ */
484
+ getMask: function (maskPattern, i, j) {
485
+ switch (maskPattern) {
486
+ case QRMaskPattern.PATTERN000:
487
+ return (i + j) % 2 == 0
488
+ case QRMaskPattern.PATTERN001:
489
+ return i % 2 == 0
490
+ case QRMaskPattern.PATTERN010:
491
+ return j % 3 == 0
492
+ case QRMaskPattern.PATTERN011:
493
+ return (i + j) % 3 == 0
494
+ case QRMaskPattern.PATTERN100:
495
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
496
+ case QRMaskPattern.PATTERN101:
497
+ return ((i * j) % 2) + ((i * j) % 3) == 0
498
+ case QRMaskPattern.PATTERN110:
499
+ return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
500
+ case QRMaskPattern.PATTERN111:
501
+ return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
502
+ default:
503
+ throw new Error('bad maskPattern:' + maskPattern)
504
+ }
505
+ },
506
+ /*
507
+ 获取RS的纠错多项式
508
+ */
509
+ getErrorCorrectPolynomial: function (errorCorrectLength) {
510
+ var a = new QRPolynomial([1], 0)
511
+ for (var i = 0; i < errorCorrectLength; i++) {
512
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
513
+ }
514
+ return a
515
+ },
516
+ /*
517
+ 获取评价
518
+ */
519
+ getLostPoint: function (qrCode) {
520
+ var moduleCount = qrCode.getModuleCount(),
521
+ lostPoint = 0,
522
+ darkCount = 0
590
523
  for (var row = 0; row < moduleCount; row++) {
591
- var current = qrCode.modules[row][col]
592
- //level 3 评价
593
- if (row < moduleCount - 6) {
594
- if (
595
- current &&
596
- !qrCode.modules[row + 1][col] &&
597
- qrCode.modules[row + 2][col] &&
598
- qrCode.modules[row + 3][col] &&
599
- qrCode.modules[row + 4][col] &&
600
- !qrCode.modules[row + 5][col] &&
601
- qrCode.modules[row + 6][col]
602
- ) {
603
- if (row < moduleCount - 10) {
604
- if (
605
- qrCode.modules[row + 7][col] &&
606
- qrCode.modules[row + 8][col] &&
607
- qrCode.modules[row + 9][col] &&
608
- qrCode.modules[row + 10][col]
609
- ) {
610
- lostPoint += 40
611
- }
612
- } else if (row > 3) {
613
- if (
614
- qrCode.modules[row - 1][col] &&
615
- qrCode.modules[row - 2][col] &&
616
- qrCode.modules[row - 3][col] &&
617
- qrCode.modules[row - 4][col]
618
- ) {
619
- lostPoint += 40
524
+ var sameCount = 0
525
+ var head = qrCode.modules[row][0]
526
+ for (var col = 0; col < moduleCount; col++) {
527
+ var current = qrCode.modules[row][col]
528
+ //level 3 评价
529
+ if (col < moduleCount - 6) {
530
+ if (
531
+ current &&
532
+ !qrCode.modules[row][col + 1] &&
533
+ qrCode.modules[row][col + 2] &&
534
+ qrCode.modules[row][col + 3] &&
535
+ qrCode.modules[row][col + 4] &&
536
+ !qrCode.modules[row][col + 5] &&
537
+ qrCode.modules[row][col + 6]
538
+ ) {
539
+ if (col < moduleCount - 10) {
540
+ if (
541
+ qrCode.modules[row][col + 7] &&
542
+ qrCode.modules[row][col + 8] &&
543
+ qrCode.modules[row][col + 9] &&
544
+ qrCode.modules[row][col + 10]
545
+ ) {
546
+ lostPoint += 40
547
+ }
548
+ } else if (col > 3) {
549
+ if (
550
+ qrCode.modules[row][col - 1] &&
551
+ qrCode.modules[row][col - 2] &&
552
+ qrCode.modules[row][col - 3] &&
553
+ qrCode.modules[row][col - 4]
554
+ ) {
555
+ lostPoint += 40
556
+ }
620
557
  }
621
558
  }
622
559
  }
560
+ //level 2 评价
561
+ if (row < moduleCount - 1 && col < moduleCount - 1) {
562
+ var count = 0
563
+ if (current) count++
564
+ if (qrCode.modules[row + 1][col]) count++
565
+ if (qrCode.modules[row][col + 1]) count++
566
+ if (qrCode.modules[row + 1][col + 1]) count++
567
+ if (count == 0 || count == 4) {
568
+ lostPoint += 3
569
+ }
570
+ }
571
+ //level 1 评价
572
+ if (head ^ current) {
573
+ sameCount++
574
+ } else {
575
+ head = current
576
+ if (sameCount >= 5) {
577
+ lostPoint += 3 + sameCount - 5
578
+ }
579
+ sameCount = 1
580
+ }
581
+ //level 4 评价
582
+ if (current) {
583
+ darkCount++
584
+ }
623
585
  }
624
- //level 1 评价
625
- if (head ^ current) {
626
- sameCount++
627
- } else {
628
- head = current
629
- if (sameCount >= 5) {
630
- lostPoint += 3 + sameCount - 5
586
+ }
587
+ for (var col = 0; col < moduleCount; col++) {
588
+ var sameCount = 0
589
+ var head = qrCode.modules[0][col]
590
+ for (var row = 0; row < moduleCount; row++) {
591
+ var current = qrCode.modules[row][col]
592
+ //level 3 评价
593
+ if (row < moduleCount - 6) {
594
+ if (
595
+ current &&
596
+ !qrCode.modules[row + 1][col] &&
597
+ qrCode.modules[row + 2][col] &&
598
+ qrCode.modules[row + 3][col] &&
599
+ qrCode.modules[row + 4][col] &&
600
+ !qrCode.modules[row + 5][col] &&
601
+ qrCode.modules[row + 6][col]
602
+ ) {
603
+ if (row < moduleCount - 10) {
604
+ if (
605
+ qrCode.modules[row + 7][col] &&
606
+ qrCode.modules[row + 8][col] &&
607
+ qrCode.modules[row + 9][col] &&
608
+ qrCode.modules[row + 10][col]
609
+ ) {
610
+ lostPoint += 40
611
+ }
612
+ } else if (row > 3) {
613
+ if (
614
+ qrCode.modules[row - 1][col] &&
615
+ qrCode.modules[row - 2][col] &&
616
+ qrCode.modules[row - 3][col] &&
617
+ qrCode.modules[row - 4][col]
618
+ ) {
619
+ lostPoint += 40
620
+ }
621
+ }
622
+ }
623
+ }
624
+ //level 1 评价
625
+ if (head ^ current) {
626
+ sameCount++
627
+ } else {
628
+ head = current
629
+ if (sameCount >= 5) {
630
+ lostPoint += 3 + sameCount - 5
631
+ }
632
+ sameCount = 1
631
633
  }
632
- sameCount = 1
633
634
  }
634
635
  }
636
+ // LEVEL4
637
+ var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
638
+ lostPoint += ratio * 10
639
+ return lostPoint
635
640
  }
636
- // LEVEL4
637
- var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
638
- lostPoint += ratio * 10
639
- return lostPoint
640
641
  }
641
- }
642
- //---------------------------------------------------------------------
643
- // QRMath使用的数学工具
644
- //---------------------------------------------------------------------
645
- var QRMath = {
646
- /*
647
- 将n转化为a^m
648
- */
649
- glog: function (n) {
650
- if (n < 1) {
651
- throw new Error('glog(' + n + ')')
652
- }
653
- return QRMath.LOG_TABLE[n]
654
- },
655
- /*
656
- 将a^m转化为n
657
- */
658
- gexp: function (n) {
659
- while (n < 0) {
660
- n += 255
661
- }
662
- while (n >= 256) {
663
- n -= 255
664
- }
665
- return QRMath.EXP_TABLE[n]
666
- },
667
- EXP_TABLE: new Array(256),
668
- LOG_TABLE: new Array(256)
669
- }
670
- for (var i = 0; i < 8; i++) {
671
- QRMath.EXP_TABLE[i] = 1 << i
672
- }
673
- for (var i = 8; i < 256; i++) {
674
- QRMath.EXP_TABLE[i] =
675
- QRMath.EXP_TABLE[i - 4] ^
676
- QRMath.EXP_TABLE[i - 5] ^
677
- QRMath.EXP_TABLE[i - 6] ^
678
- QRMath.EXP_TABLE[i - 8]
679
- }
680
- for (var i = 0; i < 255; i++) {
681
- QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
682
- }
683
- //---------------------------------------------------------------------
684
- // QRPolynomial 多项式
685
- //---------------------------------------------------------------------
686
- /**
687
- * 多项式类
688
- * @param {Array} num 系数
689
- * @param {num} shift a^shift
690
- */
691
- function QRPolynomial(num, shift) {
692
- if (num.length == undefined) {
693
- throw new Error(num.length + '/' + shift)
642
+ //---------------------------------------------------------------------
643
+ // QRMath使用的数学工具
644
+ //---------------------------------------------------------------------
645
+ var QRMath = {
646
+ /*
647
+ 将n转化为a^m
648
+ */
649
+ glog: function (n) {
650
+ if (n < 1) {
651
+ throw new Error('glog(' + n + ')')
652
+ }
653
+ return QRMath.LOG_TABLE[n]
654
+ },
655
+ /*
656
+ 将a^m转化为n
657
+ */
658
+ gexp: function (n) {
659
+ while (n < 0) {
660
+ n += 255
661
+ }
662
+ while (n >= 256) {
663
+ n -= 255
664
+ }
665
+ return QRMath.EXP_TABLE[n]
666
+ },
667
+ EXP_TABLE: new Array(256),
668
+ LOG_TABLE: new Array(256)
669
+ }
670
+ for (var i = 0; i < 8; i++) {
671
+ QRMath.EXP_TABLE[i] = 1 << i
694
672
  }
695
- var offset = 0
696
- while (offset < num.length && num[offset] == 0) {
697
- offset++
673
+ for (var i = 8; i < 256; i++) {
674
+ QRMath.EXP_TABLE[i] =
675
+ QRMath.EXP_TABLE[i - 4] ^
676
+ QRMath.EXP_TABLE[i - 5] ^
677
+ QRMath.EXP_TABLE[i - 6] ^
678
+ QRMath.EXP_TABLE[i - 8]
698
679
  }
699
- this.num = new Array(num.length - offset + shift)
700
- for (var i = 0; i < num.length - offset; i++) {
701
- this.num[i] = num[i + offset]
680
+ for (var i = 0; i < 255; i++) {
681
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
702
682
  }
703
- }
704
- QRPolynomial.prototype = {
705
- get: function (index) {
706
- return this.num[index]
707
- },
708
- getLength: function () {
709
- return this.num.length
710
- },
683
+ //---------------------------------------------------------------------
684
+ // QRPolynomial 多项式
685
+ //---------------------------------------------------------------------
711
686
  /**
712
- * 多项式乘法
713
- * @param {QRPolynomial} e 被乘多项式
714
- * @return {[type]} [description]
687
+ * 多项式类
688
+ * @param {Array} num 系数
689
+ * @param {num} shift a^shift
715
690
  */
716
- multiply: function (e) {
717
- var num = new Array(this.getLength() + e.getLength() - 1)
718
- for (var i = 0; i < this.getLength(); i++) {
719
- for (var j = 0; j < e.getLength(); j++) {
720
- num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
721
- }
691
+ function QRPolynomial(num, shift) {
692
+ if (num.length == undefined) {
693
+ throw new Error(num.length + '/' + shift)
722
694
  }
723
- return new QRPolynomial(num, 0)
724
- },
725
- /**
726
- * 多项式模运算
727
- * @param {QRPolynomial} e 模多项式
728
- * @return {}
729
- */
730
- mod: function (e) {
731
- var tl = this.getLength(),
732
- el = e.getLength()
733
- if (tl - el < 0) {
734
- return this
695
+ var offset = 0
696
+ while (offset < num.length && num[offset] == 0) {
697
+ offset++
735
698
  }
736
- var num = new Array(tl)
737
- for (var i = 0; i < tl; i++) {
738
- num[i] = this.get(i)
699
+ this.num = new Array(num.length - offset + shift)
700
+ for (var i = 0; i < num.length - offset; i++) {
701
+ this.num[i] = num[i + offset]
739
702
  }
740
- while (num.length >= el) {
741
- var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0))
742
-
743
- for (var i = 0; i < e.getLength(); i++) {
744
- num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
703
+ }
704
+ QRPolynomial.prototype = {
705
+ get: function (index) {
706
+ return this.num[index]
707
+ },
708
+ getLength: function () {
709
+ return this.num.length
710
+ },
711
+ /**
712
+ * 多项式乘法
713
+ * @param {QRPolynomial} e 被乘多项式
714
+ * @return {[type]} [description]
715
+ */
716
+ multiply: function (e) {
717
+ var num = new Array(this.getLength() + e.getLength() - 1)
718
+ for (var i = 0; i < this.getLength(); i++) {
719
+ for (var j = 0; j < e.getLength(); j++) {
720
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
721
+ }
722
+ }
723
+ return new QRPolynomial(num, 0)
724
+ },
725
+ /**
726
+ * 多项式模运算
727
+ * @param {QRPolynomial} e 模多项式
728
+ * @return {}
729
+ */
730
+ mod: function (e) {
731
+ var tl = this.getLength(),
732
+ el = e.getLength()
733
+ if (tl - el < 0) {
734
+ return this
735
+ }
736
+ var num = new Array(tl)
737
+ for (var i = 0; i < tl; i++) {
738
+ num[i] = this.get(i)
745
739
  }
746
- while (num[0] == 0) {
747
- num.shift()
740
+ while (num.length >= el) {
741
+ var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0))
742
+
743
+ for (var i = 0; i < e.getLength(); i++) {
744
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
745
+ }
746
+ while (num[0] == 0) {
747
+ num.shift()
748
+ }
748
749
  }
750
+ return new QRPolynomial(num, 0)
749
751
  }
750
- return new QRPolynomial(num, 0)
751
752
  }
752
- }
753
753
 
754
- //---------------------------------------------------------------------
755
- // RS_BLOCK_TABLE
756
- //---------------------------------------------------------------------
757
- /*
758
- 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
759
- */
760
- var RS_BLOCK_TABLE = [
761
- // L
762
- // M
763
- // Q
764
- // H
765
- // 1
766
- [1, 26, 19],
767
- [1, 26, 16],
768
- [1, 26, 13],
769
- [1, 26, 9],
754
+ //---------------------------------------------------------------------
755
+ // RS_BLOCK_TABLE
756
+ //---------------------------------------------------------------------
757
+ /*
758
+ 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
759
+ */
760
+ var RS_BLOCK_TABLE = [
761
+ // L
762
+ // M
763
+ // Q
764
+ // H
765
+ // 1
766
+ [1, 26, 19],
767
+ [1, 26, 16],
768
+ [1, 26, 13],
769
+ [1, 26, 9],
770
770
 
771
- // 2
772
- [1, 44, 34],
773
- [1, 44, 28],
774
- [1, 44, 22],
775
- [1, 44, 16],
771
+ // 2
772
+ [1, 44, 34],
773
+ [1, 44, 28],
774
+ [1, 44, 22],
775
+ [1, 44, 16],
776
776
 
777
- // 3
778
- [1, 70, 55],
779
- [1, 70, 44],
780
- [2, 35, 17],
781
- [2, 35, 13],
777
+ // 3
778
+ [1, 70, 55],
779
+ [1, 70, 44],
780
+ [2, 35, 17],
781
+ [2, 35, 13],
782
782
 
783
- // 4
784
- [1, 100, 80],
785
- [2, 50, 32],
786
- [2, 50, 24],
787
- [4, 25, 9],
783
+ // 4
784
+ [1, 100, 80],
785
+ [2, 50, 32],
786
+ [2, 50, 24],
787
+ [4, 25, 9],
788
788
 
789
- // 5
790
- [1, 134, 108],
791
- [2, 67, 43],
792
- [2, 33, 15, 2, 34, 16],
793
- [2, 33, 11, 2, 34, 12],
789
+ // 5
790
+ [1, 134, 108],
791
+ [2, 67, 43],
792
+ [2, 33, 15, 2, 34, 16],
793
+ [2, 33, 11, 2, 34, 12],
794
794
 
795
- // 6
796
- [2, 86, 68],
797
- [4, 43, 27],
798
- [4, 43, 19],
799
- [4, 43, 15],
795
+ // 6
796
+ [2, 86, 68],
797
+ [4, 43, 27],
798
+ [4, 43, 19],
799
+ [4, 43, 15],
800
800
 
801
- // 7
802
- [2, 98, 78],
803
- [4, 49, 31],
804
- [2, 32, 14, 4, 33, 15],
805
- [4, 39, 13, 1, 40, 14],
801
+ // 7
802
+ [2, 98, 78],
803
+ [4, 49, 31],
804
+ [2, 32, 14, 4, 33, 15],
805
+ [4, 39, 13, 1, 40, 14],
806
806
 
807
- // 8
808
- [2, 121, 97],
809
- [2, 60, 38, 2, 61, 39],
810
- [4, 40, 18, 2, 41, 19],
811
- [4, 40, 14, 2, 41, 15],
807
+ // 8
808
+ [2, 121, 97],
809
+ [2, 60, 38, 2, 61, 39],
810
+ [4, 40, 18, 2, 41, 19],
811
+ [4, 40, 14, 2, 41, 15],
812
812
 
813
- // 9
814
- [2, 146, 116],
815
- [3, 58, 36, 2, 59, 37],
816
- [4, 36, 16, 4, 37, 17],
817
- [4, 36, 12, 4, 37, 13],
813
+ // 9
814
+ [2, 146, 116],
815
+ [3, 58, 36, 2, 59, 37],
816
+ [4, 36, 16, 4, 37, 17],
817
+ [4, 36, 12, 4, 37, 13],
818
818
 
819
- // 10
820
- [2, 86, 68, 2, 87, 69],
821
- [4, 69, 43, 1, 70, 44],
822
- [6, 43, 19, 2, 44, 20],
823
- [6, 43, 15, 2, 44, 16],
819
+ // 10
820
+ [2, 86, 68, 2, 87, 69],
821
+ [4, 69, 43, 1, 70, 44],
822
+ [6, 43, 19, 2, 44, 20],
823
+ [6, 43, 15, 2, 44, 16],
824
824
 
825
- // 11
826
- [4, 101, 81],
827
- [1, 80, 50, 4, 81, 51],
828
- [4, 50, 22, 4, 51, 23],
829
- [3, 36, 12, 8, 37, 13],
825
+ // 11
826
+ [4, 101, 81],
827
+ [1, 80, 50, 4, 81, 51],
828
+ [4, 50, 22, 4, 51, 23],
829
+ [3, 36, 12, 8, 37, 13],
830
830
 
831
- // 12
832
- [2, 116, 92, 2, 117, 93],
833
- [6, 58, 36, 2, 59, 37],
834
- [4, 46, 20, 6, 47, 21],
835
- [7, 42, 14, 4, 43, 15],
831
+ // 12
832
+ [2, 116, 92, 2, 117, 93],
833
+ [6, 58, 36, 2, 59, 37],
834
+ [4, 46, 20, 6, 47, 21],
835
+ [7, 42, 14, 4, 43, 15],
836
836
 
837
- // 13
838
- [4, 133, 107],
839
- [8, 59, 37, 1, 60, 38],
840
- [8, 44, 20, 4, 45, 21],
841
- [12, 33, 11, 4, 34, 12],
837
+ // 13
838
+ [4, 133, 107],
839
+ [8, 59, 37, 1, 60, 38],
840
+ [8, 44, 20, 4, 45, 21],
841
+ [12, 33, 11, 4, 34, 12],
842
842
 
843
- // 14
844
- [3, 145, 115, 1, 146, 116],
845
- [4, 64, 40, 5, 65, 41],
846
- [11, 36, 16, 5, 37, 17],
847
- [11, 36, 12, 5, 37, 13],
843
+ // 14
844
+ [3, 145, 115, 1, 146, 116],
845
+ [4, 64, 40, 5, 65, 41],
846
+ [11, 36, 16, 5, 37, 17],
847
+ [11, 36, 12, 5, 37, 13],
848
848
 
849
- // 15
850
- [5, 109, 87, 1, 110, 88],
851
- [5, 65, 41, 5, 66, 42],
852
- [5, 54, 24, 7, 55, 25],
853
- [11, 36, 12],
849
+ // 15
850
+ [5, 109, 87, 1, 110, 88],
851
+ [5, 65, 41, 5, 66, 42],
852
+ [5, 54, 24, 7, 55, 25],
853
+ [11, 36, 12],
854
854
 
855
- // 16
856
- [5, 122, 98, 1, 123, 99],
857
- [7, 73, 45, 3, 74, 46],
858
- [15, 43, 19, 2, 44, 20],
859
- [3, 45, 15, 13, 46, 16],
855
+ // 16
856
+ [5, 122, 98, 1, 123, 99],
857
+ [7, 73, 45, 3, 74, 46],
858
+ [15, 43, 19, 2, 44, 20],
859
+ [3, 45, 15, 13, 46, 16],
860
860
 
861
- // 17
862
- [1, 135, 107, 5, 136, 108],
863
- [10, 74, 46, 1, 75, 47],
864
- [1, 50, 22, 15, 51, 23],
865
- [2, 42, 14, 17, 43, 15],
861
+ // 17
862
+ [1, 135, 107, 5, 136, 108],
863
+ [10, 74, 46, 1, 75, 47],
864
+ [1, 50, 22, 15, 51, 23],
865
+ [2, 42, 14, 17, 43, 15],
866
866
 
867
- // 18
868
- [5, 150, 120, 1, 151, 121],
869
- [9, 69, 43, 4, 70, 44],
870
- [17, 50, 22, 1, 51, 23],
871
- [2, 42, 14, 19, 43, 15],
867
+ // 18
868
+ [5, 150, 120, 1, 151, 121],
869
+ [9, 69, 43, 4, 70, 44],
870
+ [17, 50, 22, 1, 51, 23],
871
+ [2, 42, 14, 19, 43, 15],
872
872
 
873
- // 19
874
- [3, 141, 113, 4, 142, 114],
875
- [3, 70, 44, 11, 71, 45],
876
- [17, 47, 21, 4, 48, 22],
877
- [9, 39, 13, 16, 40, 14],
873
+ // 19
874
+ [3, 141, 113, 4, 142, 114],
875
+ [3, 70, 44, 11, 71, 45],
876
+ [17, 47, 21, 4, 48, 22],
877
+ [9, 39, 13, 16, 40, 14],
878
878
 
879
- // 20
880
- [3, 135, 107, 5, 136, 108],
881
- [3, 67, 41, 13, 68, 42],
882
- [15, 54, 24, 5, 55, 25],
883
- [15, 43, 15, 10, 44, 16],
879
+ // 20
880
+ [3, 135, 107, 5, 136, 108],
881
+ [3, 67, 41, 13, 68, 42],
882
+ [15, 54, 24, 5, 55, 25],
883
+ [15, 43, 15, 10, 44, 16],
884
884
 
885
- // 21
886
- [4, 144, 116, 4, 145, 117],
887
- [17, 68, 42],
888
- [17, 50, 22, 6, 51, 23],
889
- [19, 46, 16, 6, 47, 17],
885
+ // 21
886
+ [4, 144, 116, 4, 145, 117],
887
+ [17, 68, 42],
888
+ [17, 50, 22, 6, 51, 23],
889
+ [19, 46, 16, 6, 47, 17],
890
890
 
891
- // 22
892
- [2, 139, 111, 7, 140, 112],
893
- [17, 74, 46],
894
- [7, 54, 24, 16, 55, 25],
895
- [34, 37, 13],
891
+ // 22
892
+ [2, 139, 111, 7, 140, 112],
893
+ [17, 74, 46],
894
+ [7, 54, 24, 16, 55, 25],
895
+ [34, 37, 13],
896
896
 
897
- // 23
898
- [4, 151, 121, 5, 152, 122],
899
- [4, 75, 47, 14, 76, 48],
900
- [11, 54, 24, 14, 55, 25],
901
- [16, 45, 15, 14, 46, 16],
897
+ // 23
898
+ [4, 151, 121, 5, 152, 122],
899
+ [4, 75, 47, 14, 76, 48],
900
+ [11, 54, 24, 14, 55, 25],
901
+ [16, 45, 15, 14, 46, 16],
902
902
 
903
- // 24
904
- [6, 147, 117, 4, 148, 118],
905
- [6, 73, 45, 14, 74, 46],
906
- [11, 54, 24, 16, 55, 25],
907
- [30, 46, 16, 2, 47, 17],
903
+ // 24
904
+ [6, 147, 117, 4, 148, 118],
905
+ [6, 73, 45, 14, 74, 46],
906
+ [11, 54, 24, 16, 55, 25],
907
+ [30, 46, 16, 2, 47, 17],
908
908
 
909
- // 25
910
- [8, 132, 106, 4, 133, 107],
911
- [8, 75, 47, 13, 76, 48],
912
- [7, 54, 24, 22, 55, 25],
913
- [22, 45, 15, 13, 46, 16],
909
+ // 25
910
+ [8, 132, 106, 4, 133, 107],
911
+ [8, 75, 47, 13, 76, 48],
912
+ [7, 54, 24, 22, 55, 25],
913
+ [22, 45, 15, 13, 46, 16],
914
914
 
915
- // 26
916
- [10, 142, 114, 2, 143, 115],
917
- [19, 74, 46, 4, 75, 47],
918
- [28, 50, 22, 6, 51, 23],
919
- [33, 46, 16, 4, 47, 17],
915
+ // 26
916
+ [10, 142, 114, 2, 143, 115],
917
+ [19, 74, 46, 4, 75, 47],
918
+ [28, 50, 22, 6, 51, 23],
919
+ [33, 46, 16, 4, 47, 17],
920
920
 
921
- // 27
922
- [8, 152, 122, 4, 153, 123],
923
- [22, 73, 45, 3, 74, 46],
924
- [8, 53, 23, 26, 54, 24],
925
- [12, 45, 15, 28, 46, 16],
921
+ // 27
922
+ [8, 152, 122, 4, 153, 123],
923
+ [22, 73, 45, 3, 74, 46],
924
+ [8, 53, 23, 26, 54, 24],
925
+ [12, 45, 15, 28, 46, 16],
926
926
 
927
- // 28
928
- [3, 147, 117, 10, 148, 118],
929
- [3, 73, 45, 23, 74, 46],
930
- [4, 54, 24, 31, 55, 25],
931
- [11, 45, 15, 31, 46, 16],
927
+ // 28
928
+ [3, 147, 117, 10, 148, 118],
929
+ [3, 73, 45, 23, 74, 46],
930
+ [4, 54, 24, 31, 55, 25],
931
+ [11, 45, 15, 31, 46, 16],
932
932
 
933
- // 29
934
- [7, 146, 116, 7, 147, 117],
935
- [21, 73, 45, 7, 74, 46],
936
- [1, 53, 23, 37, 54, 24],
937
- [19, 45, 15, 26, 46, 16],
933
+ // 29
934
+ [7, 146, 116, 7, 147, 117],
935
+ [21, 73, 45, 7, 74, 46],
936
+ [1, 53, 23, 37, 54, 24],
937
+ [19, 45, 15, 26, 46, 16],
938
938
 
939
- // 30
940
- [5, 145, 115, 10, 146, 116],
941
- [19, 75, 47, 10, 76, 48],
942
- [15, 54, 24, 25, 55, 25],
943
- [23, 45, 15, 25, 46, 16],
939
+ // 30
940
+ [5, 145, 115, 10, 146, 116],
941
+ [19, 75, 47, 10, 76, 48],
942
+ [15, 54, 24, 25, 55, 25],
943
+ [23, 45, 15, 25, 46, 16],
944
944
 
945
- // 31
946
- [13, 145, 115, 3, 146, 116],
947
- [2, 74, 46, 29, 75, 47],
948
- [42, 54, 24, 1, 55, 25],
949
- [23, 45, 15, 28, 46, 16],
945
+ // 31
946
+ [13, 145, 115, 3, 146, 116],
947
+ [2, 74, 46, 29, 75, 47],
948
+ [42, 54, 24, 1, 55, 25],
949
+ [23, 45, 15, 28, 46, 16],
950
950
 
951
- // 32
952
- [17, 145, 115],
953
- [10, 74, 46, 23, 75, 47],
954
- [10, 54, 24, 35, 55, 25],
955
- [19, 45, 15, 35, 46, 16],
951
+ // 32
952
+ [17, 145, 115],
953
+ [10, 74, 46, 23, 75, 47],
954
+ [10, 54, 24, 35, 55, 25],
955
+ [19, 45, 15, 35, 46, 16],
956
956
 
957
- // 33
958
- [17, 145, 115, 1, 146, 116],
959
- [14, 74, 46, 21, 75, 47],
960
- [29, 54, 24, 19, 55, 25],
961
- [11, 45, 15, 46, 46, 16],
957
+ // 33
958
+ [17, 145, 115, 1, 146, 116],
959
+ [14, 74, 46, 21, 75, 47],
960
+ [29, 54, 24, 19, 55, 25],
961
+ [11, 45, 15, 46, 46, 16],
962
962
 
963
- // 34
964
- [13, 145, 115, 6, 146, 116],
965
- [14, 74, 46, 23, 75, 47],
966
- [44, 54, 24, 7, 55, 25],
967
- [59, 46, 16, 1, 47, 17],
963
+ // 34
964
+ [13, 145, 115, 6, 146, 116],
965
+ [14, 74, 46, 23, 75, 47],
966
+ [44, 54, 24, 7, 55, 25],
967
+ [59, 46, 16, 1, 47, 17],
968
968
 
969
- // 35
970
- [12, 151, 121, 7, 152, 122],
971
- [12, 75, 47, 26, 76, 48],
972
- [39, 54, 24, 14, 55, 25],
973
- [22, 45, 15, 41, 46, 16],
969
+ // 35
970
+ [12, 151, 121, 7, 152, 122],
971
+ [12, 75, 47, 26, 76, 48],
972
+ [39, 54, 24, 14, 55, 25],
973
+ [22, 45, 15, 41, 46, 16],
974
974
 
975
- // 36
976
- [6, 151, 121, 14, 152, 122],
977
- [6, 75, 47, 34, 76, 48],
978
- [46, 54, 24, 10, 55, 25],
979
- [2, 45, 15, 64, 46, 16],
975
+ // 36
976
+ [6, 151, 121, 14, 152, 122],
977
+ [6, 75, 47, 34, 76, 48],
978
+ [46, 54, 24, 10, 55, 25],
979
+ [2, 45, 15, 64, 46, 16],
980
980
 
981
- // 37
982
- [17, 152, 122, 4, 153, 123],
983
- [29, 74, 46, 14, 75, 47],
984
- [49, 54, 24, 10, 55, 25],
985
- [24, 45, 15, 46, 46, 16],
981
+ // 37
982
+ [17, 152, 122, 4, 153, 123],
983
+ [29, 74, 46, 14, 75, 47],
984
+ [49, 54, 24, 10, 55, 25],
985
+ [24, 45, 15, 46, 46, 16],
986
986
 
987
- // 38
988
- [4, 152, 122, 18, 153, 123],
989
- [13, 74, 46, 32, 75, 47],
990
- [48, 54, 24, 14, 55, 25],
991
- [42, 45, 15, 32, 46, 16],
987
+ // 38
988
+ [4, 152, 122, 18, 153, 123],
989
+ [13, 74, 46, 32, 75, 47],
990
+ [48, 54, 24, 14, 55, 25],
991
+ [42, 45, 15, 32, 46, 16],
992
992
 
993
- // 39
994
- [20, 147, 117, 4, 148, 118],
995
- [40, 75, 47, 7, 76, 48],
996
- [43, 54, 24, 22, 55, 25],
997
- [10, 45, 15, 67, 46, 16],
993
+ // 39
994
+ [20, 147, 117, 4, 148, 118],
995
+ [40, 75, 47, 7, 76, 48],
996
+ [43, 54, 24, 22, 55, 25],
997
+ [10, 45, 15, 67, 46, 16],
998
998
 
999
- // 40
1000
- [19, 148, 118, 6, 149, 119],
1001
- [18, 75, 47, 31, 76, 48],
1002
- [34, 54, 24, 34, 55, 25],
1003
- [20, 45, 15, 61, 46, 16]
1004
- ]
999
+ // 40
1000
+ [19, 148, 118, 6, 149, 119],
1001
+ [18, 75, 47, 31, 76, 48],
1002
+ [34, 54, 24, 34, 55, 25],
1003
+ [20, 45, 15, 61, 46, 16]
1004
+ ]
1005
1005
 
1006
- /**
1007
- * 根据数据获取对应版本
1008
- * @return {[type]} [description]
1009
- */
1010
- QRCodeAlg.prototype.getRightType = function () {
1011
- for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1012
- var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]
1013
- if (rsBlock == undefined) {
1014
- throw new Error(
1015
- 'bad rs block @ typeNumber:' +
1006
+ /**
1007
+ * 根据数据获取对应版本
1008
+ * @return {[type]} [description]
1009
+ */
1010
+ QRCodeAlg.prototype.getRightType = function () {
1011
+ for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1012
+ var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]
1013
+ if (rsBlock == undefined) {
1014
+ throw new Error(
1015
+ 'bad rs block @ typeNumber:' +
1016
1016
  typeNumber +
1017
1017
  '/errorCorrectLevel:' +
1018
1018
  this.errorCorrectLevel
1019
- )
1020
- }
1021
- var length = rsBlock.length / 3
1022
- var totalDataCount = 0
1023
- for (var i = 0; i < length; i++) {
1024
- var count = rsBlock[i * 3 + 0]
1025
- var dataCount = rsBlock[i * 3 + 2]
1026
- totalDataCount += dataCount * count
1027
- }
1028
- var lengthBytes = typeNumber > 9 ? 2 : 1
1029
- if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
1030
- this.typeNumber = typeNumber
1031
- this.rsBlock = rsBlock
1032
- this.totalDataCount = totalDataCount
1033
- break
1019
+ )
1020
+ }
1021
+ var length = rsBlock.length / 3
1022
+ var totalDataCount = 0
1023
+ for (var i = 0; i < length; i++) {
1024
+ var count = rsBlock[i * 3 + 0]
1025
+ var dataCount = rsBlock[i * 3 + 2]
1026
+ totalDataCount += dataCount * count
1027
+ }
1028
+ var lengthBytes = typeNumber > 9 ? 2 : 1
1029
+ if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
1030
+ this.typeNumber = typeNumber
1031
+ this.rsBlock = rsBlock
1032
+ this.totalDataCount = totalDataCount
1033
+ break
1034
+ }
1034
1035
  }
1035
1036
  }
1036
- }
1037
1037
 
1038
- //---------------------------------------------------------------------
1039
- // QRBitBuffer
1040
- //---------------------------------------------------------------------
1041
- function QRBitBuffer() {
1042
- this.buffer = new Array()
1043
- this.length = 0
1044
- }
1045
- QRBitBuffer.prototype = {
1046
- get: function (index) {
1047
- var bufIndex = Math.floor(index / 8)
1048
- return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1
1049
- },
1050
- put: function (num, length) {
1051
- for (var i = 0; i < length; i++) {
1052
- this.putBit((num >>> (length - i - 1)) & 1)
1053
- }
1054
- },
1055
- putBit: function (bit) {
1056
- var bufIndex = Math.floor(this.length / 8)
1057
- if (this.buffer.length <= bufIndex) {
1058
- this.buffer.push(0)
1059
- }
1060
- if (bit) {
1061
- this.buffer[bufIndex] |= 0x80 >>> this.length % 8
1038
+ //---------------------------------------------------------------------
1039
+ // QRBitBuffer
1040
+ //---------------------------------------------------------------------
1041
+ function QRBitBuffer() {
1042
+ this.buffer = new Array()
1043
+ this.length = 0
1044
+ }
1045
+ QRBitBuffer.prototype = {
1046
+ get: function (index) {
1047
+ var bufIndex = Math.floor(index / 8)
1048
+ return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1
1049
+ },
1050
+ put: function (num, length) {
1051
+ for (var i = 0; i < length; i++) {
1052
+ this.putBit((num >>> (length - i - 1)) & 1)
1053
+ }
1054
+ },
1055
+ putBit: function (bit) {
1056
+ var bufIndex = Math.floor(this.length / 8)
1057
+ if (this.buffer.length <= bufIndex) {
1058
+ this.buffer.push(0)
1059
+ }
1060
+ if (bit) {
1061
+ this.buffer[bufIndex] |= 0x80 >>> this.length % 8
1062
+ }
1063
+ this.length++
1062
1064
  }
1063
- this.length++
1064
1065
  }
1065
- }
1066
1066
 
1067
- // xzedit
1068
- let qrcodeAlgObjCache = []
1069
- /**
1070
- * 二维码构造函数,主要用于绘制
1071
- * @param {参数列表} opt 传递参数
1072
- * @return {}
1073
- */
1074
- QRCode = function (opt) {
1075
- //设置默认参数
1076
- this.options = {
1077
- text: '',
1078
- size: 256,
1079
- correctLevel: 3,
1080
- background: '#ffffff',
1081
- foreground: '#000000',
1082
- pdground: '#000000',
1083
- image: '',
1084
- imageSize: 30,
1085
- canvasId: opt.canvasId,
1086
- nvueContext: opt.nvueContext,
1087
- context: opt.context,
1088
- usingComponents: opt.usingComponents,
1089
- showLoading: opt.showLoading,
1090
- loadingText: opt.loadingText
1091
- }
1092
- if (typeof opt === 'string') {
1093
- // 只编码ASCII字符串
1094
- opt = {
1095
- text: opt
1067
+ // xzedit
1068
+ let qrcodeAlgObjCache = []
1069
+ /**
1070
+ * 二维码构造函数,主要用于绘制
1071
+ * @param {参数列表} opt 传递参数
1072
+ * @return {}
1073
+ */
1074
+ QRCode = function (opt) {
1075
+ //设置默认参数
1076
+ this.options = {
1077
+ text: '',
1078
+ size: 256,
1079
+ correctLevel: 3,
1080
+ background: '#ffffff',
1081
+ foreground: '#000000',
1082
+ pdground: '#000000',
1083
+ image: '',
1084
+ imageSize: 30,
1085
+ canvasId: opt.canvasId,
1086
+ nvueContext: opt.nvueContext,
1087
+ context: opt.context,
1088
+ usingComponents: opt.usingComponents,
1089
+ showLoading: opt.showLoading,
1090
+ loadingText: opt.loadingText
1096
1091
  }
1097
- }
1098
- if (opt) {
1099
- for (var i in opt) {
1100
- this.options[i] = opt[i]
1092
+ if (typeof opt === 'string') {
1093
+ // 只编码ASCII字符串
1094
+ opt = {
1095
+ text: opt
1096
+ }
1101
1097
  }
1102
- }
1103
- //使用QRCodeAlg创建二维码结构
1104
- var qrCodeAlg = null
1105
- for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1106
- if (
1107
- qrcodeAlgObjCache[i].text == this.options.text &&
1108
- qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1109
- ) {
1110
- qrCodeAlg = qrcodeAlgObjCache[i].obj
1111
- break
1098
+ if (opt) {
1099
+ // 使用 Object.keys 避免遍历组件实例的原型链属性
1100
+ var keys = Object.keys(opt)
1101
+ for (var i = 0; i < keys.length; i++) {
1102
+ var key = keys[i]
1103
+ this.options[key] = opt[key]
1104
+ }
1112
1105
  }
1113
- }
1114
- if (i == l) {
1115
- qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel)
1116
- qrcodeAlgObjCache.push({
1117
- text: this.options.text,
1118
- correctLevel: this.options.correctLevel,
1119
- obj: qrCodeAlg
1120
- })
1121
- }
1122
- /**
1123
- * 计算矩阵点的前景色
1124
- * @param {Obj} config
1125
- * @param {Number} config.row 点x坐标
1126
- * @param {Number} config.col 点y坐标
1127
- * @param {Number} config.count 矩阵大小
1128
- * @param {Number} config.options 组件的options
1129
- * @return {String}
1130
- */
1131
- let getForeGround = function (config) {
1132
- var options = config.options
1133
- if (
1134
- options.pdground &&
1135
- ((config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1136
- (config.row > config.count - 6 &&
1137
- config.row < config.count - 2 &&
1138
- config.col > 1 &&
1139
- config.col < 5) ||
1140
- (config.row > 1 &&
1141
- config.row < 5 &&
1142
- config.col > config.count - 6 &&
1143
- config.col < config.count - 2))
1144
- ) {
1145
- return options.pdground
1106
+ //使用QRCodeAlg创建二维码结构
1107
+ var qrCodeAlg = null
1108
+ for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1109
+ if (
1110
+ qrcodeAlgObjCache[i].text == this.options.text &&
1111
+ qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1112
+ ) {
1113
+ qrCodeAlg = qrcodeAlgObjCache[i].obj
1114
+ break
1115
+ }
1146
1116
  }
1147
- return options.foreground
1148
- }
1149
- // 创建canvas
1150
- let createCanvas = function (options) {
1151
- if (options.showLoading) {
1152
- uni.showLoading({
1153
- title: options.loadingText,
1154
- mask: true
1117
+ if (i == l) {
1118
+ qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel)
1119
+ qrcodeAlgObjCache.push({
1120
+ text: this.options.text,
1121
+ correctLevel: this.options.correctLevel,
1122
+ obj: qrCodeAlg
1155
1123
  })
1156
1124
  }
1157
- var ctx = ''
1158
- if (options.nvueContext) {
1159
- ctx = options.nvueContext
1160
- } else {
1161
- ctx = uni.createCanvasContext(options.canvasId, options.context)
1125
+ /**
1126
+ * 计算矩阵点的前景色
1127
+ * @param {Obj} config
1128
+ * @param {Number} config.row 点x坐标
1129
+ * @param {Number} config.col 点y坐标
1130
+ * @param {Number} config.count 矩阵大小
1131
+ * @param {Number} config.options 组件的options
1132
+ * @return {String}
1133
+ */
1134
+ let getForeGround = function (config) {
1135
+ var options = config.options
1136
+ if (
1137
+ options.pdground &&
1138
+ ((config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1139
+ (config.row > config.count - 6 &&
1140
+ config.row < config.count - 2 &&
1141
+ config.col > 1 &&
1142
+ config.col < 5) ||
1143
+ (config.row > 1 &&
1144
+ config.row < 5 &&
1145
+ config.col > config.count - 6 &&
1146
+ config.col < config.count - 2))
1147
+ ) {
1148
+ return options.pdground
1149
+ }
1150
+ return options.foreground
1162
1151
  }
1163
- var count = qrCodeAlg.getModuleCount()
1164
- var ratioSize = options.size
1165
- var ratioImgSize = options.imageSize
1166
- //计算每个点的长宽
1167
- var tileW = (ratioSize / count).toPrecision(4)
1168
- var tileH = (ratioSize / count).toPrecision(4)
1169
- //绘制
1170
- for (var row = 0; row < count; row++) {
1171
- for (var col = 0; col < count; col++) {
1172
- var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
1173
- var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
1174
- var foreground = getForeGround({
1175
- row: row,
1176
- col: col,
1177
- count: count,
1178
- options: options
1152
+ // 创建canvas
1153
+ let createCanvas = function (options) {
1154
+ if (options.showLoading) {
1155
+ uni.showLoading({
1156
+ title: options.loadingText,
1157
+ mask: true
1179
1158
  })
1180
- ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background)
1181
- ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
1182
1159
  }
1183
- }
1184
- if (options.image) {
1185
- var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1186
- var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1187
- drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1188
- ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize)
1189
- // 画圆角矩形
1190
- function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1191
- ctxi.setLineWidth(lineWidth)
1192
- ctxi.setFillStyle(options.background)
1193
- ctxi.setStrokeStyle(options.background)
1194
- ctxi.beginPath() // draw top and top right corner
1195
- ctxi.moveTo(x + r, y)
1196
- ctxi.arcTo(x + width, y, x + width, y + r, r) // draw right side and bottom right corner
1197
- ctxi.arcTo(x + width, y + height, x + width - r, y + height, r) // draw bottom and bottom left corner
1198
- ctxi.arcTo(x, y + height, x, y + height - r, r) // draw left and top left corner
1199
- ctxi.arcTo(x, y, x + r, y, r)
1200
- ctxi.closePath()
1201
- if (fill) {
1202
- ctxi.fill()
1160
+ var ctx = ''
1161
+ if (options.nvueContext) {
1162
+ ctx = options.nvueContext
1163
+ } else {
1164
+ // #ifdef MP-ALIPAY
1165
+ // 支付宝小程序不传递context参数,避免遍历组件实例属性
1166
+ ctx = uni.createCanvasContext(options.canvasId)
1167
+ // #else
1168
+ ctx = uni.createCanvasContext(options.canvasId, options.context)
1169
+ // #endif
1170
+ }
1171
+ var count = qrCodeAlg.getModuleCount()
1172
+ var ratioSize = options.size
1173
+ var ratioImgSize = options.imageSize
1174
+ //计算每个点的长宽
1175
+ var tileW = (ratioSize / count).toPrecision(4)
1176
+ var tileH = (ratioSize / count).toPrecision(4)
1177
+ //绘制
1178
+ for (var row = 0; row < count; row++) {
1179
+ for (var col = 0; col < count; col++) {
1180
+ var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
1181
+ var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
1182
+ var foreground = getForeGround({
1183
+ row: row,
1184
+ col: col,
1185
+ count: count,
1186
+ options: options
1187
+ })
1188
+ ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background)
1189
+ ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
1203
1190
  }
1204
- if (stroke) {
1205
- ctxi.stroke()
1191
+ }
1192
+ if (options.image) {
1193
+ var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1194
+ var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1195
+ drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1196
+ ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize)
1197
+ // 画圆角矩形
1198
+ function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1199
+ ctxi.setLineWidth(lineWidth)
1200
+ ctxi.setFillStyle(options.background)
1201
+ ctxi.setStrokeStyle(options.background)
1202
+ ctxi.beginPath() // draw top and top right corner
1203
+ ctxi.moveTo(x + r, y)
1204
+ ctxi.arcTo(x + width, y, x + width, y + r, r) // draw right side and bottom right corner
1205
+ ctxi.arcTo(x + width, y + height, x + width - r, y + height, r) // draw bottom and bottom left corner
1206
+ ctxi.arcTo(x, y + height, x, y + height - r, r) // draw left and top left corner
1207
+ ctxi.arcTo(x, y, x + r, y, r)
1208
+ ctxi.closePath()
1209
+ if (fill) {
1210
+ ctxi.fill()
1211
+ }
1212
+ if (stroke) {
1213
+ ctxi.stroke()
1214
+ }
1206
1215
  }
1207
1216
  }
1208
- }
1209
- setTimeout(
1210
- () => {
1211
- ctx.draw(true, () => {
1212
- // 保存到临时区域
1213
- setTimeout(() => {
1214
- if (options.nvueContext) {
1215
- ctx.toTempFilePath(
1216
- 0,
1217
- 0,
1218
- options.width,
1219
- options.height,
1220
- options.width,
1221
- options.height,
1222
- '',
1223
- 1,
1224
- function (res) {
1225
- if (options.cbResult) {
1226
- options.cbResult(res.tempFilePath)
1217
+ setTimeout(
1218
+ () => {
1219
+ ctx.draw(true, () => {
1220
+ // 保存到临时区域
1221
+ setTimeout(() => {
1222
+ if (options.nvueContext) {
1223
+ ctx.toTempFilePath(
1224
+ 0,
1225
+ 0,
1226
+ options.width,
1227
+ options.height,
1228
+ options.width,
1229
+ options.height,
1230
+ '',
1231
+ 1,
1232
+ function (res) {
1233
+ if (options.cbResult) {
1234
+ options.cbResult(res.tempFilePath)
1235
+ }
1227
1236
  }
1228
- }
1229
- )
1230
- } else {
1231
- uni.canvasToTempFilePath(
1232
- {
1237
+ )
1238
+ } else {
1239
+ // #ifdef MP-ALIPAY
1240
+ // 支付宝小程序不传递context参数,避免遍历组件实例属性
1241
+ uni.canvasToTempFilePath({
1233
1242
  width: options.width,
1234
1243
  height: options.height,
1235
1244
  destWidth: options.width,
@@ -1238,11 +1247,11 @@ let QRCode = {}
1238
1247
  quality: Number(1),
1239
1248
  success: function (res) {
1240
1249
  if (options.cbResult) {
1241
- // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1242
- if (!empty(res.tempFilePath)) {
1243
- options.cbResult(res.tempFilePath)
1244
- } else if (!empty(res.apFilePath)) {
1250
+ // 支付宝为 res.apFilePath
1251
+ if (!empty(res.apFilePath)) {
1245
1252
  options.cbResult(res.apFilePath)
1253
+ } else if (!empty(res.tempFilePath)) {
1254
+ options.cbResult(res.tempFilePath)
1246
1255
  } else {
1247
1256
  options.cbResult(res.tempFilePath)
1248
1257
  }
@@ -1256,49 +1265,80 @@ let QRCode = {}
1256
1265
  complete: function () {
1257
1266
  uni.hideLoading()
1258
1267
  }
1259
- },
1260
- options.context
1261
- )
1262
- }
1263
- }, options.text.length + 100)
1264
- })
1265
- },
1266
- options.usingComponents ? 0 : 150
1267
- )
1268
- }
1269
- createCanvas(this.options)
1270
- // 空判定
1271
- let empty = function (v) {
1272
- let tp = typeof v,
1273
- rt = false
1274
- if (tp == 'number' && String(v) == '') {
1275
- rt = true
1276
- } else if (tp == 'undefined') {
1277
- rt = true
1278
- } else if (tp == 'object') {
1279
- if (JSON.stringify(v) == '{}' || JSON.stringify(v) == '[]' || v == null) rt = true
1280
- } else if (tp == 'string') {
1281
- if (v == '' || v == 'undefined' || v == 'null' || v == '{}' || v == '[]') rt = true
1282
- } else if (tp == 'function') {
1283
- rt = false
1268
+ })
1269
+ // #else
1270
+ uni.canvasToTempFilePath(
1271
+ {
1272
+ width: options.width,
1273
+ height: options.height,
1274
+ destWidth: options.width,
1275
+ destHeight: options.height,
1276
+ canvasId: options.canvasId,
1277
+ quality: Number(1),
1278
+ success: function (res) {
1279
+ if (options.cbResult) {
1280
+ // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1281
+ if (!empty(res.tempFilePath)) {
1282
+ options.cbResult(res.tempFilePath)
1283
+ } else if (!empty(res.apFilePath)) {
1284
+ options.cbResult(res.apFilePath)
1285
+ } else {
1286
+ options.cbResult(res.tempFilePath)
1287
+ }
1288
+ }
1289
+ },
1290
+ fail: function (res) {
1291
+ if (options.cbResult) {
1292
+ options.cbResult(res)
1293
+ }
1294
+ },
1295
+ complete: function () {
1296
+ uni.hideLoading()
1297
+ }
1298
+ },
1299
+ options.context
1300
+ )
1301
+ // #endif
1302
+ }
1303
+ }, options.text.length + 100)
1304
+ })
1305
+ },
1306
+ options.usingComponents ? 0 : 150
1307
+ )
1308
+ }
1309
+ createCanvas(this.options)
1310
+ // 空判定
1311
+ let empty = function (v) {
1312
+ let tp = typeof v,
1313
+ rt = false
1314
+ if (tp == 'number' && String(v) == '') {
1315
+ rt = true
1316
+ } else if (tp == 'undefined') {
1317
+ rt = true
1318
+ } else if (tp == 'object') {
1319
+ if (JSON.stringify(v) == '{}' || JSON.stringify(v) == '[]' || v == null) rt = true
1320
+ } else if (tp == 'string') {
1321
+ if (v == '' || v == 'undefined' || v == 'null' || v == '{}' || v == '[]') rt = true
1322
+ } else if (tp == 'function') {
1323
+ rt = false
1324
+ }
1325
+ return rt
1284
1326
  }
1285
- return rt
1286
- }
1287
- }
1288
- QRCode.prototype.clear = function (fn) {
1289
- var ctx = ''
1290
- if (options.nvueContext) {
1291
- ctx = options.nvueContext
1292
- } else {
1293
- uni.createCanvasContext(this.options.canvasId, this.options.context)
1294
1327
  }
1295
- ctx.clearRect(0, 0, this.options.size, this.options.size)
1296
- ctx.draw(false, () => {
1297
- if (fn) {
1298
- fn()
1328
+ QRCode.prototype.clear = function (fn) {
1329
+ var ctx = ''
1330
+ if (options.nvueContext) {
1331
+ ctx = options.nvueContext
1332
+ } else {
1333
+ uni.createCanvasContext(this.options.canvasId, this.options.context)
1299
1334
  }
1300
- })
1301
- }
1302
- })()
1335
+ ctx.clearRect(0, 0, this.options.size, this.options.size)
1336
+ ctx.draw(false, () => {
1337
+ if (fn) {
1338
+ fn()
1339
+ }
1340
+ })
1341
+ }
1342
+ })()
1303
1343
 
1304
1344
  export default QRCode