rqrcode_core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ class QRUtil
5
+ PATTERN_POSITION_TABLE = [
6
+ [],
7
+ [6, 18],
8
+ [6, 22],
9
+ [6, 26],
10
+ [6, 30],
11
+ [6, 34],
12
+ [6, 22, 38],
13
+ [6, 24, 42],
14
+ [6, 26, 46],
15
+ [6, 28, 50],
16
+ [6, 30, 54],
17
+ [6, 32, 58],
18
+ [6, 34, 62],
19
+ [6, 26, 46, 66],
20
+ [6, 26, 48, 70],
21
+ [6, 26, 50, 74],
22
+ [6, 30, 54, 78],
23
+ [6, 30, 56, 82],
24
+ [6, 30, 58, 86],
25
+ [6, 34, 62, 90],
26
+ [6, 28, 50, 72, 94],
27
+ [6, 26, 50, 74, 98],
28
+ [6, 30, 54, 78, 102],
29
+ [6, 28, 54, 80, 106],
30
+ [6, 32, 58, 84, 110],
31
+ [6, 30, 58, 86, 114],
32
+ [6, 34, 62, 90, 118],
33
+ [6, 26, 50, 74, 98, 122],
34
+ [6, 30, 54, 78, 102, 126],
35
+ [6, 26, 52, 78, 104, 130],
36
+ [6, 30, 56, 82, 108, 134],
37
+ [6, 34, 60, 86, 112, 138],
38
+ [6, 30, 58, 86, 114, 142],
39
+ [6, 34, 62, 90, 118, 146],
40
+ [6, 30, 54, 78, 102, 126, 150],
41
+ [6, 24, 50, 76, 102, 128, 154],
42
+ [6, 28, 54, 80, 106, 132, 158],
43
+ [6, 32, 58, 84, 110, 136, 162],
44
+ [6, 26, 54, 82, 110, 138, 166],
45
+ [6, 30, 58, 86, 114, 142, 170]
46
+ ]
47
+
48
+ G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0
49
+ G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0
50
+ G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1
51
+
52
+ DEMERIT_POINTS_1 = 3
53
+ DEMERIT_POINTS_2 = 3
54
+ DEMERIT_POINTS_3 = 40
55
+ DEMERIT_POINTS_4 = 10
56
+
57
+ BITS_FOR_MODE = {
58
+ QRMODE[:mode_number] => [10, 12, 14],
59
+ QRMODE[:mode_alpha_numk] => [9, 11, 13],
60
+ QRMODE[:mode_8bit_byte] => [8, 16, 16],
61
+ QRMODE[:mode_kanji] => [8, 10, 12],
62
+ }
63
+
64
+ def QRUtil.max_size
65
+ PATTERN_POSITION_TABLE.count
66
+ end
67
+
68
+ def QRUtil.get_bch_format_info( data )
69
+ d = data << 10
70
+ while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15) >= 0
71
+ d ^= (G15 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15)))
72
+ end
73
+ (( data << 10 ) | d) ^ G15_MASK
74
+ end
75
+
76
+ def QRUtil.get_bch_version(data)
77
+ d = data << 12
78
+ while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18) >= 0
79
+ d ^= (G18 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18)))
80
+ end
81
+ ( data << 12 ) | d
82
+ end
83
+
84
+ def QRUtil.get_bch_digit( data )
85
+ digit = 0
86
+
87
+ while data != 0
88
+ digit = digit + 1
89
+ data = (data).rszf(1)
90
+ end
91
+
92
+ digit
93
+ end
94
+
95
+ def QRUtil.get_pattern_positions(version)
96
+ PATTERN_POSITION_TABLE[version - 1]
97
+ end
98
+
99
+ def QRUtil.get_mask( mask_pattern, i, j )
100
+ if mask_pattern > QRMASKCOMPUTATIONS.size
101
+ raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}"
102
+ end
103
+
104
+ return QRMASKCOMPUTATIONS[mask_pattern].call(i, j)
105
+ end
106
+
107
+ def QRUtil.get_error_correct_polynomial( error_correct_length )
108
+ a = QRPolynomial.new( [1], 0 )
109
+
110
+ ( 0...error_correct_length ).each do |i|
111
+ a = a.multiply( QRPolynomial.new( [1, QRMath.gexp(i)], 0 ) )
112
+ end
113
+
114
+ a
115
+ end
116
+
117
+ def QRUtil.get_length_in_bits(mode, version)
118
+ if !QRMODE.value?(mode)
119
+ raise QRCodeRunTimeError, "Unknown mode: #{mode}"
120
+ end
121
+
122
+ if version > 40
123
+ raise QRCodeRunTimeError, "Unknown version: #{version}"
124
+ end
125
+
126
+ if version.between?(1, 9)
127
+ # 1 - 9
128
+ macro_version = 0
129
+ elsif version <= 26
130
+ # 10 - 26
131
+ macro_version = 1
132
+ elsif version <= 40
133
+ # 27 - 40
134
+ macro_version = 2
135
+ end
136
+
137
+ return BITS_FOR_MODE[mode][macro_version]
138
+ end
139
+
140
+ def QRUtil.get_lost_points(modules)
141
+ demerit_points = 0
142
+
143
+ demerit_points += QRUtil.demerit_points_1_same_color(modules)
144
+ demerit_points += QRUtil.demerit_points_2_full_blocks(modules)
145
+ demerit_points += QRUtil.demerit_points_3_dangerous_patterns(modules)
146
+ demerit_points += QRUtil.demerit_points_4_dark_ratio(modules)
147
+
148
+ return demerit_points
149
+ end
150
+
151
+ def QRUtil.demerit_points_1_same_color(modules)
152
+ demerit_points = 0
153
+ module_count = modules.size
154
+
155
+ # level1
156
+ (0...module_count).each do |row|
157
+ (0...module_count).each do |col|
158
+ same_count = 0
159
+ dark = modules[row][col]
160
+
161
+ ( -1..1 ).each do |r|
162
+ next if row + r < 0 || module_count <= row + r
163
+
164
+ ( -1..1 ).each do |c|
165
+ next if col + c < 0 || module_count <= col + c
166
+ next if r == 0 && c == 0
167
+ if dark == modules[row + r][col + c]
168
+ same_count += 1
169
+ end
170
+ end
171
+ end
172
+
173
+ if same_count > 5
174
+ demerit_points += (DEMERIT_POINTS_1 + same_count - 5)
175
+ end
176
+ end
177
+ end
178
+
179
+ return demerit_points
180
+ end
181
+
182
+ def QRUtil.demerit_points_2_full_blocks(modules)
183
+ demerit_points = 0
184
+ module_count = modules.size
185
+
186
+ # level 2
187
+ (0...(module_count - 1)).each do |row|
188
+ (0...(module_count - 1)).each do |col|
189
+ count = 0
190
+ count += 1 if modules[row][col]
191
+ count += 1 if modules[row + 1][col]
192
+ count += 1 if modules[row][col + 1]
193
+ count += 1 if modules[row + 1][col + 1]
194
+ if (count == 0 || count == 4)
195
+ demerit_points += DEMERIT_POINTS_2
196
+ end
197
+ end
198
+ end
199
+
200
+ return demerit_points
201
+ end
202
+
203
+ def QRUtil.demerit_points_3_dangerous_patterns(modules)
204
+ demerit_points = 0
205
+ module_count = modules.size
206
+
207
+ # level 3
208
+ modules.each do |row|
209
+ (module_count - 6).times do |col_idx|
210
+ if row[col_idx] &&
211
+ !row[col_idx + 1] &&
212
+ row[col_idx + 2] &&
213
+ row[col_idx + 3] &&
214
+ row[col_idx + 4] &&
215
+ !row[col_idx + 5] &&
216
+ row[col_idx + 6]
217
+ demerit_points += DEMERIT_POINTS_3
218
+ end
219
+ end
220
+ end
221
+
222
+ (0...module_count).each do |col|
223
+ (0...(module_count - 6)).each do |row|
224
+ if modules[row][col] &&
225
+ !modules[row + 1][col] &&
226
+ modules[row + 2][col] &&
227
+ modules[row + 3][col] &&
228
+ modules[row + 4][col] &&
229
+ !modules[row + 5][col] &&
230
+ modules[row + 6][col]
231
+ demerit_points += DEMERIT_POINTS_3
232
+ end
233
+ end
234
+ end
235
+
236
+ return demerit_points
237
+ end
238
+
239
+ def QRUtil.demerit_points_4_dark_ratio(modules)
240
+ # level 4
241
+ dark_count = modules.reduce(0) do |sum, col|
242
+ sum + col.count(true)
243
+ end
244
+
245
+ ratio = dark_count / (modules.size * modules.size)
246
+ ratio_delta = (100 * ratio - 50).abs / 5
247
+
248
+ demerit_points = ratio_delta * DEMERIT_POINTS_4
249
+ return demerit_points
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RQRCodeCore
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,32 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "rqrcode_core/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rqrcode_core"
8
+ spec.version = RQRCodeCore::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Duncan Robertson"]
11
+ spec.email = ["duncan@whomwah.com"]
12
+
13
+ spec.summary = "A library to encode QR Codes"
14
+ spec.description = <<EOF
15
+ rqrcode_core is a Ruby library for encoding QR Codes. The simple
16
+ interface (with no runtime dependencies) allows you to create QR Code data structures.
17
+ EOF
18
+ spec.homepage = "https://github.com/whomwah/rqrcode_core"
19
+ spec.license = "MIT"
20
+
21
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.required_ruby_version = '~> 2.3'
29
+ spec.add_development_dependency "bundler", "~> 2.0"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "minitest", "~> 5.0"
32
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rqrcode_core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Duncan Robertson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-07-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: |
56
+ rqrcode_core is a Ruby library for encoding QR Codes. The simple
57
+ interface (with no runtime dependencies) allows you to create QR Code data structures.
58
+ email:
59
+ - duncan@whomwah.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - lib/rqrcode_core.rb
73
+ - lib/rqrcode_core/core_ext.rb
74
+ - lib/rqrcode_core/core_ext/array.rb
75
+ - lib/rqrcode_core/core_ext/array/behavior.rb
76
+ - lib/rqrcode_core/core_ext/integer.rb
77
+ - lib/rqrcode_core/core_ext/integer/bitwise.rb
78
+ - lib/rqrcode_core/qrcode.rb
79
+ - lib/rqrcode_core/qrcode/qr_8bit_byte.rb
80
+ - lib/rqrcode_core/qrcode/qr_alphanumeric.rb
81
+ - lib/rqrcode_core/qrcode/qr_bit_buffer.rb
82
+ - lib/rqrcode_core/qrcode/qr_code.rb
83
+ - lib/rqrcode_core/qrcode/qr_math.rb
84
+ - lib/rqrcode_core/qrcode/qr_numeric.rb
85
+ - lib/rqrcode_core/qrcode/qr_polynomial.rb
86
+ - lib/rqrcode_core/qrcode/qr_rs_block.rb
87
+ - lib/rqrcode_core/qrcode/qr_util.rb
88
+ - lib/rqrcode_core/version.rb
89
+ - rqrcode_core.gemspec
90
+ homepage: https://github.com/whomwah/rqrcode_core
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.3'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.0.1
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: A library to encode QR Codes
113
+ test_files: []