rqrcode 0.1.0 → 0.2.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.
- data/CHANGELOG +6 -1
- data/COPYING +19 -0
- data/README +44 -44
- data/lib/rqrcode/core_ext/array.rb +1 -1
- data/lib/rqrcode/core_ext/array/behavior.rb +2 -2
- data/lib/rqrcode/core_ext/integer.rb +1 -1
- data/lib/rqrcode/core_ext/integer/bitwise.rb +2 -2
- data/lib/rqrcode/extensions.rb +0 -0
- data/lib/rqrcode/extensions/image.rb +1006 -0
- data/lib/rqrcode/qrcode.rb +3 -923
- data/lib/rqrcode/qrcode/qr_8bit_byte.rb +35 -0
- data/lib/rqrcode/qrcode/qr_bit_buffer.rb +56 -0
- data/lib/rqrcode/qrcode/qr_code.rb +394 -0
- data/lib/rqrcode/qrcode/qr_math.rb +63 -0
- data/lib/rqrcode/qrcode/qr_polynomial.rb +78 -0
- data/lib/rqrcode/qrcode/qr_rs_block.rb +134 -0
- data/lib/rqrcode/qrcode/qr_util.rb +254 -0
- data/test/{unit/qrcode_test.rb → runtest.rb} +2 -1
- metadata +23 -22
- data/test/test_helper.rb +0 -2
- data/test/unit/test_data.rb +0 -21
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRMath
|
15
|
+
|
16
|
+
module_eval {
|
17
|
+
exp_table = Array.new(256)
|
18
|
+
log_table = Array.new(256)
|
19
|
+
|
20
|
+
( 0...8 ).each do |i|
|
21
|
+
exp_table[i] = 1 << i
|
22
|
+
end
|
23
|
+
|
24
|
+
( 8...256 ).each do |i|
|
25
|
+
exp_table[i] = exp_table[i - 4] \
|
26
|
+
^ exp_table[i - 5] \
|
27
|
+
^ exp_table[i - 6] \
|
28
|
+
^ exp_table[i - 8]
|
29
|
+
end
|
30
|
+
|
31
|
+
( 0...255 ).each do |i|
|
32
|
+
log_table[exp_table[i] ] = i
|
33
|
+
end
|
34
|
+
|
35
|
+
EXP_TABLE = exp_table
|
36
|
+
LOG_TABLE = log_table
|
37
|
+
}
|
38
|
+
|
39
|
+
class << self
|
40
|
+
|
41
|
+
def glog(n)
|
42
|
+
raise QRCodeRunTimeError, "glog(#{n})" if ( n < 1 )
|
43
|
+
LOG_TABLE[n]
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def gexp(n)
|
48
|
+
while n < 0
|
49
|
+
n = n + 255
|
50
|
+
end
|
51
|
+
|
52
|
+
while n >= 256
|
53
|
+
n = n - 255
|
54
|
+
end
|
55
|
+
|
56
|
+
EXP_TABLE[n]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRPolynomial
|
15
|
+
|
16
|
+
def initialize( num, shift )
|
17
|
+
raise QRCodeRunTimeError, "#{num.size}/#{shift}" if num.empty?
|
18
|
+
offset = 0
|
19
|
+
|
20
|
+
while offset < num.size && num[offset] == 0
|
21
|
+
offset = offset + 1
|
22
|
+
end
|
23
|
+
|
24
|
+
@num = Array.new( num.size - offset + shift )
|
25
|
+
|
26
|
+
( 0...num.size - offset ).each do |i|
|
27
|
+
@num[i] = num[i + offset]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def get( index )
|
33
|
+
@num[index]
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_length
|
38
|
+
@num.size
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def multiply( e )
|
43
|
+
num = Array.new( get_length + e.get_length - 1 )
|
44
|
+
|
45
|
+
( 0...get_length ).each do |i|
|
46
|
+
( 0...e.get_length ).each do |j|
|
47
|
+
tmp = num[i + j].nil? ? 0 : num[i + j]
|
48
|
+
num[i + j] = tmp ^ QRMath.gexp(QRMath.glog( get(i) ) + QRMath.glog(e.get(j)))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return QRPolynomial.new( num, 0 )
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def mod( e )
|
57
|
+
if get_length - e.get_length < 0
|
58
|
+
return self
|
59
|
+
end
|
60
|
+
|
61
|
+
ratio = QRMath.glog(get(0)) - QRMath.glog(e.get(0))
|
62
|
+
num = Array.new(get_length)
|
63
|
+
|
64
|
+
( 0...get_length ).each do |i|
|
65
|
+
num[i] = get(i)
|
66
|
+
end
|
67
|
+
|
68
|
+
( 0...e.get_length ).each do |i|
|
69
|
+
tmp = num[i].nil? ? 0 : num[i]
|
70
|
+
num[i] = tmp ^ QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
|
71
|
+
end
|
72
|
+
|
73
|
+
return QRPolynomial.new( num, 0 ).mod(e)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRRSBlock
|
15
|
+
attr_reader :data_count, :total_count
|
16
|
+
|
17
|
+
def initialize( total_count, data_count )
|
18
|
+
@total_count = total_count
|
19
|
+
@data_count = data_count
|
20
|
+
end
|
21
|
+
|
22
|
+
RS_BLOCK_TABLE = [
|
23
|
+
|
24
|
+
# L
|
25
|
+
# M
|
26
|
+
# Q
|
27
|
+
# H
|
28
|
+
|
29
|
+
# 1
|
30
|
+
[1, 26, 19],
|
31
|
+
[1, 26, 16],
|
32
|
+
[1, 26, 13],
|
33
|
+
[1, 26, 9],
|
34
|
+
|
35
|
+
# 2
|
36
|
+
[1, 44, 34],
|
37
|
+
[1, 44, 28],
|
38
|
+
[1, 44, 22],
|
39
|
+
[1, 44, 16],
|
40
|
+
|
41
|
+
# 3
|
42
|
+
[1, 70, 55],
|
43
|
+
[1, 70, 44],
|
44
|
+
[2, 35, 17],
|
45
|
+
[2, 35, 13],
|
46
|
+
|
47
|
+
# 4
|
48
|
+
[1, 100, 80],
|
49
|
+
[2, 50, 32],
|
50
|
+
[2, 50, 24],
|
51
|
+
[4, 25, 9],
|
52
|
+
|
53
|
+
# 5
|
54
|
+
[1, 134, 108],
|
55
|
+
[2, 67, 43],
|
56
|
+
[2, 33, 15, 2, 34, 16],
|
57
|
+
[2, 33, 11, 2, 34, 12],
|
58
|
+
|
59
|
+
# 6
|
60
|
+
[2, 86, 68],
|
61
|
+
[4, 43, 27],
|
62
|
+
[4, 43, 19],
|
63
|
+
[4, 43, 15],
|
64
|
+
|
65
|
+
# 7
|
66
|
+
[2, 98, 78],
|
67
|
+
[4, 49, 31],
|
68
|
+
[2, 32, 14, 4, 33, 15],
|
69
|
+
[4, 39, 13, 1, 40, 14],
|
70
|
+
|
71
|
+
# 8
|
72
|
+
[2, 121, 97],
|
73
|
+
[2, 60, 38, 2, 61, 39],
|
74
|
+
[4, 40, 18, 2, 41, 19],
|
75
|
+
[4, 40, 14, 2, 41, 15],
|
76
|
+
|
77
|
+
# 9
|
78
|
+
[2, 146, 116],
|
79
|
+
[3, 58, 36, 2, 59, 37],
|
80
|
+
[4, 36, 16, 4, 37, 17],
|
81
|
+
[4, 36, 12, 4, 37, 13],
|
82
|
+
|
83
|
+
# 10
|
84
|
+
[2, 86, 68, 2, 87, 69],
|
85
|
+
[4, 69, 43, 1, 70, 44],
|
86
|
+
[6, 43, 19, 2, 44, 20],
|
87
|
+
[6, 43, 15, 2, 44, 16]
|
88
|
+
|
89
|
+
]
|
90
|
+
|
91
|
+
|
92
|
+
def QRRSBlock.get_rs_blocks( type_no, error_correct_level )
|
93
|
+
rs_block = QRRSBlock.get_rs_block_table( type_no, error_correct_level )
|
94
|
+
|
95
|
+
if rs_block.nil?
|
96
|
+
raise QRCodeRunTimeError,
|
97
|
+
"bad rsblock @ typeno: #{type_no}/error_correct_level:#{error_correct_level}"
|
98
|
+
end
|
99
|
+
|
100
|
+
length = rs_block.size / 3
|
101
|
+
list = []
|
102
|
+
|
103
|
+
( 0...length ).each do |i|
|
104
|
+
count = rs_block[i * 3 + 0]
|
105
|
+
total_count = rs_block[i * 3 + 1]
|
106
|
+
data_count = rs_block[i * 3 + 2]
|
107
|
+
|
108
|
+
( 0...count ).each do |j|
|
109
|
+
list << QRRSBlock.new( total_count, data_count )
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
list
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def QRRSBlock.get_rs_block_table( type_number, error_correct_level )
|
118
|
+
case error_correct_level
|
119
|
+
when QRERRORCORRECTLEVEL[:l]
|
120
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 0]
|
121
|
+
when QRERRORCORRECTLEVEL[:m]
|
122
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 1]
|
123
|
+
when QRERRORCORRECTLEVEL[:q]
|
124
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 2]
|
125
|
+
when QRERRORCORRECTLEVEL[:h]
|
126
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 3]
|
127
|
+
else
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRUtil
|
15
|
+
|
16
|
+
PATTERN_POSITION_TABLE = [
|
17
|
+
|
18
|
+
[],
|
19
|
+
[6, 18],
|
20
|
+
[6, 22],
|
21
|
+
[6, 26],
|
22
|
+
[6, 30],
|
23
|
+
[6, 34],
|
24
|
+
[6, 22, 38],
|
25
|
+
[6, 24, 42],
|
26
|
+
[6, 26, 46],
|
27
|
+
[6, 28, 50],
|
28
|
+
[6, 30, 54],
|
29
|
+
[6, 32, 58],
|
30
|
+
[6, 34, 62],
|
31
|
+
[6, 26, 46, 66],
|
32
|
+
[6, 26, 48, 70],
|
33
|
+
[6, 26, 50, 74],
|
34
|
+
[6, 30, 54, 78],
|
35
|
+
[6, 30, 56, 82],
|
36
|
+
[6, 30, 58, 86],
|
37
|
+
[6, 34, 62, 90],
|
38
|
+
[6, 28, 50, 72, 94],
|
39
|
+
[6, 26, 50, 74, 98],
|
40
|
+
[6, 30, 54, 78, 102],
|
41
|
+
[6, 28, 54, 80, 106],
|
42
|
+
[6, 32, 58, 84, 110],
|
43
|
+
[6, 30, 58, 86, 114],
|
44
|
+
[6, 34, 62, 90, 118],
|
45
|
+
[6, 26, 50, 74, 98, 122],
|
46
|
+
[6, 30, 54, 78, 102, 126],
|
47
|
+
[6, 26, 52, 78, 104, 130],
|
48
|
+
[6, 30, 56, 82, 108, 134],
|
49
|
+
[6, 34, 60, 86, 112, 138],
|
50
|
+
[6, 30, 58, 86, 114, 142],
|
51
|
+
[6, 34, 62, 90, 118, 146],
|
52
|
+
[6, 30, 54, 78, 102, 126, 150],
|
53
|
+
[6, 24, 50, 76, 102, 128, 154],
|
54
|
+
[6, 28, 54, 80, 106, 132, 158],
|
55
|
+
[6, 32, 58, 84, 110, 136, 162],
|
56
|
+
[6, 26, 54, 82, 110, 138, 166],
|
57
|
+
[6, 30, 58, 86, 114, 142, 170]
|
58
|
+
]
|
59
|
+
|
60
|
+
G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0
|
61
|
+
G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0
|
62
|
+
G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1
|
63
|
+
|
64
|
+
|
65
|
+
def QRUtil.get_bch_type_info( data )
|
66
|
+
d = data << 10
|
67
|
+
while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15) >= 0
|
68
|
+
d ^= (G15 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15)))
|
69
|
+
end
|
70
|
+
(( data << 10 ) | d) ^ G15_MASK
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def QRUtil.get_bch_type_number( data )
|
75
|
+
d = data << 12
|
76
|
+
while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18) >= 0
|
77
|
+
d ^= (G18 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18)))
|
78
|
+
end
|
79
|
+
( data << 12 ) | d
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def QRUtil.get_bch_digit( data )
|
84
|
+
digit = 0
|
85
|
+
|
86
|
+
while data != 0
|
87
|
+
digit = digit + 1
|
88
|
+
data = (data).rszf(1)
|
89
|
+
end
|
90
|
+
|
91
|
+
digit
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def QRUtil.get_pattern_position( type_number )
|
96
|
+
PATTERN_POSITION_TABLE[ type_number - 1 ]
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def QRUtil.get_mask( mask_pattern, i, j )
|
101
|
+
case mask_pattern
|
102
|
+
when QRMASKPATTERN[:pattern000]
|
103
|
+
(i + j) % 2 == 0
|
104
|
+
when QRMASKPATTERN[:pattern001]
|
105
|
+
i % 2 == 0
|
106
|
+
when QRMASKPATTERN[:pattern010]
|
107
|
+
j % 3 == 0
|
108
|
+
when QRMASKPATTERN[:pattern011]
|
109
|
+
(i + j) % 3 == 0
|
110
|
+
when QRMASKPATTERN[:pattern100]
|
111
|
+
((i / 2).floor + (j / 3).floor ) % 2 == 0
|
112
|
+
when QRMASKPATTERN[:pattern101]
|
113
|
+
(i * j) % 2 + (i * j) % 3 == 0
|
114
|
+
when QRMASKPATTERN[:pattern110]
|
115
|
+
( (i * j) % 2 + (i * j) % 3) % 2 == 0
|
116
|
+
when QRMASKPATTERN[:pattern111]
|
117
|
+
( (i * j) % 3 + (i + j) % 2) % 2 == 0
|
118
|
+
else
|
119
|
+
raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def QRUtil.get_error_correct_polynomial( error_correct_length )
|
125
|
+
a = QRPolynomial.new( [1], 0 )
|
126
|
+
|
127
|
+
( 0...error_correct_length ).each do |i|
|
128
|
+
a = a.multiply( QRPolynomial.new( [1, QRMath.gexp(i)], 0 ) )
|
129
|
+
end
|
130
|
+
|
131
|
+
a
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def QRUtil.get_length_in_bits( mode, type )
|
136
|
+
if 1 <= type && type < 10
|
137
|
+
|
138
|
+
# 1 - 9
|
139
|
+
case mode
|
140
|
+
when QRMODE[:mode_number] : 10
|
141
|
+
when QRMODE[:mode_alpha_num] : 9
|
142
|
+
when QRMODE[:mode_8bit_byte] : 8
|
143
|
+
when QRMODE[:mode_kanji] : 8
|
144
|
+
else
|
145
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
146
|
+
end
|
147
|
+
|
148
|
+
elsif type < 27
|
149
|
+
|
150
|
+
# 10 -26
|
151
|
+
case mode
|
152
|
+
when QRMODE[:mode_number] : 12
|
153
|
+
when QRMODE[:mode_alpha_num] : 11
|
154
|
+
when QRMODE[:mode_8bit_byte] : 16
|
155
|
+
when QRMODE[:mode_kanji] : 10
|
156
|
+
else
|
157
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
158
|
+
end
|
159
|
+
|
160
|
+
elsif type < 41
|
161
|
+
|
162
|
+
# 27 - 40
|
163
|
+
case mode
|
164
|
+
when QRMODE[:mode_number] : 14
|
165
|
+
when QRMODE[:mode_alpha_num] : 13
|
166
|
+
when QRMODE[:mode_8bit_byte] : 16
|
167
|
+
when QRMODE[:mode_kanji] : 12
|
168
|
+
else
|
169
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
170
|
+
end
|
171
|
+
|
172
|
+
else
|
173
|
+
raise QRCodeRunTimeError, "type: #{type}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def QRUtil.get_lost_point( qr_code )
|
179
|
+
module_count = qr_code.module_count
|
180
|
+
lost_point = 0
|
181
|
+
|
182
|
+
# level1
|
183
|
+
( 0...module_count ).each do |row|
|
184
|
+
( 0...module_count ).each do |col|
|
185
|
+
same_count = 0
|
186
|
+
dark = qr_code.is_dark( row, col )
|
187
|
+
|
188
|
+
( -1..1 ).each do |r|
|
189
|
+
next if row + r < 0 || module_count <= row + r
|
190
|
+
|
191
|
+
( -1..1 ).each do |c|
|
192
|
+
next if col + c < 0 || module_count <= col + c
|
193
|
+
next if r == 0 && c == 0
|
194
|
+
if dark == qr_code.is_dark( row + r, col + c )
|
195
|
+
same_count += 1
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
if same_count > 5
|
201
|
+
lost_point += (3 + same_count - 5)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# level 2
|
207
|
+
( 0...( module_count - 1 ) ).each do |row|
|
208
|
+
( 0...( module_count - 1 ) ).each do |col|
|
209
|
+
count = 0
|
210
|
+
count = count + 1 if qr_code.is_dark( row, col )
|
211
|
+
count = count + 1 if qr_code.is_dark( row + 1, col )
|
212
|
+
count = count + 1 if qr_code.is_dark( row, col + 1 )
|
213
|
+
count = count + 1 if qr_code.is_dark( row + 1, col + 1 )
|
214
|
+
lost_point = lost_point + 3 if (count == 0 || count == 4)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# level 3
|
219
|
+
( 0...module_count ).each do |row|
|
220
|
+
( 0...( module_count - 6 ) ).each do |col|
|
221
|
+
if qr_code.is_dark( row, col ) && !qr_code.is_dark( row, col + 1 ) && qr_code.is_dark( row, col + 2 ) && qr_code.is_dark( row, col + 3 ) && qr_code.is_dark( row, col + 4 ) && !qr_code.is_dark( row, col + 5 ) && qr_code.is_dark( row, col + 6 )
|
222
|
+
lost_point = lost_point + 40
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
( 0...module_count ).each do |col|
|
228
|
+
( 0...( module_count - 6 ) ).each do |row|
|
229
|
+
if qr_code.is_dark(row, col) && !qr_code.is_dark(row + 1, col) && qr_code.is_dark(row + 2, col) && qr_code.is_dark(row + 3, col) && qr_code.is_dark(row + 4, col) && !qr_code.is_dark(row + 5, col) && qr_code.is_dark(row + 6, col)
|
230
|
+
lost_point = lost_point + 40
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# level 4
|
236
|
+
dark_count = 0
|
237
|
+
|
238
|
+
( 0...module_count ).each do |col|
|
239
|
+
( 0...module_count ).each do |row|
|
240
|
+
if qr_code.is_dark(row, col)
|
241
|
+
dark_count = dark_count + 1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
ratio = (100 * dark_count / module_count / module_count - 50).abs / 5
|
247
|
+
lost_point = lost_point * 10
|
248
|
+
|
249
|
+
lost_point
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|