crc 0.3.1.1 → 0.4
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 +48 -0
- data/README.md +105 -80
- data/bin/rbcrc +10 -7
- data/gemstub.rb +6 -6
- data/lib/crc.rb +39 -261
- data/lib/crc/_aux.rb +37 -0
- data/lib/crc/_byruby.rb +5 -10
- data/lib/crc/_combine.rb +1 -1
- data/lib/crc/_extensions.rb +201 -0
- data/lib/crc/_file.rb +15 -0
- data/lib/crc/_magic.rb +93 -0
- data/lib/crc/_modules.rb +1 -1
- data/lib/crc/_shift.rb +194 -0
- data/lib/crc/_utils.rb +114 -0
- data/lib/crc/acrc.rb +16 -71
- data/lib/crc/codegen.rb +1 -1
- data/lib/crc/version.rb +1 -1
- data/test/common.rb +23 -0
- data/test/self_check.rb +31 -0
- data/test/test_block.rb +28 -0
- data/test/test_magic.rb +25 -0
- metadata +28 -12
data/lib/crc/_aux.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class CRC
|
2
|
+
#
|
3
|
+
# Internal using module.
|
4
|
+
#
|
5
|
+
module Aux
|
6
|
+
def self.DIGEST(num, bitsize)
|
7
|
+
bits = (bitsize + 7) / 8 * 8
|
8
|
+
seq = ""
|
9
|
+
(bits - 8).step(0, -8) { |i| seq << yield((num >> i) & 0xff) }
|
10
|
+
seq
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.digest(num, bitsize)
|
14
|
+
DIGEST(num, bitsize) { |n| n.chr(Encoding::BINARY) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.hexdigest(num, bitsize)
|
18
|
+
DIGEST(num, bitsize) { |n| "%02X" % n }
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# call-seq:
|
23
|
+
# slide_to_head(bitsize, state, polynomial, bitmask) { |padded_state, padded_polynomial, shift_input, off_msb, carries_mask, padding_size| padded_new_state } -> new_state
|
24
|
+
#
|
25
|
+
# YIELD(padded_state, padded_polynomial, shift_input, off_msb, carries_mask, padding_size) -> padded_new_state
|
26
|
+
#
|
27
|
+
def self.slide_to_head(bitsize, state, polynomial, bitmask)
|
28
|
+
pad = bitsize & 0x07
|
29
|
+
if pad == 0
|
30
|
+
yield(state, polynomial, bitsize - 8, bitsize - 1, bitmask >> 1, 0)
|
31
|
+
else
|
32
|
+
pad = 8 - pad
|
33
|
+
yield(state << pad, polynomial << pad, bitsize - 8 + pad, bitsize - 1 + pad, (bitmask << pad >> 1) | 0x7f, pad) >> pad
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/crc/_byruby.rb
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
#--
|
4
4
|
# File:: _byruby.rb
|
5
|
-
# Author:: dearblue <dearblue@users.
|
5
|
+
# Author:: dearblue <dearblue@users.noreply.github.com>
|
6
6
|
# License:: Creative Commons License Zero (CC0 / Public Domain)
|
7
7
|
#++
|
8
8
|
|
9
9
|
#
|
10
10
|
# \* \* \* \* \* \* \* \*
|
11
11
|
#
|
12
|
-
# Pure ruby implemented general CRC
|
12
|
+
# Pure ruby implemented general CRC calcurator.
|
13
13
|
# It's used slice-by-16 algorithm with byte-order free.
|
14
14
|
# This is based on the Intel's slice-by-eight algorithm.
|
15
15
|
#
|
@@ -28,8 +28,7 @@ class CRC
|
|
28
28
|
#
|
29
29
|
# call-seq:
|
30
30
|
# new(bitsize, polynomial, initial_crc = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil) -> new crc module class (CRC based class)
|
31
|
-
# new(initial_crc = nil, size = 0) -> new crc
|
32
|
-
# new(seq, initial_crc = nil, size = 0) -> new crc generator (CRC instance)
|
31
|
+
# new(initial_crc = nil, size = 0) -> new crc calcurator (CRC instance)
|
33
32
|
#
|
34
33
|
def new(bitsize, polynomial, initial_crc = 0, reflect_input = true, reflect_output = true, xor_output = ~0, name = nil)
|
35
34
|
bitsize = bitsize.to_i
|
@@ -57,11 +56,7 @@ class CRC
|
|
57
56
|
# CRC クラスを普通に派生させた場合でも、CRC.new の基底メソッドが呼ばれるための細工
|
58
57
|
define_singleton_method(:new, &Class.instance_method(:new).bind(self))
|
59
58
|
|
60
|
-
|
61
|
-
alias_method :[], :new
|
62
|
-
end
|
63
|
-
|
64
|
-
extend CRC::ModuleClass
|
59
|
+
extend CRC::Calcurator
|
65
60
|
end
|
66
61
|
end
|
67
62
|
|
@@ -259,7 +254,7 @@ class CRC
|
|
259
254
|
end
|
260
255
|
end
|
261
256
|
|
262
|
-
module
|
257
|
+
module Calcurator
|
263
258
|
attr_reader :bitsize, :bitmask, :polynomial, :initial_crc,
|
264
259
|
:reflect_input, :reflect_output, :xor_output, :name
|
265
260
|
|
data/lib/crc/_combine.rb
CHANGED
@@ -0,0 +1,201 @@
|
|
1
|
+
class CRC
|
2
|
+
module Extensions
|
3
|
+
# refinements
|
4
|
+
# * each_byte
|
5
|
+
# * reverse_each_byte
|
6
|
+
;
|
7
|
+
|
8
|
+
refine Array do
|
9
|
+
def each_byte
|
10
|
+
return to_enum(:each_byte) unless block_given?
|
11
|
+
each { |ch| yield 0xff & ch }
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def reverse_each_byte
|
16
|
+
return to_enum(:reverse_each_byte) unless block_given?
|
17
|
+
reverse_each { |ch| yield 0xff & ch }
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
refine BasicObject do
|
23
|
+
def each_byte(&block)
|
24
|
+
Array(self).each_byte(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def reverse_each_byte(&block)
|
28
|
+
Array(self).reverse_each_byte(&block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
refine String do
|
33
|
+
def reverse_each_byte
|
34
|
+
return to_enum(:reverse_each_byte) unless block_given?
|
35
|
+
(bytesize - 1).downto(0) { |i| yield getbyte(i) }
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# refinements:
|
41
|
+
# * convert_internal_state_for
|
42
|
+
# * convert_target_state_for
|
43
|
+
;
|
44
|
+
|
45
|
+
refine BasicObject do
|
46
|
+
def convert_internal_state_for(crc)
|
47
|
+
raise TypeError, "cant convertion to #{crc.to_s} (for #{inspect})"
|
48
|
+
end
|
49
|
+
|
50
|
+
def convert_target_state_for(crc)
|
51
|
+
raise TypeError, "cant convertion to #{crc.to_s} (for #{inspect})"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
refine NilClass do
|
56
|
+
def convert_internal_state_for(crc)
|
57
|
+
crc.setup(crc.initial_crc)
|
58
|
+
end
|
59
|
+
|
60
|
+
def convert_target_state_for(crc)
|
61
|
+
crc.setup(0)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
refine String do
|
66
|
+
def convert_internal_state_for(crc)
|
67
|
+
crc.update(self, crc.setup(crc.initial_crc))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
refine Integer do
|
72
|
+
def convert_internal_state_for(crc)
|
73
|
+
crc.setup(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
def convert_target_state_for(crc)
|
77
|
+
crc.setup(self)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
refine CRC do
|
82
|
+
def convert_internal_state_for(crc)
|
83
|
+
unless crc.variant?(self)
|
84
|
+
raise "not variant crc module (expect #{crc.to_s}, but self is #{inspect})"
|
85
|
+
end
|
86
|
+
|
87
|
+
state
|
88
|
+
end
|
89
|
+
|
90
|
+
def convert_target_state_for(crc)
|
91
|
+
unless crc.variant?(self)
|
92
|
+
raise "not variant crc module (expect #{crc.to_s}, but self is #{inspect})"
|
93
|
+
end
|
94
|
+
|
95
|
+
state
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# refinements:
|
100
|
+
# * splitbytes
|
101
|
+
;
|
102
|
+
|
103
|
+
refine Integer do
|
104
|
+
def splitbytes(bucket, bytes, is_little_endian)
|
105
|
+
if is_little_endian
|
106
|
+
bytes.times { |i| bucket.pushbyte self >> (i * 8) }
|
107
|
+
else
|
108
|
+
(bytes - 1).downto(0) { |i| bucket.pushbyte self >> (i * 8) }
|
109
|
+
end
|
110
|
+
|
111
|
+
bucket
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
refine String do
|
116
|
+
def pushbyte(ch)
|
117
|
+
self << (0xff & ch).chr(Encoding::BINARY)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
refine Array do
|
122
|
+
def pushbyte(ch)
|
123
|
+
self << (0xff & ch)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# refinements:
|
128
|
+
# * bitsize_to_bytesize
|
129
|
+
# * bitsize_to_intsize
|
130
|
+
# * byte_paddingsize
|
131
|
+
# * int_paddingsize
|
132
|
+
;
|
133
|
+
|
134
|
+
refine Integer do
|
135
|
+
def bitsize_to_bytesize
|
136
|
+
(self + 7) / 8
|
137
|
+
end
|
138
|
+
|
139
|
+
def bitsize_to_intsize
|
140
|
+
bitsize = 8
|
141
|
+
intsize = 1
|
142
|
+
10.times do
|
143
|
+
return intsize if self <= bitsize
|
144
|
+
bitsize <<= 1
|
145
|
+
intsize <<= 1
|
146
|
+
end
|
147
|
+
|
148
|
+
raise "数値が巨大すぎるため、intsize が決定できません - #{inspect}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def byte_paddingsize
|
152
|
+
(bitsize_to_bytesize * 8) - bitsize
|
153
|
+
end
|
154
|
+
|
155
|
+
def int_paddingsize
|
156
|
+
(bitsize_to_intsize * 8) - bitsize
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# refinements:
|
161
|
+
# * get_crc_module
|
162
|
+
# * variant_for?
|
163
|
+
;
|
164
|
+
|
165
|
+
refine BasicObject do
|
166
|
+
def get_crc_module
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
170
|
+
def variant_for?(m)
|
171
|
+
false
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
refine CRC do
|
176
|
+
alias get_crc_module class
|
177
|
+
|
178
|
+
def variant_for?(m)
|
179
|
+
get_crc_module.variant_for?(m)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
refine CRC.singleton_class do
|
184
|
+
alias get_crc_module itself
|
185
|
+
|
186
|
+
def variant_for?(m)
|
187
|
+
return false unless m = m.get_crc_module
|
188
|
+
|
189
|
+
if bitsize == m.bitsize &&
|
190
|
+
polynomial == m.polynomial &&
|
191
|
+
reflect_input? == m.reflect_input? &&
|
192
|
+
reflect_output? == m.reflect_output? &&
|
193
|
+
xor_output == m.xor_output
|
194
|
+
true
|
195
|
+
else
|
196
|
+
false
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
data/lib/crc/_file.rb
ADDED
data/lib/crc/_magic.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
class CRC
|
2
|
+
module Extensions
|
3
|
+
refine Integer do
|
4
|
+
def to_magicdigest_for(m, bytesize = m.bitsize.bitsize_to_bytesize)
|
5
|
+
if m.reflect_input? ^ m.reflect_output?
|
6
|
+
tmp = CRC.bitreflect(self, m.bitsize)
|
7
|
+
else
|
8
|
+
tmp = self
|
9
|
+
end
|
10
|
+
|
11
|
+
if m.reflect_input?
|
12
|
+
magic = tmp.splitbytes("".b, bytesize, true)
|
13
|
+
else
|
14
|
+
tmp <<= ((bytesize * 8) - m.bitsize)
|
15
|
+
magic = tmp.splitbytes("".b, bytesize, false)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
refine String do
|
21
|
+
def to_magicdigest_for(m)
|
22
|
+
bytes = m.bitsize.bitsize_to_bytesize
|
23
|
+
case bytesize
|
24
|
+
when bytes
|
25
|
+
crc = unpack("C*").reduce { |a, ch| (a << 8) | ch }
|
26
|
+
when bytes * 2
|
27
|
+
crc = hex
|
28
|
+
else
|
29
|
+
raise TypeError, "wrong byte size (expect #{bytes} or #{bytes * 2} bytes, but given #{inspect})", caller
|
30
|
+
end
|
31
|
+
|
32
|
+
crc.to_magicdigest_for(m, bytes)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
refine CRC do
|
37
|
+
def to_magicdigest_for(m)
|
38
|
+
unless m.variant?(get_crc_module)
|
39
|
+
raise TypeError, "different crc type - #{get_crc_module.inspect} (expect #{m.inspect})", caller
|
40
|
+
end
|
41
|
+
|
42
|
+
magicdigest
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
refine BasicObject do
|
47
|
+
def to_magicdigest_for(m)
|
48
|
+
raise TypeError, "cant convert type - #{get_crc_module}", caller
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
refine CRC.singleton_class do
|
53
|
+
def __cached_magic_code__
|
54
|
+
@__cached_magic_code__ = initial_crc.to_magicdigest_for(self).freeze
|
55
|
+
singleton_class.class_eval { attr_reader :__cached_magic_code__ }
|
56
|
+
@__cached_magic_code__
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
using CRC::Extensions
|
62
|
+
|
63
|
+
module Calcurator
|
64
|
+
def magicnumber
|
65
|
+
@magicnumber = crc(__cached_magic_code__)
|
66
|
+
singleton_class.class_eval { attr_reader :magicnumber }
|
67
|
+
@magicnumber
|
68
|
+
end
|
69
|
+
|
70
|
+
def magic
|
71
|
+
@magic = hexdigest(__cached_magic_code__).freeze
|
72
|
+
singleton_class.class_eval { attr_reader :magic }
|
73
|
+
@magic
|
74
|
+
end
|
75
|
+
|
76
|
+
def magicdigest(seq, crc = nil)
|
77
|
+
crc(seq, crc).to_magicdigest_for(self)
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# crc 値を与えると magicdigest へと変換したバイナリデータを返します。
|
82
|
+
#
|
83
|
+
# crc には整数値、digest/hexdigest データ、変種を含む CRC インスタンスを渡すことが出来ます。
|
84
|
+
#
|
85
|
+
def to_magicdigest(crc)
|
86
|
+
crc.to_magicdigest_for(self)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def magicdigest
|
91
|
+
crc.to_magicdigest_for(get_crc_module)
|
92
|
+
end
|
93
|
+
end
|
data/lib/crc/_modules.rb
CHANGED
data/lib/crc/_shift.rb
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
class CRC
|
2
|
+
module Calcurator
|
3
|
+
#
|
4
|
+
# call-seq:
|
5
|
+
# shiftbits_by_bitbybit(bitset, state) -> state
|
6
|
+
#
|
7
|
+
def shiftbits_by_bitbybit(bitset, state)
|
8
|
+
bitset = Array(bitset)
|
9
|
+
|
10
|
+
if reflect_input?
|
11
|
+
poly = CRC.bitreflect(polynomial, bitsize)
|
12
|
+
bitset.each do |b|
|
13
|
+
state ^= (1 & b)
|
14
|
+
state = (state[0] == 0) ? (state >> 1) : ((state >> 1) ^ poly)
|
15
|
+
end
|
16
|
+
|
17
|
+
state
|
18
|
+
else
|
19
|
+
Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries|
|
20
|
+
bitset.each do |b|
|
21
|
+
s ^= (1 & b) << head
|
22
|
+
s = (s[head] == 0) ? (s << 1) : (((carries & s) << 1) ^ poly)
|
23
|
+
end
|
24
|
+
|
25
|
+
s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# call-seq:
|
32
|
+
# shiftbytes_by_bitbybit(byteset, state)
|
33
|
+
#
|
34
|
+
# standard input の場合は byte は上位ビットから、reflect input の場合は byte は下位ビットから計算されます。
|
35
|
+
#
|
36
|
+
def shiftbytes_by_bitbybit(byteset, state)
|
37
|
+
if reflect_input?
|
38
|
+
poly = CRC.bitreflect(polynomial, bitsize)
|
39
|
+
byteset.each_byte do |b|
|
40
|
+
state ^= 0xff & b
|
41
|
+
8.times do
|
42
|
+
state = (state[0] == 0) ? (state >> 1) : ((state >> 1) ^ poly)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
state
|
47
|
+
else
|
48
|
+
Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries|
|
49
|
+
byteset.each_byte do |b|
|
50
|
+
s ^= (0xff & b) << csh
|
51
|
+
8.times do
|
52
|
+
s = (s[head] == 0) ? (s << 1) : (((carries & s) << 1) ^ poly)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# call-seq:
|
63
|
+
# unshiftbits_by_bitbybit(bitset, state)
|
64
|
+
#
|
65
|
+
# bitset を与えることで state となるような内部状態を逆算します。
|
66
|
+
#
|
67
|
+
def unshiftbits_by_bitbybit(bitset, state)
|
68
|
+
bitset = Array(bitset)
|
69
|
+
|
70
|
+
if reflect_input?
|
71
|
+
poly = (CRC.bitreflect(polynomial, bitsize) << 1) | 1
|
72
|
+
head = bitsize
|
73
|
+
bitset.reverse_each do |b|
|
74
|
+
state <<= 1
|
75
|
+
state ^= poly unless state[head] == 0
|
76
|
+
state ^= 1 & b
|
77
|
+
end
|
78
|
+
|
79
|
+
state
|
80
|
+
else
|
81
|
+
Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries|
|
82
|
+
headbit = 1 << head
|
83
|
+
lowoff = (head + 1) - bitsize
|
84
|
+
poly = (poly >> 1) | headbit
|
85
|
+
bitset.reverse_each do |b|
|
86
|
+
tmp = s[lowoff]
|
87
|
+
s >>= 1
|
88
|
+
s ^= poly unless tmp == 0
|
89
|
+
s ^= (1 & b) << head
|
90
|
+
end
|
91
|
+
|
92
|
+
s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# call-seq:
|
99
|
+
# unshiftbytes_by_bitbybit(byteset, state)
|
100
|
+
#
|
101
|
+
# byteset を与えることで state となるような内部状態を逆算します。
|
102
|
+
#
|
103
|
+
def unshiftbytes_by_bitbybit(byteset, state)
|
104
|
+
if reflect_input?
|
105
|
+
poly = (CRC.bitreflect(polynomial, bitsize) << 1) | 1
|
106
|
+
head = bitsize
|
107
|
+
byteset.reverse_each_byte do |b|
|
108
|
+
7.downto(0) do |i|
|
109
|
+
state <<= 1
|
110
|
+
state ^= poly unless state[head] == 0
|
111
|
+
state ^= b[i]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
state
|
116
|
+
else
|
117
|
+
Aux.slide_to_head(bitsize, state, polynomial, bitmask) do |s, poly, csh, head, carries|
|
118
|
+
headbit = 1 << head
|
119
|
+
lowoff = (head + 1) - bitsize
|
120
|
+
poly = (poly >> 1) | headbit
|
121
|
+
byteset.reverse_each_byte do |b|
|
122
|
+
8.times do |i|
|
123
|
+
tmp = s[lowoff]
|
124
|
+
s >>= 1
|
125
|
+
s ^= poly unless tmp == 0
|
126
|
+
s ^= b[i] << head
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
s
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def unshift_table
|
136
|
+
if reflect_input?
|
137
|
+
if bitsize < 8
|
138
|
+
pad = 8 - bitsize
|
139
|
+
shift = 0
|
140
|
+
else
|
141
|
+
pad = 0
|
142
|
+
shift = bitsize - 8
|
143
|
+
end
|
144
|
+
poly = ((CRC.bitreflect(polynomial, bitsize) << 1) | 1) << pad
|
145
|
+
head = bitsize + pad
|
146
|
+
@unshift_table = 256.times.map do |ch|
|
147
|
+
state = ch << shift
|
148
|
+
8.times do |i|
|
149
|
+
state <<= 1
|
150
|
+
state ^= poly unless state[head] == 0
|
151
|
+
end
|
152
|
+
state >> pad
|
153
|
+
end
|
154
|
+
else
|
155
|
+
raise NotImplementedError
|
156
|
+
end
|
157
|
+
|
158
|
+
singleton_class.module_eval { attr_reader :unshift_table }
|
159
|
+
|
160
|
+
@unshift_table
|
161
|
+
end
|
162
|
+
|
163
|
+
def unshiftbytes_by_table(byteset, state)
|
164
|
+
if reflect_input?
|
165
|
+
table = unshift_table
|
166
|
+
if bitsize < 8
|
167
|
+
pad = 8 - bitsize
|
168
|
+
shift = 0
|
169
|
+
mask = bitmask
|
170
|
+
byteset.reverse_each_byte do |ch|
|
171
|
+
state = (state << 8) ^ ch
|
172
|
+
state = table[state >> bitsize] ^ (ch & mask)
|
173
|
+
end
|
174
|
+
else
|
175
|
+
shift = bitsize - 8
|
176
|
+
mask = ~(~0 << shift)
|
177
|
+
byteset.reverse_each_byte do |ch|
|
178
|
+
state = table[state >> shift] ^ ((state & mask) << 8)
|
179
|
+
state ^= ch
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
state
|
184
|
+
else
|
185
|
+
unshiftbytes_by_bitbybit(byteset, state)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
alias shiftbits shiftbits_by_bitbybit
|
190
|
+
alias shiftbytes shiftbytes_by_bitbybit
|
191
|
+
alias unshiftbits unshiftbits_by_bitbybit
|
192
|
+
alias unshiftbytes unshiftbytes_by_table
|
193
|
+
end
|
194
|
+
end
|