@@ -17,6 +17,9 @@ class CRC < Digest::Class
17
17
# The bit width of the CRC checksum
18
18
WIDTH = 0
19
19
20
+ # Define true or false whether the input direction is bit reversed or not of the CRC checksum
21
+ REFLECT_INPUT = nil
22
+
20
23
# Default place holder CRC table
21
24
TABLE = [ ] . freeze
22
25
@@ -64,10 +67,11 @@ def self.pack(crc)
64
67
# Initializes the CRC checksum.
65
68
#
66
69
def initialize
67
- @init_crc = self . class . const_get ( :INIT_CRC )
68
- @xor_mask = self . class . const_get ( :XOR_MASK )
69
- @width = self . class . const_get ( :WIDTH )
70
- @table = self . class . const_get ( :TABLE )
70
+ @init_crc = self . class . const_get ( :INIT_CRC )
71
+ @xor_mask = self . class . const_get ( :XOR_MASK )
72
+ @width = self . class . const_get ( :WIDTH )
73
+ @reflect_input = self . class . const_get ( :REFLECT_INPUT )
74
+ @table = self . class . const_get ( :TABLE )
71
75
72
76
reset
73
77
end
@@ -97,10 +101,57 @@ def digest_length
97
101
# @param [String] data
98
102
# The data to update the CRC checksum with.
99
103
#
100
- # @abstract
104
+ # @raise [NotImplementedError]
105
+ # If WIDTH, TABLE, or REFLECT_INPUT constants are not set properly.
101
106
#
102
107
def update ( data )
103
- raise ( NotImplementedError , "#{ self . class } ##{ __method__ } not implemented" )
108
+ unless @width >= 1
109
+ raise ( NotImplementedError , "incompleted #{ self . class } as CRC (expected WIDTH to be 1 or more)" )
110
+ end
111
+
112
+ if @table . empty?
113
+ raise ( NotImplementedError , "incompleted #{ self . class } as CRC (expected TABLE to be not empty)" )
114
+ end
115
+
116
+ if @reflect_input . nil?
117
+ raise ( NotImplementedError , "incompleted #{ self . class } as CRC (expected REFLECT_INPUT to be not nil)" )
118
+ end
119
+
120
+ table = @table
121
+ crc = @crc
122
+
123
+ if @reflect_input
124
+ if @width > 8
125
+ data . each_byte do |b |
126
+ crc = table [ b ^ ( 0xff & crc ) ] ^ ( crc >> 8 )
127
+ end
128
+ else
129
+ data . each_byte do |b |
130
+ # Omit (crc >> 8) since bits upper than the lower 8 bits are always 0
131
+ crc = table [ b ^ ( 0xff & crc ) ]
132
+ end
133
+ end
134
+ else
135
+ if @width > 8
136
+ higher_bit_off = @width - 8
137
+ remain_mask = ~( -1 << higher_bit_off )
138
+
139
+ data . each_byte do |b |
140
+ crc = table [ b ^ ( 0xff & ( crc >> higher_bit_off ) ) ] ^ ( ( remain_mask & crc ) << 8 )
141
+ end
142
+ else
143
+ padding = 8 - @width
144
+
145
+ data . each_byte do |b |
146
+ # Omit (crc << 8) since bits lower than the upper 8 bits are always 0
147
+ crc = table [ b ^ ( 0xff & ( crc << padding ) ) ]
148
+ end
149
+ end
150
+ end
151
+
152
+ @crc = crc
153
+
154
+ self
104
155
end
105
156
106
157
#
0 commit comments