rqrcode_core 0.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,39 +6,38 @@ module RQRCodeCore
6
6
  exp_table = Array.new(256)
7
7
  log_table = Array.new(256)
8
8
 
9
- ( 0...8 ).each do |i|
9
+ (0...8).each do |i|
10
10
  exp_table[i] = 1 << i
11
11
  end
12
12
 
13
- ( 8...256 ).each do |i|
13
+ (8...256).each do |i|
14
14
  exp_table[i] = exp_table[i - 4] \
15
15
  ^ exp_table[i - 5] \
16
16
  ^ exp_table[i - 6] \
17
17
  ^ exp_table[i - 8]
18
18
  end
19
19
 
20
- ( 0...255 ).each do |i|
21
- log_table[exp_table[i] ] = i
20
+ (0...255).each do |i|
21
+ log_table[exp_table[i]] = i
22
22
  end
23
23
 
24
- EXP_TABLE = exp_table
25
- LOG_TABLE = log_table
24
+ const_set(:EXP_TABLE, exp_table).freeze
25
+ const_set(:LOG_TABLE, log_table).freeze
26
26
  }
27
27
 
28
28
  class << self
29
29
  def glog(n)
30
- raise QRCodeRunTimeError, "glog(#{n})" if ( n < 1 )
30
+ raise QRCodeRunTimeError, "glog(#{n})" if n < 1
31
31
  LOG_TABLE[n]
32
32
  end
33
33
 
34
-
35
34
  def gexp(n)
36
35
  while n < 0
37
- n = n + 255
36
+ n += 255
38
37
  end
39
38
 
40
39
  while n >= 256
41
- n = n - 255
40
+ n -= 255
42
41
  end
43
42
 
44
43
  EXP_TABLE[n]
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRMulti
5
+ def initialize(data)
6
+ @data = data
7
+ end
8
+
9
+ def write(buffer)
10
+ @data.each { |seg| seg.writer.write(buffer) }
11
+ end
12
+ end
13
+ end
@@ -1,38 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RQRCodeCore
4
- NUMERIC = ['0','1','2','3','4','5','6','7','8','9'].freeze
4
+ NUMERIC = %w[0 1 2 3 4 5 6 7 8 9].freeze
5
5
 
6
6
  class QRNumeric
7
- attr_reader :mode
8
-
9
- def initialize( data )
10
- @mode = QRMODE[:mode_number]
11
-
7
+ def initialize(data)
12
8
  raise QRCodeArgumentError, "Not a numeric string `#{data}`" unless QRNumeric.valid_data?(data)
13
9
 
14
- @data = data;
10
+ @data = data
15
11
  end
16
12
 
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
13
+ def self.valid_data?(data)
14
+ (data.chars - NUMERIC).empty?
26
15
  end
27
16
 
28
- def write( buffer)
29
- buffer.numeric_encoding_start(get_length)
17
+ def write(buffer)
18
+ buffer.numeric_encoding_start(@data.size)
30
19
 
31
- (@data.size).times do |i|
20
+ @data.size.times do |i|
32
21
  if i % 3 == 0
33
22
  chars = @data[i, 3]
34
23
  bit_length = get_bit_length(chars.length)
35
- buffer.put( get_code(chars), bit_length )
24
+ buffer.put(get_code(chars), bit_length)
36
25
  end
37
26
  end
38
27
  end
@@ -2,22 +2,22 @@
2
2
 
3
3
  module RQRCodeCore
4
4
  class QRPolynomial
5
- def initialize( num, shift )
5
+ def initialize(num, shift)
6
6
  raise QRCodeRunTimeError, "#{num.size}/#{shift}" if num.empty?
7
7
  offset = 0
8
8
 
9
9
  while offset < num.size && num[offset] == 0
10
- offset = offset + 1
10
+ offset += 1
11
11
  end
12
12
 
13
- @num = Array.new( num.size - offset + shift )
13
+ @num = Array.new(num.size - offset + shift)
14
14
 
15
- ( 0...num.size - offset ).each do |i|
15
+ (0...num.size - offset).each do |i|
16
16
  @num[i] = num[i + offset]
17
17
  end
18
18
  end
19
19
 
20
- def get( index )
20
+ def get(index)
21
21
  @num[index]
22
22
  end
23
23
 
@@ -25,20 +25,20 @@ module RQRCodeCore
25
25
  @num.size
26
26
  end
27
27
 
28
- def multiply( e )
29
- num = Array.new( get_length + e.get_length - 1 )
28
+ def multiply(e)
29
+ num = Array.new(get_length + e.get_length - 1)
30
30
 
31
- ( 0...get_length ).each do |i|
32
- ( 0...e.get_length ).each do |j|
31
+ (0...get_length).each do |i|
32
+ (0...e.get_length).each do |j|
33
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)))
34
+ num[i + j] = tmp ^ QRMath.gexp(QRMath.glog(get(i)) + QRMath.glog(e.get(j)))
35
35
  end
36
36
  end
37
37
 
38
- return QRPolynomial.new( num, 0 )
38
+ QRPolynomial.new(num, 0)
39
39
  end
40
40
 
41
- def mod( e )
41
+ def mod(e)
42
42
  if get_length - e.get_length < 0
43
43
  return self
44
44
  end
@@ -46,16 +46,16 @@ module RQRCodeCore
46
46
  ratio = QRMath.glog(get(0)) - QRMath.glog(e.get(0))
47
47
  num = Array.new(get_length)
48
48
 
49
- ( 0...get_length ).each do |i|
49
+ (0...get_length).each do |i|
50
50
  num[i] = get(i)
51
51
  end
52
52
 
53
- ( 0...e.get_length ).each do |i|
53
+ (0...e.get_length).each do |i|
54
54
  tmp = num[i].nil? ? 0 : num[i]
55
55
  num[i] = tmp ^ QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
56
56
  end
57
57
 
58
- return QRPolynomial.new( num, 0 ).mod(e)
58
+ QRPolynomial.new(num, 0).mod(e)
59
59
  end
60
60
  end
61
61
  end
@@ -4,13 +4,13 @@ module RQRCodeCore
4
4
  class QRRSBlock
5
5
  attr_reader :data_count, :total_count
6
6
 
7
- def initialize( total_count, data_count )
7
+ def initialize(total_count, data_count)
8
8
  @total_count = total_count
9
9
  @data_count = data_count
10
10
  end
11
11
 
12
12
  # http://www.thonky.com/qr-code-tutorial/error-correction-table/
13
- RQRCodeCore::QRRSBlock::RS_BLOCK_TABLE = [
13
+ RS_BLOCK_TABLE = [
14
14
  # L
15
15
  # M
16
16
  # Q
@@ -256,9 +256,9 @@ module RQRCodeCore
256
256
  [34, 54, 24, 34, 55, 25],
257
257
  [20, 45, 15, 61, 46, 16]
258
258
 
259
- ]
259
+ ].freeze
260
260
 
261
- def QRRSBlock.get_rs_blocks(version, error_correct_level)
261
+ def self.get_rs_blocks(version, error_correct_level)
262
262
  rs_block = QRRSBlock.get_rs_block_table(version, error_correct_level)
263
263
 
264
264
  if rs_block.nil?
@@ -269,20 +269,20 @@ module RQRCodeCore
269
269
  length = rs_block.size / 3
270
270
  list = []
271
271
 
272
- ( 0...length ).each do |i|
272
+ (0...length).each do |i|
273
273
  count = rs_block[i * 3 + 0]
274
274
  total_count = rs_block[i * 3 + 1]
275
275
  data_count = rs_block[i * 3 + 2]
276
276
 
277
- ( 0...count ).each do |j|
278
- list << QRRSBlock.new( total_count, data_count )
277
+ (0...count).each do |j|
278
+ list << QRRSBlock.new(total_count, data_count)
279
279
  end
280
280
  end
281
281
 
282
282
  list
283
283
  end
284
284
 
285
- def QRRSBlock.get_rs_block_table(version, error_correct_level)
285
+ def self.get_rs_block_table(version, error_correct_level)
286
286
  case error_correct_level
287
287
  when QRERRORCORRECTLEVEL[:l]
288
288
  QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 0]
@@ -292,8 +292,6 @@ module RQRCodeCore
292
292
  QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 2]
293
293
  when QRERRORCORRECTLEVEL[:h]
294
294
  QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 3]
295
- else
296
- nil
297
295
  end
298
296
  end
299
297
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRSegment
5
+ attr_reader :data, :mode
6
+
7
+ def initialize(data:, mode: nil)
8
+ @data = data
9
+ @mode = QRMODE_NAME.dig(mode&.to_sym)
10
+
11
+ # If mode is not explicitely found choose mode according to data type
12
+ @mode ||= if RQRCodeCore::QRNumeric.valid_data?(@data)
13
+ QRMODE_NAME[:number]
14
+ elsif QRAlphanumeric.valid_data?(@data)
15
+ QRMODE_NAME[:alphanumeric]
16
+ else
17
+ QRMODE_NAME[:byte_8bit]
18
+ end
19
+ end
20
+
21
+ def size(version)
22
+ 4 + header_size(version) + content_size
23
+ end
24
+
25
+ def header_size(version)
26
+ QRUtil.get_length_in_bits(QRMODE[mode], version)
27
+ end
28
+
29
+ def content_size
30
+ chunk_size, bit_length, extra = case mode
31
+ when :mode_number
32
+ [3, QRNumeric::NUMBER_LENGTH[3], QRNumeric::NUMBER_LENGTH[data_length % 3] || 0]
33
+ when :mode_alpha_numk
34
+ [2, 11, 6]
35
+ when :mode_8bit_byte
36
+ [1, 8, 0]
37
+ end
38
+
39
+ (data_length / chunk_size) * bit_length + ((data_length % chunk_size) == 0 ? 0 : extra)
40
+ end
41
+
42
+ def writer
43
+ case mode
44
+ when :mode_number
45
+ QRNumeric.new(data)
46
+ when :mode_alpha_numk
47
+ QRAlphanumeric.new(data)
48
+ when :mode_multi
49
+ QRMulti.new(data)
50
+ else
51
+ QR8bitByte.new(data)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def data_length
58
+ data.bytesize
59
+ end
60
+ end
61
+ end
@@ -43,7 +43,7 @@ module RQRCodeCore
43
43
  [6, 32, 58, 84, 110, 136, 162],
44
44
  [6, 26, 54, 82, 110, 138, 166],
45
45
  [6, 30, 58, 86, 114, 142, 170]
46
- ]
46
+ ].freeze
47
47
 
48
48
  G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0
49
49
  G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0
@@ -58,70 +58,70 @@ module RQRCodeCore
58
58
  QRMODE[:mode_number] => [10, 12, 14],
59
59
  QRMODE[:mode_alpha_numk] => [9, 11, 13],
60
60
  QRMODE[:mode_8bit_byte] => [8, 16, 16],
61
- QRMODE[:mode_kanji] => [8, 10, 12],
62
- }
61
+ QRMODE[:mode_kanji] => [8, 10, 12]
62
+ }.freeze
63
63
 
64
- def QRUtil.max_size
64
+ def self.max_size
65
65
  PATTERN_POSITION_TABLE.count
66
66
  end
67
67
 
68
- def QRUtil.get_bch_format_info( data )
68
+ def self.get_bch_format_info(data)
69
69
  d = data << 10
70
70
  while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15) >= 0
71
71
  d ^= (G15 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15)))
72
72
  end
73
- (( data << 10 ) | d) ^ G15_MASK
73
+ ((data << 10) | d) ^ G15_MASK
74
74
  end
75
75
 
76
- def QRUtil.rszf( num, count )
76
+ def self.rszf(num, count)
77
77
  # zero fill right shift
78
- (num >> count) & ((2 ** ((num.size * 8) - count))-1)
78
+ (num >> count) & ((2**((num.size * 8) - count)) - 1)
79
79
  end
80
80
 
81
- def QRUtil.get_bch_version(data)
81
+ def self.get_bch_version(data)
82
82
  d = data << 12
83
83
  while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18) >= 0
84
84
  d ^= (G18 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18)))
85
85
  end
86
- ( data << 12 ) | d
86
+ (data << 12) | d
87
87
  end
88
88
 
89
- def QRUtil.get_bch_digit( data )
89
+ def self.get_bch_digit(data)
90
90
  digit = 0
91
91
 
92
92
  while data != 0
93
- digit = digit + 1
94
- data = QRUtil.rszf( data, 1 )
93
+ digit += 1
94
+ data = QRUtil.rszf(data, 1)
95
95
  end
96
96
 
97
97
  digit
98
98
  end
99
99
 
100
- def QRUtil.get_pattern_positions(version)
100
+ def self.get_pattern_positions(version)
101
101
  PATTERN_POSITION_TABLE[version - 1]
102
102
  end
103
103
 
104
- def QRUtil.get_mask( mask_pattern, i, j )
104
+ def self.get_mask(mask_pattern, i, j)
105
105
  if mask_pattern > QRMASKCOMPUTATIONS.size
106
106
  raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}"
107
107
  end
108
108
 
109
- return QRMASKCOMPUTATIONS[mask_pattern].call(i, j)
109
+ QRMASKCOMPUTATIONS[mask_pattern].call(i, j)
110
110
  end
111
111
 
112
- def QRUtil.get_error_correct_polynomial( error_correct_length )
113
- a = QRPolynomial.new( [1], 0 )
112
+ def self.get_error_correct_polynomial(error_correct_length)
113
+ a = QRPolynomial.new([1], 0)
114
114
 
115
- ( 0...error_correct_length ).each do |i|
116
- a = a.multiply( QRPolynomial.new( [1, QRMath.gexp(i)], 0 ) )
115
+ (0...error_correct_length).each do |i|
116
+ a = a.multiply(QRPolynomial.new([1, QRMath.gexp(i)], 0))
117
117
  end
118
118
 
119
119
  a
120
120
  end
121
121
 
122
- def QRUtil.get_length_in_bits(mode, version)
122
+ def self.get_length_in_bits(mode, version)
123
123
  if !QRMODE.value?(mode)
124
- raise QRCodeRunTimeError, "Unknown mode: #{mode}"
124
+ raise QRCodeRunTimeError, "Unknown mode: #{mode}"
125
125
  end
126
126
 
127
127
  if version > 40
@@ -139,10 +139,10 @@ module RQRCodeCore
139
139
  macro_version = 2
140
140
  end
141
141
 
142
- return BITS_FOR_MODE[mode][macro_version]
142
+ BITS_FOR_MODE[mode][macro_version]
143
143
  end
144
144
 
145
- def QRUtil.get_lost_points(modules)
145
+ def self.get_lost_points(modules)
146
146
  demerit_points = 0
147
147
 
148
148
  demerit_points += QRUtil.demerit_points_1_same_color(modules)
@@ -150,10 +150,10 @@ module RQRCodeCore
150
150
  demerit_points += QRUtil.demerit_points_3_dangerous_patterns(modules)
151
151
  demerit_points += QRUtil.demerit_points_4_dark_ratio(modules)
152
152
 
153
- return demerit_points
153
+ demerit_points
154
154
  end
155
155
 
156
- def QRUtil.demerit_points_1_same_color(modules)
156
+ def self.demerit_points_1_same_color(modules)
157
157
  demerit_points = 0
158
158
  module_count = modules.size
159
159
 
@@ -163,10 +163,10 @@ module RQRCodeCore
163
163
  same_count = 0
164
164
  dark = modules[row][col]
165
165
 
166
- ( -1..1 ).each do |r|
166
+ (-1..1).each do |r|
167
167
  next if row + r < 0 || module_count <= row + r
168
168
 
169
- ( -1..1 ).each do |c|
169
+ (-1..1).each do |c|
170
170
  next if col + c < 0 || module_count <= col + c
171
171
  next if r == 0 && c == 0
172
172
  if dark == modules[row + r][col + c]
@@ -181,10 +181,10 @@ module RQRCodeCore
181
181
  end
182
182
  end
183
183
 
184
- return demerit_points
184
+ demerit_points
185
185
  end
186
186
 
187
- def QRUtil.demerit_points_2_full_blocks(modules)
187
+ def self.demerit_points_2_full_blocks(modules)
188
188
  demerit_points = 0
189
189
  module_count = modules.size
190
190
 
@@ -196,16 +196,16 @@ module RQRCodeCore
196
196
  count += 1 if modules[row + 1][col]
197
197
  count += 1 if modules[row][col + 1]
198
198
  count += 1 if modules[row + 1][col + 1]
199
- if (count == 0 || count == 4)
199
+ if count == 0 || count == 4
200
200
  demerit_points += DEMERIT_POINTS_2
201
201
  end
202
202
  end
203
203
  end
204
204
 
205
- return demerit_points
205
+ demerit_points
206
206
  end
207
207
 
208
- def QRUtil.demerit_points_3_dangerous_patterns(modules)
208
+ def self.demerit_points_3_dangerous_patterns(modules)
209
209
  demerit_points = 0
210
210
  module_count = modules.size
211
211
 
@@ -213,12 +213,12 @@ module RQRCodeCore
213
213
  modules.each do |row|
214
214
  (module_count - 6).times do |col_idx|
215
215
  if row[col_idx] &&
216
- !row[col_idx + 1] &&
217
- row[col_idx + 2] &&
218
- row[col_idx + 3] &&
219
- row[col_idx + 4] &&
220
- !row[col_idx + 5] &&
221
- row[col_idx + 6]
216
+ !row[col_idx + 1] &&
217
+ row[col_idx + 2] &&
218
+ row[col_idx + 3] &&
219
+ row[col_idx + 4] &&
220
+ !row[col_idx + 5] &&
221
+ row[col_idx + 6]
222
222
  demerit_points += DEMERIT_POINTS_3
223
223
  end
224
224
  end
@@ -227,21 +227,21 @@ module RQRCodeCore
227
227
  (0...module_count).each do |col|
228
228
  (0...(module_count - 6)).each do |row|
229
229
  if modules[row][col] &&
230
- !modules[row + 1][col] &&
231
- modules[row + 2][col] &&
232
- modules[row + 3][col] &&
233
- modules[row + 4][col] &&
234
- !modules[row + 5][col] &&
235
- modules[row + 6][col]
230
+ !modules[row + 1][col] &&
231
+ modules[row + 2][col] &&
232
+ modules[row + 3][col] &&
233
+ modules[row + 4][col] &&
234
+ !modules[row + 5][col] &&
235
+ modules[row + 6][col]
236
236
  demerit_points += DEMERIT_POINTS_3
237
237
  end
238
238
  end
239
239
  end
240
240
 
241
- return demerit_points
241
+ demerit_points
242
242
  end
243
243
 
244
- def QRUtil.demerit_points_4_dark_ratio(modules)
244
+ def self.demerit_points_4_dark_ratio(modules)
245
245
  # level 4
246
246
  dark_count = modules.reduce(0) do |sum, col|
247
247
  sum + col.count(true)
@@ -250,8 +250,7 @@ module RQRCodeCore
250
250
  ratio = dark_count / (modules.size * modules.size)
251
251
  ratio_delta = (100 * ratio - 50).abs / 5
252
252
 
253
- demerit_points = ratio_delta * DEMERIT_POINTS_4
254
- return demerit_points
253
+ ratio_delta * DEMERIT_POINTS_4
255
254
  end
256
255
  end
257
256
  end