rqrcode_core 0.1.0

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.
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRMath
5
+ module_eval {
6
+ exp_table = Array.new(256)
7
+ log_table = Array.new(256)
8
+
9
+ ( 0...8 ).each do |i|
10
+ exp_table[i] = 1 << i
11
+ end
12
+
13
+ ( 8...256 ).each do |i|
14
+ exp_table[i] = exp_table[i - 4] \
15
+ ^ exp_table[i - 5] \
16
+ ^ exp_table[i - 6] \
17
+ ^ exp_table[i - 8]
18
+ end
19
+
20
+ ( 0...255 ).each do |i|
21
+ log_table[exp_table[i] ] = i
22
+ end
23
+
24
+ EXP_TABLE = exp_table
25
+ LOG_TABLE = log_table
26
+ }
27
+
28
+ class << self
29
+ def glog(n)
30
+ raise QRCodeRunTimeError, "glog(#{n})" if ( n < 1 )
31
+ LOG_TABLE[n]
32
+ end
33
+
34
+
35
+ def gexp(n)
36
+ while n < 0
37
+ n = n + 255
38
+ end
39
+
40
+ while n >= 256
41
+ n = n - 255
42
+ end
43
+
44
+ EXP_TABLE[n]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ NUMERIC = ['0','1','2','3','4','5','6','7','8','9'].freeze
5
+
6
+ class QRNumeric
7
+ attr_reader :mode
8
+
9
+ def initialize( data )
10
+ @mode = QRMODE[:mode_number]
11
+
12
+ raise QRCodeArgumentError, "Not a numeric string `#{data}`" unless QRNumeric.valid_data?(data)
13
+
14
+ @data = data;
15
+ end
16
+
17
+ def get_length
18
+ @data.size
19
+ end
20
+
21
+ def self.valid_data? data
22
+ data.each_char do |s|
23
+ return false if NUMERIC.index(s).nil?
24
+ end
25
+ true
26
+ end
27
+
28
+ def write( buffer)
29
+ buffer.numeric_encoding_start(get_length)
30
+
31
+ (@data.size).times do |i|
32
+ if i % 3 == 0
33
+ chars = @data[i, 3]
34
+ bit_length = get_bit_length(chars.length)
35
+ buffer.put( get_code(chars), bit_length )
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ NUMBER_LENGTH = {
43
+ 3 => 10,
44
+ 2 => 7,
45
+ 1 => 4
46
+ }.freeze
47
+
48
+ def get_bit_length(length)
49
+ NUMBER_LENGTH[length]
50
+ end
51
+
52
+ def get_code(chars)
53
+ chars.to_i
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRPolynomial
5
+ def initialize( num, shift )
6
+ raise QRCodeRunTimeError, "#{num.size}/#{shift}" if num.empty?
7
+ offset = 0
8
+
9
+ while offset < num.size && num[offset] == 0
10
+ offset = offset + 1
11
+ end
12
+
13
+ @num = Array.new( num.size - offset + shift )
14
+
15
+ ( 0...num.size - offset ).each do |i|
16
+ @num[i] = num[i + offset]
17
+ end
18
+ end
19
+
20
+ def get( index )
21
+ @num[index]
22
+ end
23
+
24
+ def get_length
25
+ @num.size
26
+ end
27
+
28
+ def multiply( e )
29
+ num = Array.new( get_length + e.get_length - 1 )
30
+
31
+ ( 0...get_length ).each do |i|
32
+ ( 0...e.get_length ).each do |j|
33
+ tmp = num[i + j].nil? ? 0 : num[i + j]
34
+ num[i + j] = tmp ^ QRMath.gexp(QRMath.glog( get(i) ) + QRMath.glog(e.get(j)))
35
+ end
36
+ end
37
+
38
+ return QRPolynomial.new( num, 0 )
39
+ end
40
+
41
+ def mod( e )
42
+ if get_length - e.get_length < 0
43
+ return self
44
+ end
45
+
46
+ ratio = QRMath.glog(get(0)) - QRMath.glog(e.get(0))
47
+ num = Array.new(get_length)
48
+
49
+ ( 0...get_length ).each do |i|
50
+ num[i] = get(i)
51
+ end
52
+
53
+ ( 0...e.get_length ).each do |i|
54
+ tmp = num[i].nil? ? 0 : num[i]
55
+ num[i] = tmp ^ QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
56
+ end
57
+
58
+ return QRPolynomial.new( num, 0 ).mod(e)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,300 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRRSBlock
5
+ attr_reader :data_count, :total_count
6
+
7
+ def initialize( total_count, data_count )
8
+ @total_count = total_count
9
+ @data_count = data_count
10
+ end
11
+
12
+ # http://www.thonky.com/qr-code-tutorial/error-correction-table/
13
+ RQRCodeCore::QRRSBlock::RS_BLOCK_TABLE = [
14
+ # L
15
+ # M
16
+ # Q
17
+ # H
18
+
19
+ # 1
20
+ [1, 26, 19],
21
+ [1, 26, 16],
22
+ [1, 26, 13],
23
+ [1, 26, 9],
24
+
25
+ # 2
26
+ [1, 44, 34],
27
+ [1, 44, 28],
28
+ [1, 44, 22],
29
+ [1, 44, 16],
30
+
31
+ # 3
32
+ [1, 70, 55],
33
+ [1, 70, 44],
34
+ [2, 35, 17],
35
+ [2, 35, 13],
36
+
37
+ # 4
38
+ [1, 100, 80],
39
+ [2, 50, 32],
40
+ [2, 50, 24],
41
+ [4, 25, 9],
42
+
43
+ # 5
44
+ [1, 134, 108],
45
+ [2, 67, 43],
46
+ [2, 33, 15, 2, 34, 16],
47
+ [2, 33, 11, 2, 34, 12],
48
+
49
+ # 6
50
+ [2, 86, 68],
51
+ [4, 43, 27],
52
+ [4, 43, 19],
53
+ [4, 43, 15],
54
+
55
+ # 7
56
+ [2, 98, 78],
57
+ [4, 49, 31],
58
+ [2, 32, 14, 4, 33, 15],
59
+ [4, 39, 13, 1, 40, 14],
60
+
61
+ # 8
62
+ [2, 121, 97],
63
+ [2, 60, 38, 2, 61, 39],
64
+ [4, 40, 18, 2, 41, 19],
65
+ [4, 40, 14, 2, 41, 15],
66
+
67
+ # 9
68
+ [2, 146, 116],
69
+ [3, 58, 36, 2, 59, 37],
70
+ [4, 36, 16, 4, 37, 17],
71
+ [4, 36, 12, 4, 37, 13],
72
+
73
+ # 10
74
+ [2, 86, 68, 2, 87, 69],
75
+ [4, 69, 43, 1, 70, 44],
76
+ [6, 43, 19, 2, 44, 20],
77
+ [6, 43, 15, 2, 44, 16],
78
+
79
+ # 11
80
+ [4, 101, 81],
81
+ [1, 80, 50, 4, 81, 51],
82
+ [4, 50, 22, 4, 51, 23],
83
+ [3, 36, 12, 8, 37, 13],
84
+
85
+ # 12
86
+ [2, 116, 92, 2, 117, 93],
87
+ [6, 58, 36, 2, 59, 37],
88
+ [4, 46, 20, 6, 47, 21],
89
+ [7, 42, 14, 4, 43, 15],
90
+
91
+ # 13
92
+ [4, 133, 107],
93
+ [8, 59, 37, 1, 60, 38],
94
+ [8, 44, 20, 4, 45, 21],
95
+ [12, 33, 11, 4, 34, 12],
96
+
97
+ # 14
98
+ [3, 145, 115, 1, 146, 116],
99
+ [4, 64, 40, 5, 65, 41],
100
+ [11, 36, 16, 5, 37, 17],
101
+ [11, 36, 12, 5, 37, 13],
102
+
103
+ # 15
104
+ [5, 109, 87, 1, 110, 88],
105
+ [5, 65, 41, 5, 66, 42],
106
+ [5, 54, 24, 7, 55, 25],
107
+ [11, 36, 12, 7, 37, 13],
108
+
109
+ # 16
110
+ [5, 122, 98, 1, 123, 99],
111
+ [7, 73, 45, 3, 74, 46],
112
+ [15, 43, 19, 2, 44, 20],
113
+ [3, 45, 15, 13, 46, 16],
114
+
115
+ # 17
116
+ [1, 135, 107, 5, 136, 108],
117
+ [10, 74, 46, 1, 75, 47],
118
+ [1, 50, 22, 15, 51, 23],
119
+ [2, 42, 14, 17, 43, 15],
120
+
121
+ # 18
122
+ [5, 150, 120, 1, 151, 121],
123
+ [9, 69, 43, 4, 70, 44],
124
+ [17, 50, 22, 1, 51, 23],
125
+ [2, 42, 14, 19, 43, 15],
126
+
127
+ # 19
128
+ [3, 141, 113, 4, 142, 114],
129
+ [3, 70, 44, 11, 71, 45],
130
+ [17, 47, 21, 4, 48, 22],
131
+ [9, 39, 13, 16, 40, 14],
132
+
133
+ # 20
134
+ [3, 135, 107, 5, 136, 108],
135
+ [3, 67, 41, 13, 68, 42],
136
+ [15, 54, 24, 5, 55, 25],
137
+ [15, 43, 15, 10, 44, 16],
138
+
139
+ # 21
140
+ [4, 144, 116, 4, 145, 117],
141
+ [17, 68, 42],
142
+ [17, 50, 22, 6, 51, 23],
143
+ [19, 46, 16, 6, 47, 17],
144
+
145
+ # 22
146
+ [2, 139, 111, 7, 140, 112],
147
+ [17, 74, 46],
148
+ [7, 54, 24, 16, 55, 25],
149
+ [34, 37, 13],
150
+
151
+ # 23
152
+ [4, 151, 121, 5, 152, 122],
153
+ [4, 75, 47, 14, 76, 48],
154
+ [11, 54, 24, 14, 55, 25],
155
+ [16, 45, 15, 14, 46, 16],
156
+
157
+ # 24
158
+ [6, 147, 117, 4, 148, 118],
159
+ [6, 73, 45, 14, 74, 46],
160
+ [11, 54, 24, 16, 55, 25],
161
+ [30, 46, 16, 2, 47, 17],
162
+
163
+ # 25
164
+ [8, 132, 106, 4, 133, 107],
165
+ [8, 75, 47, 13, 76, 48],
166
+ [7, 54, 24, 22, 55, 25],
167
+ [22, 45, 15, 13, 46, 16],
168
+
169
+ # 26
170
+ [10, 142, 114, 2, 143, 115],
171
+ [19, 74, 46, 4, 75, 47],
172
+ [28, 50, 22, 6, 51, 23],
173
+ [33, 46, 16, 4, 47, 17],
174
+
175
+ # 27
176
+ [8, 152, 122, 4, 153, 123],
177
+ [22, 73, 45, 3, 74, 46],
178
+ [8, 53, 23, 26, 54, 24],
179
+ [12, 45, 15, 28, 46, 16],
180
+
181
+ # 28
182
+ [3, 147, 117, 10, 148, 118],
183
+ [3, 73, 45, 23, 74, 46],
184
+ [4, 54, 24, 31, 55, 25],
185
+ [11, 45, 15, 31, 46, 16],
186
+
187
+ # 29
188
+ [7, 146, 116, 7, 147, 117],
189
+ [21, 73, 45, 7, 74, 46],
190
+ [1, 53, 23, 37, 54, 24],
191
+ [19, 45, 15, 26, 46, 16],
192
+
193
+ # 30
194
+ [5, 145, 115, 10, 146, 116],
195
+ [19, 75, 47, 10, 76, 48],
196
+ [15, 54, 24, 25, 55, 25],
197
+ [23, 45, 15, 25, 46, 16],
198
+
199
+ # 31
200
+ [13, 145, 115, 3, 146, 116],
201
+ [2, 74, 46, 29, 75, 47],
202
+ [42, 54, 24, 1, 55, 25],
203
+ [23, 45, 15, 28, 46, 16],
204
+
205
+ # 32
206
+ [17, 145, 115],
207
+ [10, 74, 46, 23, 75, 47],
208
+ [10, 54, 24, 35, 55, 25],
209
+ [19, 45, 15, 35, 46, 16],
210
+
211
+ # 33
212
+ [17, 145, 115, 1, 146, 116],
213
+ [14, 74, 46, 21, 75, 47],
214
+ [29, 54, 24, 19, 55, 25],
215
+ [11, 45, 15, 46, 46, 16],
216
+
217
+ # 34
218
+ [13, 145, 115, 6, 146, 116],
219
+ [14, 74, 46, 23, 75, 47],
220
+ [44, 54, 24, 7, 55, 25],
221
+ [59, 46, 16, 1, 47, 17],
222
+
223
+ # 35
224
+ [12, 151, 121, 7, 152, 122],
225
+ [12, 75, 47, 26, 76, 48],
226
+ [39, 54, 24, 14, 55, 25],
227
+ [22, 45, 15, 41, 46, 16],
228
+
229
+ # 36
230
+ [6, 151, 121, 14, 152, 122],
231
+ [6, 75, 47, 34, 76, 48],
232
+ [46, 54, 24, 10, 55, 25],
233
+ [2, 45, 15, 64, 46, 16],
234
+
235
+ # 37
236
+ [17, 152, 122, 4, 153, 123],
237
+ [29, 74, 46, 14, 75, 47],
238
+ [49, 54, 24, 10, 55, 25],
239
+ [24, 45, 15, 46, 46, 16],
240
+
241
+ # 38
242
+ [4, 152, 122, 18, 153, 123],
243
+ [13, 74, 46, 32, 75, 47],
244
+ [48, 54, 24, 14, 55, 25],
245
+ [42, 45, 15, 32, 46, 16],
246
+
247
+ # 39
248
+ [20, 147, 117, 4, 148, 118],
249
+ [40, 75, 47, 7, 76, 48],
250
+ [43, 54, 24, 22, 55, 25],
251
+ [10, 45, 15, 67, 46, 16],
252
+
253
+ # 40
254
+ [19, 148, 118, 6, 149, 119],
255
+ [18, 75, 47, 31, 76, 48],
256
+ [34, 54, 24, 34, 55, 25],
257
+ [20, 45, 15, 61, 46, 16]
258
+
259
+ ]
260
+
261
+ def QRRSBlock.get_rs_blocks(version, error_correct_level)
262
+ rs_block = QRRSBlock.get_rs_block_table(version, error_correct_level)
263
+
264
+ if rs_block.nil?
265
+ raise QRCodeRunTimeError,
266
+ "bad rsblock @ version: #{version}/error_correct_level:#{error_correct_level}"
267
+ end
268
+
269
+ length = rs_block.size / 3
270
+ list = []
271
+
272
+ ( 0...length ).each do |i|
273
+ count = rs_block[i * 3 + 0]
274
+ total_count = rs_block[i * 3 + 1]
275
+ data_count = rs_block[i * 3 + 2]
276
+
277
+ ( 0...count ).each do |j|
278
+ list << QRRSBlock.new( total_count, data_count )
279
+ end
280
+ end
281
+
282
+ list
283
+ end
284
+
285
+ def QRRSBlock.get_rs_block_table(version, error_correct_level)
286
+ case error_correct_level
287
+ when QRERRORCORRECTLEVEL[:l]
288
+ QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 0]
289
+ when QRERRORCORRECTLEVEL[:m]
290
+ QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 1]
291
+ when QRERRORCORRECTLEVEL[:q]
292
+ QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 2]
293
+ when QRERRORCORRECTLEVEL[:h]
294
+ QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 3]
295
+ else
296
+ nil
297
+ end
298
+ end
299
+ end
300
+ end