qrest 1.0.1 → 1.0.2
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.
- checksums.yaml +4 -4
- data/lib/qrest/demerits.rb +3 -1
- data/lib/qrest/modules.rb +77 -68
- data/lib/qrest/rsblocks.rb +117 -109
- data/lib/qrest/segment.rb +27 -14
- data/lib/qrest/version.rb +1 -1
- data/lib/qrest.rb +12 -14
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2490fb27884f2ab7c5172782a898c7b20f4c77709a3c1846a8af68c6d6133cb3
|
|
4
|
+
data.tar.gz: b80229455a23a9176cd0c4f0b34c0cc56fd95c5e91303f881d08b8310ae2495d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e803f95b2ca0fbb93f21b5f00e750dca32672ee4fd7f658cac78feebf178b839984f6fcf4483bef180e5f89650b0472faa0b5e174e78da3cc8fbdbdd5c9ee18e
|
|
7
|
+
data.tar.gz: 3c41ee417fbd90787886ee4f492f8737f06f63c71d7b6f0333133c5675313dcbb9d7d6f8773dd47ae50528564ab14eb3abd79fd51ac341800c7f1715fa13cfe4
|
data/lib/qrest/demerits.rb
CHANGED
|
@@ -16,7 +16,8 @@ module QRest
|
|
|
16
16
|
def total **weigths
|
|
17
17
|
weigths.inject 0 do |sum,(k,v)|
|
|
18
18
|
e = ([*(send k)].zip [*v]).inject 0 do |s,(r,f)| s += r*f end
|
|
19
|
-
|
|
19
|
+
puts [k, v, e.class, e, e.round].inspect
|
|
20
|
+
sum + e.round
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -107,6 +108,7 @@ module QRest
|
|
|
107
108
|
|
|
108
109
|
|
|
109
110
|
def dark_ratio
|
|
111
|
+
puts @fields.inspect
|
|
110
112
|
dark = @fields.sum do |col| col.count true end
|
|
111
113
|
all = @fields.size*@fields.size
|
|
112
114
|
(dark.to_f / all - 0.5).abs * 100
|
data/lib/qrest/modules.rb
CHANGED
|
@@ -12,6 +12,8 @@ module QRest
|
|
|
12
12
|
|
|
13
13
|
class Modules
|
|
14
14
|
|
|
15
|
+
VERSIONS = 1..40
|
|
16
|
+
|
|
15
17
|
POSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
|
|
16
18
|
|
|
17
19
|
ERRORCORRECTLEVEL = { l: 1, m: 0, q: 3, h: 2 }
|
|
@@ -38,7 +40,7 @@ module QRest
|
|
|
38
40
|
proc { |i,j| ((i * j) % 3 + (i + j) % 2) % 2 },
|
|
39
41
|
]
|
|
40
42
|
|
|
41
|
-
attr_reader :version, :count, :fields
|
|
43
|
+
attr_reader :version, :count, :fields
|
|
42
44
|
|
|
43
45
|
class <<self
|
|
44
46
|
|
|
@@ -49,31 +51,30 @@ module QRest
|
|
|
49
51
|
dark_ratio: 2,
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
def create_best data
|
|
53
|
-
demerits, pattern = nil,
|
|
54
|
+
def create_best data
|
|
55
|
+
demerits, pattern = nil, nil
|
|
54
56
|
MASK_PATTERNS.length.times { |i|
|
|
55
|
-
|
|
56
|
-
d =
|
|
57
|
-
demerits, pattern = d, i if not
|
|
57
|
+
t = ModulesTest.new data, i
|
|
58
|
+
d = t.demerits.total **WEIGHTS
|
|
59
|
+
demerits, pattern = d, i if not pattern or demerits > d
|
|
58
60
|
}
|
|
59
|
-
new data,
|
|
61
|
+
new data, pattern
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
def initialize data,
|
|
65
|
-
count = version * 4 + POSITIONPATTERNLENGTH
|
|
66
|
+
def initialize data, mask_pattern
|
|
67
|
+
count = data.version * 4 + POSITIONPATTERNLENGTH
|
|
66
68
|
@fields = Array.new count do Array.new count end
|
|
67
69
|
place_position_probe_pattern 0, 0
|
|
68
70
|
place_position_probe_pattern @fields.size - 7, 0
|
|
69
71
|
place_position_probe_pattern 0, @fields.size - 7
|
|
70
|
-
place_position_adjust_pattern
|
|
72
|
+
place_position_adjust_pattern @fields.size
|
|
71
73
|
place_timing_pattern
|
|
72
|
-
place_format_info
|
|
73
|
-
place_version_info version
|
|
74
|
-
bs = BitStream.new data
|
|
74
|
+
place_format_info (ERRORCORRECTLEVEL[data.error_correct_level]<<3) | mask_pattern
|
|
75
|
+
place_version_info data.version
|
|
76
|
+
bs = BitStream.new data.data
|
|
75
77
|
walk_fields mask_pattern do bs.get end
|
|
76
|
-
@demerits = Demerits.new @fields if test
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
def inspect
|
|
@@ -165,58 +166,47 @@ module QRest
|
|
|
165
166
|
end
|
|
166
167
|
end
|
|
167
168
|
|
|
168
|
-
PATTERN_POSITION_TABLE = [
|
|
169
|
-
[],
|
|
170
|
-
[6, 18],
|
|
171
|
-
[6, 22],
|
|
172
|
-
[6, 26],
|
|
173
|
-
[6, 30],
|
|
174
|
-
[6, 34],
|
|
175
|
-
[6, 22, 38],
|
|
176
|
-
[6, 24, 42],
|
|
177
|
-
[6, 26, 46],
|
|
178
|
-
[6, 28, 50],
|
|
179
|
-
[6, 30, 54],
|
|
180
|
-
[6, 32, 58],
|
|
181
|
-
[6, 34, 62],
|
|
182
|
-
[6, 26, 46, 66],
|
|
183
|
-
[6, 26, 48, 70],
|
|
184
|
-
[6, 26, 50, 74],
|
|
185
|
-
[6, 30, 54, 78],
|
|
186
|
-
[6, 30, 56, 82],
|
|
187
|
-
[6, 30, 58, 86],
|
|
188
|
-
[6, 34, 62, 90],
|
|
189
|
-
[6, 28, 50, 72, 94],
|
|
190
|
-
[6, 26, 50, 74, 98],
|
|
191
|
-
[6, 30, 54, 78, 102],
|
|
192
|
-
[6, 28, 54, 80, 106],
|
|
193
|
-
[6, 32, 58, 84, 110],
|
|
194
|
-
[6, 30, 58, 86, 114],
|
|
195
|
-
[6, 34, 62, 90, 118],
|
|
196
|
-
[6, 26, 50, 74, 98, 122],
|
|
197
|
-
[6, 30, 54, 78, 102, 126],
|
|
198
|
-
[6, 26, 52, 78, 104, 130],
|
|
199
|
-
[6, 30, 56, 82, 108, 134],
|
|
200
|
-
[6, 34, 60, 86, 112, 138],
|
|
201
|
-
[6, 30, 58, 86, 114, 142],
|
|
202
|
-
[6, 34, 62, 90, 118, 146],
|
|
203
|
-
[6, 30, 54, 78, 102, 126, 150],
|
|
204
|
-
[6, 24, 50, 76, 102, 128, 154],
|
|
205
|
-
[6, 28, 54, 80, 106, 132, 158],
|
|
206
|
-
[6, 32, 58, 84, 110, 136, 162],
|
|
207
|
-
[6, 26, 54, 82, 110, 138, 166],
|
|
208
|
-
[6, 30, 58, 86, 114, 142, 170]
|
|
209
|
-
]
|
|
210
169
|
|
|
211
|
-
|
|
170
|
+
@adjust_pattern = {}
|
|
171
|
+
|
|
172
|
+
class <<self
|
|
173
|
+
|
|
174
|
+
ADJUST_FIRST = 6
|
|
175
|
+
def adjust_pattern_pos size
|
|
176
|
+
@adjust_pattern[ size] ||= begin
|
|
177
|
+
s = size - ADJUST_FIRST*2 - 1
|
|
178
|
+
if s < ADJUST_FIRST*2 then
|
|
179
|
+
[]
|
|
180
|
+
else
|
|
181
|
+
kat = (s-1)/28
|
|
182
|
+
ds = [ 0]
|
|
183
|
+
case kat
|
|
184
|
+
when 0 then ds.push s
|
|
185
|
+
when 1 then h = s / 2 ; ds.push h, h
|
|
186
|
+
else
|
|
187
|
+
28.step 20, -2 do |h|
|
|
188
|
+
m = s - kat*h
|
|
189
|
+
if m > h - [kat,3].max*2 then
|
|
190
|
+
ds.push m, *([ h] * kat)
|
|
191
|
+
break
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
p = ADJUST_FIRST
|
|
196
|
+
ds.map { |e| p += e }
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
212
202
|
|
|
213
203
|
R_22 = -2..2
|
|
214
204
|
|
|
215
|
-
def place_position_adjust_pattern
|
|
216
|
-
|
|
205
|
+
def place_position_adjust_pattern size
|
|
206
|
+
ps = Modules.adjust_pattern_pos size
|
|
217
207
|
rd = R_22.minmax
|
|
218
|
-
|
|
219
|
-
|
|
208
|
+
ps.each do |row|
|
|
209
|
+
ps.each do |col|
|
|
220
210
|
next unless @fields[ row][ col].nil?
|
|
221
211
|
R_22.each do |r|
|
|
222
212
|
pr = row + r
|
|
@@ -231,39 +221,45 @@ module QRest
|
|
|
231
221
|
|
|
232
222
|
def place_timing_pattern
|
|
233
223
|
(8...@fields.size-8).each do |i|
|
|
224
|
+
next unless @fields[ i][ 6].nil?
|
|
234
225
|
@fields[ i][ 6] = @fields[ 6][ i] = i.even?
|
|
235
226
|
end
|
|
236
227
|
end
|
|
237
228
|
|
|
238
|
-
def
|
|
229
|
+
def set_bit n
|
|
230
|
+
n.odd?
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def place_format_info ecl
|
|
239
234
|
bits = Bch.format_info ecl
|
|
240
235
|
15.times do |i|
|
|
241
|
-
|
|
236
|
+
m = set_bit bits
|
|
242
237
|
r =
|
|
243
238
|
case i
|
|
244
239
|
when ...6 then 0
|
|
245
240
|
when ...8 then 1
|
|
246
241
|
else @fields.size - 15
|
|
247
242
|
end
|
|
248
|
-
@fields[ r+i][ 8] =
|
|
243
|
+
@fields[ r + i][ 8] = m
|
|
249
244
|
c =
|
|
250
245
|
case i
|
|
251
246
|
when ...8 then @fields.size
|
|
252
247
|
when ...9 then 16
|
|
253
248
|
else 15
|
|
254
249
|
end
|
|
255
|
-
@fields[ 8][ c - i - 1] =
|
|
250
|
+
@fields[ 8][ c - i - 1] = m
|
|
256
251
|
bits >>= 1
|
|
257
252
|
end
|
|
258
|
-
@fields[ @fields.size - 8][ 8] =
|
|
253
|
+
@fields[ @fields.size - 8][ 8] = set_bit 1
|
|
259
254
|
end
|
|
260
255
|
|
|
261
|
-
def place_version_info version
|
|
256
|
+
def place_version_info version
|
|
257
|
+
return if version < 7
|
|
262
258
|
bits = Bch.version version
|
|
263
259
|
18.times do |i|
|
|
264
260
|
id, im = i.divmod 3
|
|
265
261
|
im += @fields.size - 8 - 3
|
|
266
|
-
@fields[ id][ im] = @fields[ im][ id] =
|
|
262
|
+
@fields[ id][ im] = @fields[ im][ id] = set_bit bits
|
|
267
263
|
bits >>= 1
|
|
268
264
|
end
|
|
269
265
|
end
|
|
@@ -297,5 +293,18 @@ module QRest
|
|
|
297
293
|
|
|
298
294
|
end
|
|
299
295
|
|
|
296
|
+
class ModulesTest < Modules
|
|
297
|
+
|
|
298
|
+
attr_reader :demerits
|
|
299
|
+
|
|
300
|
+
def initialize data, mask_pattern
|
|
301
|
+
super
|
|
302
|
+
@demerits = Demerits.new @fields
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def set_bit _ ; false ; end
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
|
|
300
309
|
end
|
|
301
310
|
|
data/lib/qrest/rsblocks.rb
CHANGED
|
@@ -9,135 +9,143 @@ require "qrest/polynomial"
|
|
|
9
9
|
|
|
10
10
|
module QRest
|
|
11
11
|
|
|
12
|
-
class
|
|
12
|
+
class RSData
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
attr_reader :version, :error_correct_level, :data
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
def initialize version, error_correct_level, input
|
|
17
|
+
@version, @error_correct_level = version, error_correct_level
|
|
18
|
+
b = Blocks.new @version, @error_correct_level
|
|
19
|
+
@data = b.create_data input, version
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Blocks
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
class Block
|
|
25
|
+
attr_reader :data_count, :total_count
|
|
26
|
+
def initialize total_count, data_count
|
|
27
|
+
@total_count, @data_count = total_count, data_count
|
|
28
|
+
end
|
|
29
|
+
def error_count ; total_count - data_count ; end
|
|
20
30
|
end
|
|
21
31
|
|
|
22
|
-
def
|
|
32
|
+
def initialize version, error_correct_level
|
|
33
|
+
@list = self.class.blocks[ version][ error_correct_level].map { |num,total,data|
|
|
34
|
+
[ num, (Block.new total, data)]
|
|
35
|
+
}
|
|
36
|
+
end
|
|
23
37
|
|
|
24
|
-
end
|
|
38
|
+
def each ; @list.each { |(n,b)| n.times { yield b } } ; end
|
|
39
|
+
def sum sym ; @list.map { |(n,b)| n * (b.send sym) }.sum ; end
|
|
40
|
+
def max sym ; @list.map { |(_,b)| (b.send sym) }.max ; end
|
|
25
41
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
def create_data input, version
|
|
43
|
+
dcdata, ecdata = create_blocks input, version
|
|
44
|
+
data = []
|
|
45
|
+
(max :data_count).times do |j|
|
|
46
|
+
dcdata.each do |dc|
|
|
47
|
+
data.push dc[j] if j < dc.size
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
(max :error_count).times do |j|
|
|
51
|
+
ecdata.each do |ec|
|
|
52
|
+
data.push ec[j] if j < ec.size
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
data.length == (sum :total_count) or
|
|
56
|
+
raise Error, "Internal error. Please consider a report."
|
|
57
|
+
data
|
|
58
|
+
end
|
|
34
59
|
|
|
35
|
-
|
|
36
|
-
l = sum :data_count
|
|
37
|
-
b = BitBuffer.build l do |buf| data.write buf, @version end
|
|
38
|
-
create_bytes b
|
|
39
|
-
end
|
|
60
|
+
private
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
dcdata, ecdata = [], []
|
|
45
|
-
i = 0
|
|
46
|
-
each do |rs|
|
|
47
|
-
p = Polynomial.new buffer[ i, rs.data_count]
|
|
48
|
-
i += rs.data_count
|
|
49
|
-
dcdata.push p.num.dup
|
|
50
|
-
p.error_mod! rs.error_count
|
|
51
|
-
ecdata.push p.num
|
|
62
|
+
def build_buffer input, version
|
|
63
|
+
l = sum :data_count
|
|
64
|
+
BitBuffer.build l do |buf| input.write_to buf, version end
|
|
52
65
|
end
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
|
|
67
|
+
def create_blocks input, version
|
|
68
|
+
buffer = build_buffer input, version
|
|
69
|
+
dcdata, ecdata = [], []
|
|
70
|
+
i = 0
|
|
71
|
+
each do |rs|
|
|
72
|
+
p = Polynomial.new buffer[ i, rs.data_count]
|
|
73
|
+
i += rs.data_count
|
|
74
|
+
dcdata.push p.num.dup
|
|
75
|
+
p.error_mod! rs.error_count
|
|
76
|
+
ecdata.push p.num
|
|
57
77
|
end
|
|
78
|
+
[ dcdata, ecdata]
|
|
58
79
|
end
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
end
|
|
80
|
+
|
|
81
|
+
class <<self
|
|
82
|
+
attr_reader :blocks
|
|
63
83
|
end
|
|
64
|
-
data.length == (sum :total_count) or
|
|
65
|
-
raise Error, "Internal error. Please consider a report."
|
|
66
|
-
data
|
|
67
|
-
end
|
|
68
84
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
@blocks = Hash.new { |h,k|
|
|
86
|
+
v = nil
|
|
87
|
+
RS_BLOCK_TABLE.each_line { |l|
|
|
88
|
+
n, l = l.split nil, 2
|
|
89
|
+
if n.to_i == k then
|
|
90
|
+
v = {}
|
|
91
|
+
while l =~ /([a-z])\b([ 0-9,]+)/ do
|
|
92
|
+
n, b, l = $1, $2, $'
|
|
93
|
+
b.rstrip!
|
|
94
|
+
v[ n.to_sym] = (b.split /,/).map { |t| t.split.map { |i| i.to_i } }
|
|
95
|
+
end
|
|
96
|
+
break
|
|
79
97
|
end
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
}
|
|
99
|
+
v or raise ArgumentError, "No RS block for version #{k}"
|
|
100
|
+
h[k] = v
|
|
82
101
|
}
|
|
83
|
-
h[k] = v
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
class <<self
|
|
87
102
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
103
|
+
# http://www.thonky.com/qr-code-tutorial/error-correction-table/
|
|
104
|
+
RS_BLOCK_TABLE = <<~EOT
|
|
105
|
+
1 l 1 26 19, m 1 26 16, q 1 26 13, h 1 26 9,
|
|
106
|
+
2 l 1 44 34, m 1 44 28, q 1 44 22, h 1 44 16,
|
|
107
|
+
3 l 1 70 55, m 1 70 44, q 2 35 17, h 2 35 13,
|
|
108
|
+
4 l 1 100 80, m 2 50 32, q 2 50 24, h 4 25 9,
|
|
109
|
+
5 l 1 134 108, m 2 67 43, q 2 33 15, 2 34 16, h 2 33 11, 2 34 12,
|
|
110
|
+
6 l 2 86 68, m 4 43 27, q 4 43 19, h 4 43 15,
|
|
111
|
+
7 l 2 98 78, m 4 49 31, q 2 32 14, 4 33 15, h 4 39 13, 1 40 14,
|
|
112
|
+
8 l 2 121 97, m 2 60 38, 2 61 39, q 4 40 18, 2 41 19, h 4 40 14, 2 41 15,
|
|
113
|
+
9 l 2 146 116, m 3 58 36, 2 59 37, q 4 36 16, 4 37 17, h 4 36 12, 4 37 13,
|
|
114
|
+
10 l 2 86 68, 2 87 69, m 4 69 43, 1 70 44, q 6 43 19, 2 44 20, h 6 43 15, 2 44 16,
|
|
115
|
+
11 l 4 101 81, m 1 80 50, 4 81 51, q 4 50 22, 4 51 23, h 3 36 12, 8 37 13,
|
|
116
|
+
12 l 2 116 92, 2 117 93, m 6 58 36, 2 59 37, q 4 46 20, 6 47 21, h 7 42 14, 4 43 15,
|
|
117
|
+
13 l 4 133 107, m 8 59 37, 1 60 38, q 8 44 20, 4 45 21, h 12 33 11, 4 34 12,
|
|
118
|
+
14 l 3 145 115, 1 146 116, m 4 64 40, 5 65 41, q 11 36 16, 5 37 17, h 11 36 12, 5 37 13,
|
|
119
|
+
15 l 5 109 87, 1 110 88, m 5 65 41, 5 66 42, q 5 54 24, 7 55 25, h 11 36 12, 7 37 13,
|
|
120
|
+
16 l 5 122 98, 1 123 99, m 7 73 45, 3 74 46, q 15 43 19, 2 44 20, h 3 45 15, 13 46 16,
|
|
121
|
+
17 l 1 135 107, 5 136 108, m 10 74 46, 1 75 47, q 1 50 22, 15 51 23, h 2 42 14, 17 43 15,
|
|
122
|
+
18 l 5 150 120, 1 151 121, m 9 69 43, 4 70 44, q 17 50 22, 1 51 23, h 2 42 14, 19 43 15,
|
|
123
|
+
19 l 3 141 113, 4 142 114, m 3 70 44, 11 71 45, q 17 47 21, 4 48 22, h 9 39 13, 16 40 14,
|
|
124
|
+
20 l 3 135 107, 5 136 108, m 3 67 41, 13 68 42, q 15 54 24, 5 55 25, h 15 43 15, 10 44 16,
|
|
125
|
+
21 l 4 144 116, 4 145 117, m 17 68 42, q 17 50 22, 6 51 23, h 19 46 16, 6 47 17,
|
|
126
|
+
22 l 2 139 111, 7 140 112, m 17 74 46, q 7 54 24, 16 55 25, h 34 37 13,
|
|
127
|
+
23 l 4 151 121, 5 152 122, m 4 75 47, 14 76 48, q 11 54 24, 14 55 25, h 16 45 15, 14 46 16,
|
|
128
|
+
24 l 6 147 117, 4 148 118, m 6 73 45, 14 74 46, q 11 54 24, 16 55 25, h 30 46 16, 2 47 17,
|
|
129
|
+
25 l 8 132 106, 4 133 107, m 8 75 47, 13 76 48, q 7 54 24, 22 55 25, h 22 45 15, 13 46 16,
|
|
130
|
+
26 l 10 142 114, 2 143 115, m 19 74 46, 4 75 47, q 28 50 22, 6 51 23, h 33 46 16, 4 47 17,
|
|
131
|
+
27 l 8 152 122, 4 153 123, m 22 73 45, 3 74 46, q 8 53 23, 26 54 24, h 12 45 15, 28 46 16,
|
|
132
|
+
28 l 3 147 117, 10 148 118, m 3 73 45, 23 74 46, q 4 54 24, 31 55 25, h 11 45 15, 31 46 16,
|
|
133
|
+
29 l 7 146 116, 7 147 117, m 21 73 45, 7 74 46, q 1 53 23, 37 54 24, h 19 45 15, 26 46 16,
|
|
134
|
+
30 l 5 145 115, 10 146 116, m 19 75 47, 10 76 48, q 15 54 24, 25 55 25, h 23 45 15, 25 46 16,
|
|
135
|
+
31 l 13 145 115, 3 146 116, m 2 74 46, 29 75 47, q 42 54 24, 1 55 25, h 23 45 15, 28 46 16,
|
|
136
|
+
32 l 17 145 115, m 10 74 46, 23 75 47, q 10 54 24, 35 55 25, h 19 45 15, 35 46 16,
|
|
137
|
+
33 l 17 145 115, 1 146 116, m 14 74 46, 21 75 47, q 29 54 24, 19 55 25, h 11 45 15, 46 46 16,
|
|
138
|
+
34 l 13 145 115, 6 146 116, m 14 74 46, 23 75 47, q 44 54 24, 7 55 25, h 59 46 16, 1 47 17,
|
|
139
|
+
35 l 12 151 121, 7 152 122, m 12 75 47, 26 76 48, q 39 54 24, 14 55 25, h 22 45 15, 41 46 16,
|
|
140
|
+
36 l 6 151 121, 14 152 122, m 6 75 47, 34 76 48, q 46 54 24, 10 55 25, h 2 45 15, 64 46 16,
|
|
141
|
+
37 l 17 152 122, 4 153 123, m 29 74 46, 14 75 47, q 49 54 24, 10 55 25, h 24 45 15, 46 46 16,
|
|
142
|
+
38 l 4 152 122, 18 153 123, m 13 74 46, 32 75 47, q 48 54 24, 14 55 25, h 42 45 15, 32 46 16,
|
|
143
|
+
39 l 20 147 117, 4 148 118, m 40 75 47, 7 76 48, q 43 54 24, 22 55 25, h 10 45 15, 67 46 16,
|
|
144
|
+
40 l 19 148 118, 6 149 119, m 18 75 47, 31 76 48, q 34 54 24, 34 55 25, h 20 45 15, 61 46 16,
|
|
145
|
+
EOT
|
|
94
146
|
|
|
95
147
|
end
|
|
96
148
|
|
|
97
|
-
# http://www.thonky.com/qr-code-tutorial/error-correction-table/
|
|
98
|
-
RS_BLOCK_TABLE = <<~EOT
|
|
99
|
-
1 l 1 26 19, m 1 26 16, q 1 26 13, h 1 26 9,
|
|
100
|
-
2 l 1 44 34, m 1 44 28, q 1 44 22, h 1 44 16,
|
|
101
|
-
3 l 1 70 55, m 1 70 44, q 2 35 17, h 2 35 13,
|
|
102
|
-
4 l 1 100 80, m 2 50 32, q 2 50 24, h 4 25 9,
|
|
103
|
-
5 l 1 134 108, m 2 67 43, q 2 33 15, 2 34 16, h 2 33 11, 2 34 12,
|
|
104
|
-
6 l 2 86 68, m 4 43 27, q 4 43 19, h 4 43 15,
|
|
105
|
-
7 l 2 98 78, m 4 49 31, q 2 32 14, 4 33 15, h 4 39 13, 1 40 14,
|
|
106
|
-
8 l 2 121 97, m 2 60 38, 2 61 39, q 4 40 18, 2 41 19, h 4 40 14, 2 41 15,
|
|
107
|
-
9 l 2 146 116, m 3 58 36, 2 59 37, q 4 36 16, 4 37 17, h 4 36 12, 4 37 13,
|
|
108
|
-
10 l 2 86 68, 2 87 69, m 4 69 43, 1 70 44, q 6 43 19, 2 44 20, h 6 43 15, 2 44 16,
|
|
109
|
-
11 l 4 101 81, m 1 80 50, 4 81 51, q 4 50 22, 4 51 23, h 3 36 12, 8 37 13,
|
|
110
|
-
12 l 2 116 92, 2 117 93, m 6 58 36, 2 59 37, q 4 46 20, 6 47 21, h 7 42 14, 4 43 15,
|
|
111
|
-
13 l 4 133 107, m 8 59 37, 1 60 38, q 8 44 20, 4 45 21, h 12 33 11, 4 34 12,
|
|
112
|
-
14 l 3 145 115, 1 146 116, m 4 64 40, 5 65 41, q 11 36 16, 5 37 17, h 11 36 12, 5 37 13,
|
|
113
|
-
15 l 5 109 87, 1 110 88, m 5 65 41, 5 66 42, q 5 54 24, 7 55 25, h 11 36 12, 7 37 13,
|
|
114
|
-
16 l 5 122 98, 1 123 99, m 7 73 45, 3 74 46, q 15 43 19, 2 44 20, h 3 45 15, 13 46 16,
|
|
115
|
-
17 l 1 135 107, 5 136 108, m 10 74 46, 1 75 47, q 1 50 22, 15 51 23, h 2 42 14, 17 43 15,
|
|
116
|
-
18 l 5 150 120, 1 151 121, m 9 69 43, 4 70 44, q 17 50 22, 1 51 23, h 2 42 14, 19 43 15,
|
|
117
|
-
19 l 3 141 113, 4 142 114, m 3 70 44, 11 71 45, q 17 47 21, 4 48 22, h 9 39 13, 16 40 14,
|
|
118
|
-
20 l 3 135 107, 5 136 108, m 3 67 41, 13 68 42, q 15 54 24, 5 55 25, h 15 43 15, 10 44 16,
|
|
119
|
-
21 l 4 144 116, 4 145 117, m 17 68 42, q 17 50 22, 6 51 23, h 19 46 16, 6 47 17,
|
|
120
|
-
22 l 2 139 111, 7 140 112, m 17 74 46, q 7 54 24, 16 55 25, h 34 37 13,
|
|
121
|
-
23 l 4 151 121, 5 152 122, m 4 75 47, 14 76 48, q 11 54 24, 14 55 25, h 16 45 15, 14 46 16,
|
|
122
|
-
24 l 6 147 117, 4 148 118, m 6 73 45, 14 74 46, q 11 54 24, 16 55 25, h 30 46 16, 2 47 17,
|
|
123
|
-
25 l 8 132 106, 4 133 107, m 8 75 47, 13 76 48, q 7 54 24, 22 55 25, h 22 45 15, 13 46 16,
|
|
124
|
-
26 l 10 142 114, 2 143 115, m 19 74 46, 4 75 47, q 28 50 22, 6 51 23, h 33 46 16, 4 47 17,
|
|
125
|
-
27 l 8 152 122, 4 153 123, m 22 73 45, 3 74 46, q 8 53 23, 26 54 24, h 12 45 15, 28 46 16,
|
|
126
|
-
28 l 3 147 117, 10 148 118, m 3 73 45, 23 74 46, q 4 54 24, 31 55 25, h 11 45 15, 31 46 16,
|
|
127
|
-
29 l 7 146 116, 7 147 117, m 21 73 45, 7 74 46, q 1 53 23, 37 54 24, h 19 45 15, 26 46 16,
|
|
128
|
-
30 l 5 145 115, 10 146 116, m 19 75 47, 10 76 48, q 15 54 24, 25 55 25, h 23 45 15, 25 46 16,
|
|
129
|
-
31 l 13 145 115, 3 146 116, m 2 74 46, 29 75 47, q 42 54 24, 1 55 25, h 23 45 15, 28 46 16,
|
|
130
|
-
32 l 17 145 115, m 10 74 46, 23 75 47, q 10 54 24, 35 55 25, h 19 45 15, 35 46 16,
|
|
131
|
-
33 l 17 145 115, 1 146 116, m 14 74 46, 21 75 47, q 29 54 24, 19 55 25, h 11 45 15, 46 46 16,
|
|
132
|
-
34 l 13 145 115, 6 146 116, m 14 74 46, 23 75 47, q 44 54 24, 7 55 25, h 59 46 16, 1 47 17,
|
|
133
|
-
35 l 12 151 121, 7 152 122, m 12 75 47, 26 76 48, q 39 54 24, 14 55 25, h 22 45 15, 41 46 16,
|
|
134
|
-
36 l 6 151 121, 14 152 122, m 6 75 47, 34 76 48, q 46 54 24, 10 55 25, h 2 45 15, 64 46 16,
|
|
135
|
-
37 l 17 152 122, 4 153 123, m 29 74 46, 14 75 47, q 49 54 24, 10 55 25, h 24 45 15, 46 46 16,
|
|
136
|
-
38 l 4 152 122, 18 153 123, m 13 74 46, 32 75 47, q 48 54 24, 14 55 25, h 42 45 15, 32 46 16,
|
|
137
|
-
39 l 20 147 117, 4 148 118, m 40 75 47, 7 76 48, q 43 54 24, 22 55 25, h 10 45 15, 67 46 16,
|
|
138
|
-
40 l 19 148 118, 6 149 119, m 18 75 47, 31 76 48, q 34 54 24, 34 55 25, h 20 45 15, 61 46 16,
|
|
139
|
-
EOT
|
|
140
|
-
|
|
141
149
|
end
|
|
142
150
|
|
|
143
151
|
end
|
data/lib/qrest/segment.rb
CHANGED
|
@@ -13,8 +13,8 @@ module QRest
|
|
|
13
13
|
@data = data
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def
|
|
17
|
-
buffer.put
|
|
16
|
+
def write_to buffer, version
|
|
17
|
+
buffer.put self.class::ID, 4
|
|
18
18
|
buffer.put @data.bytesize, (get_length_in_bits version)
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -62,10 +62,13 @@ module QRest
|
|
|
62
62
|
type or raise ArgumentError, "Not a valid segment type: #{mode}"
|
|
63
63
|
type.new data
|
|
64
64
|
else
|
|
65
|
+
r = nil
|
|
65
66
|
@sub.each do |t|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
r = t.new data
|
|
68
|
+
break
|
|
69
|
+
rescue ArgumentError, NotImplementedError, EncodingError
|
|
68
70
|
end
|
|
71
|
+
r or raise "No appropriate segment type possible."
|
|
69
72
|
end
|
|
70
73
|
when Array then
|
|
71
74
|
Multi.new data
|
|
@@ -94,8 +97,8 @@ module QRest
|
|
|
94
97
|
}
|
|
95
98
|
end
|
|
96
99
|
|
|
97
|
-
def
|
|
98
|
-
@segs.each { |s| s.
|
|
100
|
+
def write_to buffer, version
|
|
101
|
+
@segs.each { |s| s.write_to buffer, version }
|
|
99
102
|
end
|
|
100
103
|
|
|
101
104
|
def size version
|
|
@@ -108,7 +111,7 @@ module QRest
|
|
|
108
111
|
class Numeric < Segment
|
|
109
112
|
|
|
110
113
|
NAME = "number"
|
|
111
|
-
ID =
|
|
114
|
+
ID = 1
|
|
112
115
|
BITS_FOR_MODE = [10, 12, 14]
|
|
113
116
|
|
|
114
117
|
def initialize data
|
|
@@ -118,7 +121,7 @@ module QRest
|
|
|
118
121
|
|
|
119
122
|
NUMBER_LENGTH = { 3 => 10, 2 => 7, 1 => 4 }
|
|
120
123
|
|
|
121
|
-
def
|
|
124
|
+
def write_to buffer, version
|
|
122
125
|
super
|
|
123
126
|
@data.scan /\d{1,3}/ do |chars|
|
|
124
127
|
buffer.put chars.to_i, NUMBER_LENGTH[ chars.length]
|
|
@@ -132,7 +135,7 @@ module QRest
|
|
|
132
135
|
class Alphanumeric < Segment
|
|
133
136
|
|
|
134
137
|
NAME = "alphanumeric"
|
|
135
|
-
ID =
|
|
138
|
+
ID = 2
|
|
136
139
|
BITS_FOR_MODE = [ 9, 11, 13]
|
|
137
140
|
|
|
138
141
|
ALPHANUMERIC, = [
|
|
@@ -146,7 +149,7 @@ module QRest
|
|
|
146
149
|
super
|
|
147
150
|
end
|
|
148
151
|
|
|
149
|
-
def
|
|
152
|
+
def write_to buffer, version
|
|
150
153
|
super
|
|
151
154
|
@data.scan /(.)(.)?/ do |c,d|
|
|
152
155
|
val = ALPHANUMERIC[ c]
|
|
@@ -166,7 +169,7 @@ module QRest
|
|
|
166
169
|
class Kanji < Segment
|
|
167
170
|
|
|
168
171
|
NAME = "kanji"
|
|
169
|
-
ID =
|
|
172
|
+
ID = 8
|
|
170
173
|
BITS_FOR_MODE = [ 8, 10, 12]
|
|
171
174
|
|
|
172
175
|
def initialize data
|
|
@@ -174,7 +177,7 @@ module QRest
|
|
|
174
177
|
not_implemented
|
|
175
178
|
end
|
|
176
179
|
|
|
177
|
-
def
|
|
180
|
+
def write_to buffer, version
|
|
178
181
|
super
|
|
179
182
|
not_implemented
|
|
180
183
|
end
|
|
@@ -192,10 +195,20 @@ module QRest
|
|
|
192
195
|
class Bytes < Segment
|
|
193
196
|
|
|
194
197
|
NAME = "8bit"
|
|
195
|
-
ID =
|
|
198
|
+
ID = 4
|
|
196
199
|
BITS_FOR_MODE = [ 8, 16, 16]
|
|
197
200
|
|
|
198
|
-
|
|
201
|
+
@strict = false
|
|
202
|
+
class <<self
|
|
203
|
+
attr_accessor :strict
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def initialize data
|
|
207
|
+
data = data.encode Encoding::ISO8859_1 if self.class.strict
|
|
208
|
+
super
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def write_to buffer, version
|
|
199
212
|
super
|
|
200
213
|
@data.each_byte do |b|
|
|
201
214
|
buffer.put b, 8
|
data/lib/qrest/version.rb
CHANGED
data/lib/qrest.rb
CHANGED
|
@@ -27,26 +27,24 @@ module QRest
|
|
|
27
27
|
Modules::ERRORCORRECTLEVEL[error_correct_level] or
|
|
28
28
|
raise ArgumentError, "Unknown error correction level: #{level}"
|
|
29
29
|
if version then
|
|
30
|
-
|
|
31
|
-
raise ArgumentError, "Requested version
|
|
30
|
+
Modules::VERSIONS.include? version or
|
|
31
|
+
raise ArgumentError, "Requested version not in #{Modules::VERSIONS}"
|
|
32
32
|
else
|
|
33
33
|
if max_version then
|
|
34
|
-
|
|
35
|
-
raise ArgumentError, "Maximum
|
|
34
|
+
Modules::VERSIONS.include? max_version or
|
|
35
|
+
raise ArgumentError, "Maximum version mot in #{Modules::VERSIONS}"
|
|
36
36
|
else
|
|
37
|
-
max_version = Modules::
|
|
37
|
+
max_version = Modules::VERSIONS.end
|
|
38
38
|
end
|
|
39
39
|
mb = Modules::MAXBITS[error_correct_level]
|
|
40
|
-
version =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
end until (input.size version) <= mb[version - 1]
|
|
40
|
+
version = Modules::VERSIONS.find { |v|
|
|
41
|
+
v <= max_version or
|
|
42
|
+
raise Error, "Data length exceeds requested maximum version of #{max_version}"
|
|
43
|
+
(input.size v) <= mb[ v - 1]
|
|
44
|
+
}
|
|
46
45
|
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@modules = Modules.create_best data, version, error_correct_level
|
|
46
|
+
data = RSData.new version, error_correct_level, input
|
|
47
|
+
@modules = Modules.create_best data
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def to_s dark: nil, light: nil, quiet_size: nil
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: qrest
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bertram Scharpf
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: |
|
|
13
13
|
A Ruby library that generates QR Codes
|
|
@@ -50,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '0'
|
|
52
52
|
requirements: []
|
|
53
|
-
rubygems_version: 3.
|
|
53
|
+
rubygems_version: 3.7.1
|
|
54
54
|
specification_version: 4
|
|
55
55
|
summary: Generate QR Codes
|
|
56
56
|
test_files: []
|