Class: Digest::CRC
Overview
Base class for all CRC algorithms.
Constant Summary collapse
- INIT_CRC =
The initial value of the CRC checksum
0x00
- XOR_MASK =
The XOR mask to apply to the resulting CRC checksum
0x00
- WIDTH =
The bit width of the CRC checksum
0
- REFLECT_INPUT =
Define true or false whether the input direction is bit reversed or not of the CRC checksum
nil
- TABLE =
Default place holder CRC table
[].freeze
Class Method Summary collapse
-
.checksum(data) ⇒ Integer
Calculates the CRC checksum.
-
.implementation ⇒ :c_ext, :pure
Determines whether the library is using the optimized C extensions implementation, or the pure-Ruby implementation.
-
.pack(crc) ⇒ String
Packs the given CRC checksum.
Instance Method Summary collapse
- #<<(data) ⇒ Object
-
#block_length ⇒ 1
The input block length.
-
#checksum ⇒ Integer
The resulting CRC checksum.
-
#digest_length ⇒ Integer
The length of the digest.
-
#finish ⇒ Object
Finishes the CRC checksum calculation.
-
#initialize ⇒ CRC
constructor
Initializes the CRC checksum.
-
#reset ⇒ Integer
Resets the CRC checksum.
-
#update(data) ⇒ Object
Updates the CRC checksum with the given data.
Constructor Details
#initialize ⇒ CRC
Initializes the CRC checksum.
85 86 87 88 89 90 91 92 93 |
# File 'lib/digest/crc.rb', line 85 def initialize @init_crc = self.class.const_get(:INIT_CRC) @xor_mask = self.class.const_get(:XOR_MASK) @width = self.class.const_get(:WIDTH) @reflect_input = self.class.const_get(:REFLECT_INPUT) @table = self.class.const_get(:TABLE) reset end |
Class Method Details
.checksum(data) ⇒ Integer
Calculates the CRC checksum.
35 36 37 38 39 40 |
# File 'lib/digest/crc.rb', line 35 def self.checksum(data) crc = self.new crc << data return crc.checksum end |
.implementation ⇒ :c_ext, :pure
Determines whether the library is using the optimized C extensions implementation, or the pure-Ruby implementation.
74 75 76 77 78 79 80 |
# File 'lib/digest/crc.rb', line 74 def self.implementation if instance_method(:update).source_location.nil? :c_ext else :pure end end |
.pack(crc) ⇒ String
Packs the given CRC checksum.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/digest/crc.rb', line 51 def self.pack(crc) unless (width = self::WIDTH) > 0 raise(NotImplementedError, "#{self} is incompleted as CRC") end bitclass = width + (-width & 0x07) byte_count = bitclass / 8 crc &= ~(-1 << width) result = [crc].pack("Q>") result[0, result.bytesize - byte_count] = "" result end |
Instance Method Details
#<<(data) ⇒ Object
176 177 178 179 |
# File 'lib/digest/crc.rb', line 176 def <<(data) update(data) return self end |
#block_length ⇒ 1
The input block length.
100 101 102 |
# File 'lib/digest/crc.rb', line 100 def block_length 1 end |
#checksum ⇒ Integer
The resulting CRC checksum.
197 198 199 |
# File 'lib/digest/crc.rb', line 197 def checksum @crc ^ @xor_mask end |
#digest_length ⇒ Integer
The length of the digest.
110 111 112 |
# File 'lib/digest/crc.rb', line 110 def digest_length (@width / 8.0).ceil end |
#finish ⇒ Object
Finishes the CRC checksum calculation.
206 207 208 |
# File 'lib/digest/crc.rb', line 206 def finish self.class.pack(checksum) end |
#reset ⇒ Integer
Resets the CRC checksum.
187 188 189 |
# File 'lib/digest/crc.rb', line 187 def reset @crc = @init_crc end |
#update(data) ⇒ Object
Updates the CRC checksum with the given data.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/digest/crc.rb', line 123 def update(data) unless @width >= 1 raise(NotImplementedError, "incompleted #{self.class} as CRC (expected WIDTH to be 1 or more)") end if @table.empty? raise(NotImplementedError, "incompleted #{self.class} as CRC (expected TABLE to be not empty)") end if @reflect_input.nil? raise(NotImplementedError, "incompleted #{self.class} as CRC (expected REFLECT_INPUT to be not nil)") end table = @table crc = @crc if @reflect_input if @width > 8 data.each_byte do |b| crc = table[b ^ (0xff & crc)] ^ (crc >> 8) end else data.each_byte do |b| # Omit (crc >> 8) since bits upper than the lower 8 bits are always 0 crc = table[b ^ (0xff & crc)] end end else if @width > 8 higher_bit_off = @width - 8 remain_mask = ~(-1 << higher_bit_off) data.each_byte do |b| crc = table[b ^ (0xff & (crc >> higher_bit_off))] ^ ((remain_mask & crc) << 8) end else padding = 8 - @width data.each_byte do |b| # Omit (crc << 8) since bits lower than the upper 8 bits are always 0 crc = table[b ^ (0xff & (crc << padding))] end end end @crc = crc self end |