crc 0.3.1.1 → 0.4
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.
- 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
|