crc 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.ja.md +22 -0
- data/README.md +140 -30
- data/benchmark.rb +15 -9
- data/gemstub.rb +6 -5
- data/lib/crc.rb +211 -220
- data/lib/crc/_byruby.rb +89 -65
- data/lib/crc/_combine.rb +5 -5
- data/lib/crc/_modules.rb +24 -23
- data/lib/crc/acrc.rb +195 -0
- data/lib/crc/finder.rb +4 -4
- data/lib/crc/version.rb +5 -0
- metadata +12 -10
data/lib/crc/_byruby.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
# \* \* \* \* \* \* \* \*
|
10
10
|
#
|
11
11
|
# Ruby implemented CRC generator.
|
12
|
-
# It's used slice-by-16 algorithm with byte-order free
|
12
|
+
# It's used slice-by-16 algorithm with byte-order free.
|
13
13
|
# This is based on the Intel's slice-by-eight algorithm.
|
14
14
|
#
|
15
15
|
# It's faster than about 50% (CRC-32) and about 30% (CRC-64) of
|
@@ -26,69 +26,46 @@
|
|
26
26
|
#
|
27
27
|
# If defined "RUBY_CRC_NOFAST=3" enviroment variable, switch to reference algorithm.
|
28
28
|
#
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def bitreflect16(n)
|
39
|
-
n = n.to_i
|
40
|
-
n = ((n & 0x5555) << 1) | ((n >> 1) & 0x5555)
|
41
|
-
n = ((n & 0x3333) << 2) | ((n >> 2) & 0x3333)
|
42
|
-
n = ((n & 0x0f0f) << 4) | ((n >> 4) & 0x0f0f)
|
43
|
-
return ((n & 0x00ff) << 8) | (n >> 8) # 0x00ff
|
44
|
-
end
|
45
|
-
|
46
|
-
def bitreflect32(n)
|
47
|
-
n = n.to_i
|
48
|
-
n = ((n & 0x55555555) << 1) | ((n >> 1) & 0x55555555)
|
49
|
-
n = ((n & 0x33333333) << 2) | ((n >> 2) & 0x33333333)
|
50
|
-
n = ((n & 0x0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f)
|
51
|
-
n = ((n & 0x00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff)
|
52
|
-
return ((n & 0x0000ffff) << 16) | (n >> 16) # 0x0000ffff
|
53
|
-
end
|
54
|
-
|
55
|
-
def bitreflect64(n)
|
56
|
-
n = n.to_i
|
57
|
-
n = ((n & 0x5555555555555555) << 1) | ((n >> 1) & 0x5555555555555555)
|
58
|
-
n = ((n & 0x3333333333333333) << 2) | ((n >> 2) & 0x3333333333333333)
|
59
|
-
n = ((n & 0x0f0f0f0f0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f0f0f0f0f)
|
60
|
-
n = ((n & 0x00ff00ff00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff00ff00ff)
|
61
|
-
n = ((n & 0x0000ffff0000ffff) << 16) | ((n >> 16) & 0x0000ffff0000ffff)
|
62
|
-
return ((n & 0x00000000ffffffff) << 32) | (n >> 32) # 0x00000000ffffffff
|
63
|
-
end
|
64
|
-
|
65
|
-
def bitreflect128(n)
|
66
|
-
n = n.to_i
|
67
|
-
n = ((n & 0x55555555555555555555555555555555) << 1) | ((n >> 1) & 0x55555555555555555555555555555555)
|
68
|
-
n = ((n & 0x33333333333333333333333333333333) << 2) | ((n >> 2) & 0x33333333333333333333333333333333)
|
69
|
-
n = ((n & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f)
|
70
|
-
n = ((n & 0x00ff00ff00ff00ff00ff00ff00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff)
|
71
|
-
n = ((n & 0x0000ffff0000ffff0000ffff0000ffff) << 16) | ((n >> 16) & 0x0000ffff0000ffff0000ffff0000ffff)
|
72
|
-
n = ((n & 0x00000000ffffffff00000000ffffffff) << 32) | ((n >> 32) & 0x00000000ffffffff00000000ffffffff)
|
73
|
-
return ((n & 0x0000000000000000ffffffffffffffff) << 64) | (n >> 64) # 0x0000000000000000ffffffffffffffff
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class Generator < Struct.new(:bitsize, :bitmask, :polynomial, :initial_state, :table, :reflect_input, :reflect_output, :xor_output, :name)
|
78
|
-
BasicStruct = superclass
|
79
|
-
|
80
|
-
def initialize(bitsize, polynomial, initial_state = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil)
|
29
|
+
class CRC
|
30
|
+
class << self
|
31
|
+
#
|
32
|
+
# call-seq:
|
33
|
+
# new(bitsize, polynomial, initial_crc = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil) -> new crc module class (CRC based class)
|
34
|
+
# new(initial_crc = nil, size = 0) -> new crc generator (CRC instance)
|
35
|
+
# new(seq, initial_crc = nil, size = 0) -> new crc generator (CRC instance)
|
36
|
+
#
|
37
|
+
def new(bitsize, polynomial, initial_crc = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil)
|
81
38
|
bitsize = bitsize.to_i
|
82
39
|
if bitsize < 1 || bitsize > 64
|
83
40
|
raise ArgumentError, "wrong bitsize (except 1..64, but given #{bitsize})"
|
84
41
|
end
|
42
|
+
|
85
43
|
bitmask = ~(~0 << bitsize)
|
86
44
|
polynomial = bitmask & polynomial
|
87
|
-
|
45
|
+
initial_crc = bitmask & initial_crc
|
88
46
|
xor_output = bitmask & xor_output
|
89
47
|
name = (name.nil? || ((name = String(name)).empty?)) ? nil : name
|
90
|
-
|
91
|
-
|
48
|
+
|
49
|
+
::Class.new(self) do
|
50
|
+
@bitsize = bitsize
|
51
|
+
@bitmask = bitmask
|
52
|
+
@polynomial = polynomial
|
53
|
+
@initial_crc = initial_crc
|
54
|
+
@table = nil
|
55
|
+
@reflect_input = !!reflect_input
|
56
|
+
@reflect_output = !!reflect_output
|
57
|
+
@xor_output = xor_output
|
58
|
+
@name = name
|
59
|
+
|
60
|
+
# CRC クラスを普通に派生させた場合でも、CRC.new の基底メソッドが呼ばれるための細工
|
61
|
+
define_singleton_method(:new, &Class.instance_method(:new).bind(self))
|
62
|
+
|
63
|
+
singleton_class.class_eval do
|
64
|
+
alias_method :[], :new
|
65
|
+
end
|
66
|
+
|
67
|
+
extend CRC::ModuleClass
|
68
|
+
end
|
92
69
|
end
|
93
70
|
|
94
71
|
def update_with_reference(seq, state)
|
@@ -204,14 +181,14 @@ module CRC
|
|
204
181
|
|
205
182
|
def table
|
206
183
|
if reflect_input
|
207
|
-
|
184
|
+
@table = CRC.build_reflect_table(bitsize, polynomial, slice: 16)
|
208
185
|
else
|
209
|
-
|
186
|
+
@table = CRC.build_table(bitsize, polynomial, slice: 16)
|
210
187
|
end
|
211
188
|
|
212
|
-
|
189
|
+
singleton_class.class_eval "attr_reader :table"
|
213
190
|
|
214
|
-
|
191
|
+
@table
|
215
192
|
end
|
216
193
|
|
217
194
|
case ENV["RUBY_CRC_NOFAST"].to_i
|
@@ -222,13 +199,60 @@ module CRC
|
|
222
199
|
else
|
223
200
|
alias update update_with_reference
|
224
201
|
end
|
202
|
+
end
|
203
|
+
|
204
|
+
module ModuleClass
|
205
|
+
attr_reader :bitsize, :bitmask, :polynomial, :initial_crc,
|
206
|
+
:reflect_input, :reflect_output, :xor_output, :name
|
207
|
+
|
208
|
+
alias reflect_input? reflect_input
|
209
|
+
alias reflect_output? reflect_output
|
210
|
+
end
|
211
|
+
|
212
|
+
module Utils
|
213
|
+
def bitreflect8(n)
|
214
|
+
n = n.to_i
|
215
|
+
n = ((n & 0x55) << 1) | ((n >> 1) & 0x55)
|
216
|
+
n = ((n & 0x33) << 2) | ((n >> 2) & 0x33)
|
217
|
+
return ((n & 0x0f) << 4) | (n >> 4) # 0x0f
|
218
|
+
end
|
225
219
|
|
226
|
-
|
227
|
-
|
228
|
-
|
220
|
+
def bitreflect16(n)
|
221
|
+
n = n.to_i
|
222
|
+
n = ((n & 0x5555) << 1) | ((n >> 1) & 0x5555)
|
223
|
+
n = ((n & 0x3333) << 2) | ((n >> 2) & 0x3333)
|
224
|
+
n = ((n & 0x0f0f) << 4) | ((n >> 4) & 0x0f0f)
|
225
|
+
return ((n & 0x00ff) << 8) | (n >> 8) # 0x00ff
|
226
|
+
end
|
229
227
|
|
230
|
-
|
231
|
-
|
228
|
+
def bitreflect32(n)
|
229
|
+
n = n.to_i
|
230
|
+
n = ((n & 0x55555555) << 1) | ((n >> 1) & 0x55555555)
|
231
|
+
n = ((n & 0x33333333) << 2) | ((n >> 2) & 0x33333333)
|
232
|
+
n = ((n & 0x0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f)
|
233
|
+
n = ((n & 0x00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff)
|
234
|
+
return ((n & 0x0000ffff) << 16) | (n >> 16) # 0x0000ffff
|
235
|
+
end
|
236
|
+
|
237
|
+
def bitreflect64(n)
|
238
|
+
n = n.to_i
|
239
|
+
n = ((n & 0x5555555555555555) << 1) | ((n >> 1) & 0x5555555555555555)
|
240
|
+
n = ((n & 0x3333333333333333) << 2) | ((n >> 2) & 0x3333333333333333)
|
241
|
+
n = ((n & 0x0f0f0f0f0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f0f0f0f0f)
|
242
|
+
n = ((n & 0x00ff00ff00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff00ff00ff)
|
243
|
+
n = ((n & 0x0000ffff0000ffff) << 16) | ((n >> 16) & 0x0000ffff0000ffff)
|
244
|
+
return ((n & 0x00000000ffffffff) << 32) | (n >> 32) # 0x00000000ffffffff
|
245
|
+
end
|
246
|
+
|
247
|
+
def bitreflect128(n)
|
248
|
+
n = n.to_i
|
249
|
+
n = ((n & 0x55555555555555555555555555555555) << 1) | ((n >> 1) & 0x55555555555555555555555555555555)
|
250
|
+
n = ((n & 0x33333333333333333333333333333333) << 2) | ((n >> 2) & 0x33333333333333333333333333333333)
|
251
|
+
n = ((n & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f)
|
252
|
+
n = ((n & 0x00ff00ff00ff00ff00ff00ff00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff)
|
253
|
+
n = ((n & 0x0000ffff0000ffff0000ffff0000ffff) << 16) | ((n >> 16) & 0x0000ffff0000ffff0000ffff0000ffff)
|
254
|
+
n = ((n & 0x00000000ffffffff00000000ffffffff) << 32) | ((n >> 32) & 0x00000000ffffffff00000000ffffffff)
|
255
|
+
return ((n & 0x0000000000000000ffffffffffffffff) << 64) | (n >> 64) # 0x0000000000000000ffffffffffffffff
|
232
256
|
end
|
233
257
|
end
|
234
258
|
end
|
data/lib/crc/_combine.rb
CHANGED
@@ -33,7 +33,7 @@
|
|
33
33
|
# License:: zlib-style
|
34
34
|
#--
|
35
35
|
|
36
|
-
|
36
|
+
class CRC
|
37
37
|
module Aux
|
38
38
|
def self.gf2_matrix_times(matrix, vector)
|
39
39
|
sum = 0
|
@@ -53,13 +53,13 @@ module CRC
|
|
53
53
|
|
54
54
|
nil
|
55
55
|
end
|
56
|
-
end
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
def self.combine(crc1, crc2, len2,
|
58
|
+
bitsize, polynomial, initial_crc,
|
59
|
+
reflect_input, reflect_output, xor_output)
|
60
60
|
return crc1 unless len2 > 1
|
61
61
|
|
62
|
-
crc1 ^=
|
62
|
+
crc1 ^= initial_crc
|
63
63
|
|
64
64
|
odd = []
|
65
65
|
even = []
|
data/lib/crc/_modules.rb
CHANGED
@@ -12,12 +12,13 @@
|
|
12
12
|
# * https://github.com/cluelogic/cluelib/blob/master/src/cl_crc.svh
|
13
13
|
# * https://users.ece.cmu.edu/~koopman/crc/hw_data.html
|
14
14
|
# * https://users.ece.cmu.edu/~koopman/roses/dsn04/koopman04_crc_poly_embedded.pdf
|
15
|
+
# * (CRC-64-ISO-3309) http://swissknife.cvs.sourceforge.net/viewvc/swissknife/SWISS/lib/SWISS/CRC64.pm
|
15
16
|
#++
|
16
17
|
|
17
|
-
|
18
|
+
class CRC
|
18
19
|
LIST = [
|
19
20
|
#
|
20
|
-
# bit size, polynomial,
|
21
|
+
# bit size, polynomial, initial crc,
|
21
22
|
# refrect input, xor output,
|
22
23
|
# reflect output, crc("123456789"), names...
|
23
24
|
#
|
@@ -33,10 +34,10 @@ module CRC
|
|
33
34
|
[ 6, 0x19, true, true, 0, 0, 0x26, "CRC-6-DARC"],
|
34
35
|
[ 6, 0x03, true, true, 0, 0, 0x06, "CRC-6-ITU"],
|
35
36
|
[ 7, 0x09, false, false, 0, 0, 0x75, "CRC-7", "CRC-7-JESD84-A441"],
|
36
|
-
[ 7, 0x65, false, false, 0, 0, nil, "CRC-7-MVB"],
|
37
|
+
#[ 7, 0x65, false, false, 0, 0, nil, "CRC-7-MVB"],
|
37
38
|
[ 7, 0x4F, true, true, ~0, 0, 0x53, "CRC-7-ROHC", "CRC-7-RFC 3095"],
|
38
39
|
[ 7, 0x45, false, false, 0, 0, 0x61, "CRC-7-UMTS"],
|
39
|
-
[ 8, 0xD5, false, false, 0, 0, nil, "CRC-8"],
|
40
|
+
#[ 8, 0xD5, false, false, 0, 0, nil, "CRC-8"],
|
40
41
|
[ 8, 0x07, false, false, 0, 0, 0xF4, "CRC-8-CCITT", "CRC-8-SMBus"],
|
41
42
|
[ 8, 0x31, true, true, 0, 0, 0xA1, "CRC-8-MAXIM", "CRC-8-Dallas/Maxim", "DOW-CRC"],
|
42
43
|
[ 8, 0x39, true, true, 0, 0, 0x15, "CRC-8-DARC"],
|
@@ -60,9 +61,9 @@ module CRC
|
|
60
61
|
[14, 0x0805, true, true, 0, 0, 0x082D, "CRC-14-DARC"],
|
61
62
|
[15, 0x4599, false, false, 0, 0, 0x059E, "CRC-15", "CRC-15-CAN"],
|
62
63
|
[15, 0x6815, false, false, 1, 1, 0x2566, "CRC-15-MPT1327"],
|
63
|
-
[16, 0x2F15, false, false, 0, 0, nil, "Chakravarty"],
|
64
|
-
[16, 0x8005, true, true, 0, 0, 0xBB3D, "
|
65
|
-
[16, 0xA02B, false, false, 0, 0, nil, "CRC-16-ARINC"],
|
64
|
+
#[16, 0x2F15, false, false, 0, 0, nil, "Chakravarty"],
|
65
|
+
[16, 0x8005, true, true, 0, 0, 0xBB3D, "CRC-16", "ARC", "CRC-IBM", "CRC-16-ARC", "CRC-16-LHA"],
|
66
|
+
#[16, 0xA02B, false, false, 0, 0, nil, "CRC-16-ARINC"],
|
66
67
|
[16, 0x1021, false, false, 0x1D0F, 0, 0xE5CC, "CRC-16-AUG-CCITT", "CRC-16-SPI-FUJITSU"],
|
67
68
|
[16, 0xC867, false, false, ~0, 0, 0x4C06, "CRC-16-CDMA2000"],
|
68
69
|
[16, 0x0589, false, false, 1, 1, 0x007E, "CRC-16-DECT-R", "R-CRC-16"],
|
@@ -81,14 +82,14 @@ module CRC
|
|
81
82
|
[16, 0xA097, false, false, 0, 0, 0x0FB3, "CRC-16-TELEDISK"],
|
82
83
|
[16, 0x1021, true, true, 0x89EC, 0, 0x26B1, "CRC-16-TMS37157"],
|
83
84
|
[16, 0x8005, true, true, 0, ~0, 0xB4C8, "CRC-16-USB"],
|
84
|
-
[16, 0x1021, true, true, 0xC6C6, 0, 0xBF05, "CRC-A", "CRC-16-ISO/IEC FCD 14443-3"],
|
85
|
-
[16, 0x1021, true, true, 0, 0, 0x2189, "KERMIT", "CRC-16-CCITT", "CRC-16-CCITT-TRUE", "CRC-CCITT"],
|
86
|
-
[16, 0x8005, true, true, ~0, 0, 0x4B37, "MODBUS"],
|
87
|
-
[16, 0x1021, true, true, 0, ~0, 0x906E, "X-25", "CRC-16-IBM-SDLC", "CRC-16-ISO-HDLC", "CRC-B"],
|
88
|
-
[16, 0x1021, false, false, 0, 0, 0x31C3, "XMODEM", "ZMODEM", "CRC-16-ACORN", "CRC-16-LTE"],
|
89
|
-
[17, 0x0001685B, false, false, 0, 0, nil, "CRC-17-CAN"],
|
90
|
-
[21, 0x00102899, false, false, 0, 0, nil, "CRC-21-CAN"],
|
91
|
-
[24, 0x005D6DCB, false, false, 0, 0, nil, "CRC-24"],
|
85
|
+
[16, 0x1021, true, true, 0xC6C6, 0, 0xBF05, "CRC-16-A", "CRC-A", "CRC-16-ISO/IEC FCD 14443-3"],
|
86
|
+
[16, 0x1021, true, true, 0, 0, 0x2189, "CRC-16-KERMIT", "KERMIT", "CRC-16-CCITT", "CRC-16-CCITT-TRUE", "CRC-CCITT"],
|
87
|
+
[16, 0x8005, true, true, ~0, 0, 0x4B37, "CRC-16-MODBUS", "MODBUS"],
|
88
|
+
[16, 0x1021, true, true, 0, ~0, 0x906E, "CRC-16-X-25", "X-25", "CRC-16-IBM-SDLC", "CRC-16-ISO-HDLC", "CRC-16-CRC-B", "CRC-B"],
|
89
|
+
[16, 0x1021, false, false, 0, 0, 0x31C3, "CRC-16-XMODEM", "XMODEM", "CRC-16-ZMODEM", "ZMODEM", "CRC-16-ACORN", "CRC-16-LTE"],
|
90
|
+
#[17, 0x0001685B, false, false, 0, 0, nil, "CRC-17-CAN"],
|
91
|
+
#[21, 0x00102899, false, false, 0, 0, nil, "CRC-21-CAN"],
|
92
|
+
#[24, 0x005D6DCB, false, false, 0, 0, nil, "CRC-24"],
|
92
93
|
[24, 0x00864CFB, false, false, 0, 0, 0x00CDE703, "CRC-24-Radix-64"],
|
93
94
|
[24, 0x00864CFB, false, false, 0x00B704CE, 0, 0x0021CF02, "CRC-24-OPENPGP"],
|
94
95
|
[24, 0x0000065B, true, true, 0x00555555, 0, 0x00C25A56, "CRC-24-BLE"],
|
@@ -97,25 +98,25 @@ module CRC
|
|
97
98
|
[24, 0x00328B63, false, false, 0, ~0, 0x00B4F3E6, "CRC-24-INTERLAKEN"],
|
98
99
|
[24, 0x00864CFB, false, false, 0, 0, 0x00CDE703, "CRC-24-LTE-A"],
|
99
100
|
[24, 0x00800063, false, false, 0, 0, 0x0023EF52, "CRC-24-LTE-B"],
|
100
|
-
[30, 0x2030B9C7, false, false, 0, 0, nil, "CRC-30"],
|
101
|
+
#[30, 0x2030B9C7, false, false, 0, 0, nil, "CRC-30"],
|
101
102
|
[30, 0x2030B9C7, false, false, 0, ~0, 0x04C34ABF, "CRC-30-CDMA"],
|
102
103
|
[31, 0x04C11DB7, false, false, 0, ~0, 0x0CE9E46C, "CRC-31-PHILIPS"],
|
103
|
-
[32, 0x04C11DB7, true, true, 0, ~0, 0xCBF43926, "CRC-32", "CRC-32-ADCCP", "PKZIP", "
|
104
|
+
[32, 0x04C11DB7, true, true, 0, ~0, 0xCBF43926, "CRC-32", "CRC-32-ADCCP", "CRC-32-PKZIP", "PKZIP"],
|
104
105
|
[32, 0x04C11DB7, false, false, 0, ~0, 0xFC891918, "CRC-32-BZIP2", "CRC-32-AAL5", "CRC-32-DECT-B", "B-CRC-32"],
|
105
106
|
[32, 0x1EDC6F41, true, true, 0, ~0, 0xE3069283, "CRC-32C", "CRC-32-ISCSI", "CRC-32-CASTAGNOLI", "CRC-32-INTERLAKEN"],
|
106
107
|
[32, 0xa833982b, true, true, 0, ~0, 0x87315576, "CRC-32D"],
|
107
108
|
[32, 0x04C11DB7, false, false, ~0, 0, 0x0376E6E7, "CRC-32-MPEG-2"],
|
108
109
|
[32, 0x04C11DB7, false, false, ~0, ~0, 0x765E7680, "CRC-32-POSIX", "CKSUM"],
|
109
|
-
[32, 0x741B8CD7, true, true, 0, ~0, nil, "CRC-32K"],
|
110
|
-
[32, 0x32583499, true, true, 0, ~0, nil, "CRC-32K2"],
|
110
|
+
#[32, 0x741B8CD7, true, true, 0, ~0, nil, "CRC-32K"],
|
111
|
+
#[32, 0x32583499, true, true, 0, ~0, nil, "CRC-32K2"],
|
111
112
|
[32, 0x814141AB, false, false, 0, 0, 0x3010BF7F, "CRC-32Q"],
|
112
|
-
[32, 0x04C11DB7, true, true, ~0, 0, 0x340BC6D9, "JAMCRC", "
|
113
|
-
[32, 0x000000AF, false, false, 0, 0, 0xBD0BE338, "XFER", "
|
113
|
+
[32, 0x04C11DB7, true, true, ~0, 0, 0x340BC6D9, "CRC-32-JAMCRC", "JAMCRC"],
|
114
|
+
[32, 0x000000AF, false, false, 0, 0, 0xBD0BE338, "CRC-32-XFER", "XFER"],
|
114
115
|
[40, 0x0004820009, false, false, ~0, ~0, 0xD4164FC646, "CRC-40-GSM"],
|
115
|
-
[64, 0x42F0E1EBA9EA3693, true, true, 0, ~0, 0x995DC9BBDF1939FA, "CRC-64", "CRC-64
|
116
|
+
[64, 0x42F0E1EBA9EA3693, true, true, 0, ~0, 0x995DC9BBDF1939FA, "CRC-64-XZ", "CRC-64"],
|
116
117
|
[64, 0x42F0E1EBA9EA3693, false, false, 0, 0, 0x6C40DF5F0B497347, "CRC-64-ECMA", "CRC-64-ECMA-182"],
|
117
118
|
[64, 0x42F0E1EBA9EA3693, false, false, 0, ~0, 0x62EC59E3F1A4F00A, "CRC-64-WE"],
|
118
|
-
[64, 0x000000000000001B,
|
119
|
+
[64, 0x000000000000001B, true, true, 0, 0, 0x46A5A9388A5BEFFE, "CRC-64-ISO", "CRC-64-ISO-3309"],
|
119
120
|
# [82, 0x308C0111011401440411, true, true, 0, 0, 0x9EA83F625023801FD612, "CRC-82/DARC"],
|
120
121
|
]
|
121
122
|
end
|
data/lib/crc/acrc.rb
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require_relative "../crc"
|
4
|
+
|
5
|
+
class CRC
|
6
|
+
module ModuleClass
|
7
|
+
#
|
8
|
+
# call-seq:
|
9
|
+
# acrc(crc, rest_seq = nil, target_crc = 0) -> byte string as arc-code
|
10
|
+
#
|
11
|
+
# 目的となる crc になるように、指定された crc に続くバイト列を逆算します。
|
12
|
+
#
|
13
|
+
# 出力されるバイト列は、crc のビット数を表現できるバイト数となります。
|
14
|
+
#
|
15
|
+
# 現在のところ、reflect-input/output 限定となっています。
|
16
|
+
#
|
17
|
+
# * crc32("123456789????") の結果が 0 となるような、???? の部分を逆算する
|
18
|
+
#
|
19
|
+
# seq = "123456789"
|
20
|
+
# seq << CRC::CRC32.acrc(seq)
|
21
|
+
# p CRC::CRC32[seq] # => #<CRC::CRC32:00000000>
|
22
|
+
#
|
23
|
+
# * crc32("123456789????ABCDEFG") の結果が 0 となるような、???? の部分を逆算する
|
24
|
+
#
|
25
|
+
# seq1 = "123456789"
|
26
|
+
# seq2 = "ABCDEFG"
|
27
|
+
# seq = seq1 + CRC::CRC32.acrc(seq1, seq2) + seq2
|
28
|
+
# p CRC::CRC32[seq] # => #<CRC::CRC32:00000000>
|
29
|
+
#
|
30
|
+
# * crc32("123456789????ABCDEFG") の結果が 0x12345678 となるような、???? の部分を逆算する
|
31
|
+
#
|
32
|
+
# seq1 = "123456789"
|
33
|
+
# seq2 = "ABCDEFG"
|
34
|
+
# target_crc = 0x12345678
|
35
|
+
# seq = seq1 + CRC::CRC32.acrc(seq1, seq2, target_crc) + seq2
|
36
|
+
# p CRC::CRC32[seq] # => #<CRC::CRC32:12345678>
|
37
|
+
#
|
38
|
+
def acrc(crc, rest_seq = nil, target_crc = 0)
|
39
|
+
raise NotImplementedError, "crc polynomial is not odd" unless polynomial.odd?
|
40
|
+
raise NotImplementedError, "crc module is not reflect input and output" unless reflect_input? && reflect_output?
|
41
|
+
|
42
|
+
bitsize = self.bitsize
|
43
|
+
poly = CRC.bitreflect(polynomial, bitsize)
|
44
|
+
target_crc = target_crc.to_i
|
45
|
+
target_crc ^= xor_output
|
46
|
+
|
47
|
+
if rest_seq
|
48
|
+
rest_seq.bytesize.downto(1) do |i|
|
49
|
+
target_crc = Aux.acrc_loop_reflect(target_crc, rest_seq.getbyte(i - 1), poly, bitsize, 0xff, 8)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
bytes = (bitsize + 7) / 8
|
54
|
+
bits = bytes * 8
|
55
|
+
|
56
|
+
case crc
|
57
|
+
when Numeric
|
58
|
+
state = bitmask & crc ^ xor_output
|
59
|
+
when CRC
|
60
|
+
raise "different crc module (given %p(%p), expect %p)" % [crc, crc.class, self] unless variant?(crc)
|
61
|
+
state = crc.state
|
62
|
+
else
|
63
|
+
state = new(crc).state
|
64
|
+
end
|
65
|
+
|
66
|
+
if bits > bitsize
|
67
|
+
# ビット数が 8 の境界にない場合、その隙間分を埋める。
|
68
|
+
# 現在の実装では、最終結果のバイト列における最終バイト値の
|
69
|
+
# 上位ビットが 0 であるようにしている。
|
70
|
+
pad = bits - bitsize
|
71
|
+
target_crc = Aux.acrc_loop_reflect(target_crc, 0, poly, bitsize, 0xff, pad)
|
72
|
+
end
|
73
|
+
|
74
|
+
target_crc = Aux.acrc_loop_reflect(target_crc, state, poly, bitsize, bitmask, bitsize)
|
75
|
+
|
76
|
+
bytes.times.reduce("") { |a, *| a << (target_crc & 0xff).chr(Encoding::BINARY); target_crc >>= 8; a }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module Aux
|
81
|
+
def self.acrc_loop_reflect(target_crc, state, poly, crcbits, bitmask, bits)
|
82
|
+
head = bits - 1
|
83
|
+
bitmask1 = bitmask >> 1
|
84
|
+
crchead = crcbits - 1
|
85
|
+
|
86
|
+
#puts "target_crc=0b%016b, state=0b%016b, reversed-polynomial=0b%016b" % [target_crc, state, poly]
|
87
|
+
bits.times do |i|
|
88
|
+
if target_crc[crchead] == 0
|
89
|
+
target_crc <<= 1
|
90
|
+
else
|
91
|
+
target_crc ^= poly
|
92
|
+
target_crc <<= 1
|
93
|
+
target_crc |= 0x01
|
94
|
+
end
|
95
|
+
|
96
|
+
target_crc ^= state[head]
|
97
|
+
#puts " 0_%016b ^ %d" % [target_crc, state[head]]
|
98
|
+
state = (state & bitmask1) << 1
|
99
|
+
end
|
100
|
+
#puts "target_crc=0b%016b" % target_crc
|
101
|
+
|
102
|
+
target_crc
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
if $0 == __FILE__
|
108
|
+
seq = "abcdefghijklmnopqrstuvwxyz"
|
109
|
+
seq2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
110
|
+
code = CRC::X_25.acrc(seq, seq2)
|
111
|
+
puts "base-crc=[%p, %p], arc'd-crc=%p, arc-code=%s" % [CRC::X_25[seq], CRC::X_25[seq2], CRC::X_25[seq + code + seq2], code.unpack("H*")[0]]
|
112
|
+
code = CRC::CRC32.acrc(seq, seq2)
|
113
|
+
puts "base-crc=[%p, %p], arc'd-crc=%p, arc-code=%s" % [CRC::CRC32[seq], CRC::CRC32[seq2], CRC::CRC32[seq + code + seq2], code.unpack("H*")[0]]
|
114
|
+
code = CRC::CRC32C.acrc(seq, seq2)
|
115
|
+
puts "base-crc=[%p, %p], arc'd-crc=%p, arc-code=%s" % [CRC::CRC32C[seq], CRC::CRC32C[seq2], CRC::CRC32C[seq + code + seq2], code.unpack("H*")[0]]
|
116
|
+
|
117
|
+
MyCRC = crcmod = CRC.new(32, rand(1<<32) | 1, rand(1<<32) | 1, true, true, rand(1<<32) | 1)
|
118
|
+
20.times do |i|
|
119
|
+
s = (10+rand(20)).times.reduce("") { |a, *| a << rand(256).chr(Encoding::BINARY) }
|
120
|
+
t = (10+rand(20)).times.reduce("") { |a, *| a << rand(256).chr(Encoding::BINARY) }
|
121
|
+
crc = crcmod.new(s)
|
122
|
+
puts "crc=[%p, %p], arc'd-crc=%p, target=%08X, seq=%s" %
|
123
|
+
[crc, crcmod[t], crcmod.new(s + crcmod.acrc(crc.crc, t, i * 9929) + t), i * 9929, s.unpack("H*")[0]]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
__END__
|
128
|
+
|
129
|
+
目的となる CRC 値を逆算して、特定のバイト列を得る機能です。
|
130
|
+
|
131
|
+
ただの思いつきで、crc すると結果が 0 になるバイト列を計算できないかなと遊んでみた結果、
|
132
|
+
それなりの形となってしまいました。
|
133
|
+
|
134
|
+
以下は acrc メソッドとして実装した、その仕組みとなります。
|
135
|
+
|
136
|
+
|
137
|
+
X-25{CRC-16-0x1021 ref-in/out xor=0xffff} を用いた場合
|
138
|
+
|
139
|
+
("abcdefghijklmnopqrstuvwxyz" + ??) を CRC して結果を 0 にしたい (?? は2バイト)。
|
140
|
+
|
141
|
+
この時の ?? を求める。
|
142
|
+
|
143
|
+
先に "abcdefghijklmnopqrstuvwxyz" までの CRC を求めておく => 0x0d43
|
144
|
+
|
145
|
+
(ここまでの内部状態は 0xf2bc) ?? <STOP> (この段階で内部状態が 0xffff であること)
|
146
|
+
|
147
|
+
内部状態の最上位ビットから順に送って、目的となる内部状態が 0xffff から 0xf2bc になるような値を逆算する
|
148
|
+
|
149
|
+
|
150
|
+
code = 0 # 最終的に求めたい CRC
|
151
|
+
state = 0b1111001010111100 # 現在の CRC 生成器の内部状態
|
152
|
+
reversed_polynomial = 0b1000010000001000
|
153
|
+
|
154
|
+
1. 最終的に求めたい CRC と xor_output する
|
155
|
+
1111111111111111
|
156
|
+
|
157
|
+
2. この時、code の最上位ビットが1なので、poly (reversed) で xor する
|
158
|
+
最上位ビットが0ならば何もしない
|
159
|
+
0111101111110111
|
160
|
+
|
161
|
+
3. 左にずらす
|
162
|
+
1111011111101110
|
163
|
+
|
164
|
+
4. (2) において poly-reversed で xor したため、最下位ビットを1にする
|
165
|
+
(2) を行わなかった場合は何もしない
|
166
|
+
1111011111101111
|
167
|
+
|
168
|
+
5. 目的となる内部状態の最上位ビットと作業内部状態の最下位ビットを xor した時に 1 となるように調整する
|
169
|
+
(2) を行わなかった場合は 0 を維持するように処置する
|
170
|
+
1111011111101110
|
171
|
+
|
172
|
+
6. 1 ビット目の処理が完了。(2) に戻って必要なだけ繰り返す
|
173
|
+
|
174
|
+
1111011111101110 <= 1 ## 最上位から2ビット目を入力
|
175
|
+
1110011111001100 <= 1 ## 最上位から3ビット目を入力
|
176
|
+
1100011110001000 <= 1 ## 以下同様に……
|
177
|
+
1000011100000000 <= 0
|
178
|
+
0000011000010001 <= 0
|
179
|
+
0000110000100010 <= 1
|
180
|
+
0001100001000101 <= 0
|
181
|
+
0011000010001010 <= 1
|
182
|
+
0110000100010101 <= 0
|
183
|
+
1100001000101010 <= 1
|
184
|
+
1000110001000100 <= 1
|
185
|
+
0001000010011000 <= 1
|
186
|
+
0010000100110001 <= 1
|
187
|
+
0100001001100011 <= 0
|
188
|
+
1000010011000110 <= 0
|
189
|
+
0000000110011101 ## 繰り返して得られた結果
|
190
|
+
この結果を元にして、バイト順を入れ替える
|
191
|
+
(CRC として求める場合に、下位から入力されるため)
|
192
|
+
|
193
|
+
10011101:00000001 >>>> [0x9d, 0x01] が返る
|
194
|
+
|
195
|
+
[EOF]
|