crc - CRC generator for ruby
This is a general CRC (Cyclic Redundancy Check) generator for ruby.
It is written by pure ruby with based on slice-by-eight algorithm (slice-by-16 algorithm as byte-order free and byte-alignment free).
Included built-in CRC modules are CRC-32, CRC-64-ECMA, CRC-64-ISO, CRC-16-CCITT, CRC-16-IBM, CRC-8, CRC-5-USB, CRC-5-EPC and many more.
Customization is posible for 1 to 64 bit width, any polynomial primitives, and with/without bit reflection input/output.
This library is slower than ×85+ of zlib/crc32, and slower than ×120+ of extlzma/crc32 on FreeBSD 10.3R amd64.
If you need more speed, please use crc-turbo.
Summary
- package name: crc
- author: dearblue (mailto:[email protected])
- report issue to: https://osdn.jp/projects/rutsubo/ticket/
- how to install:
gem install crc
- version: 0.3
- release quality: technical preview
- licensing: BSD-2-Clause
any parts are under Creative Commons License Zero (CC0 / Public Domain), and zlib-style License. - dependency gems: none
- dependency external C libraries: none
- bundled external C libraries: none
API Guide
This examples are used CRC-32 module. Please see CRC for more details.
Calcurate by direct
CRC.crc32(seq, init = CRC::CRC32.initial_crc) => crc-32 integer
(likely asZlib.crc32
)CRC.crc32.crc(seq, init = CRC::CRC32.initial_crc) => crc-32 integer
(likely asZlib.crc32
)CRC.crc32.digest(seq, init = CRC::CRC32.initial_crc) => crc-32 digest
(likely asDigest::XXXX.digest
)CRC.crc32.hexdigest(seq, init = 0) -> crc-32 hex-digest
(likely asDigest::XXXX.hexdigest
)CRC.crc32[seq, init = 0, current_length = 0] -> crc-32 generator
CRC.crc32.new(seq, init = 0, current_length = 0) -> crc-32 generator
Calcurate by streaming
CRC.crc32[init = 0, current_length = 0] => crc-32 generator
CRC.crc32.new(init = 0, current_length = 0) => crc-32 generator
CRC.crc32#update(seq) => self
(likely asDigest::XXXX.update
)CRC.crc32#finish => crc-32 integer
(likely asDigest::XXXX.finish
)CRC.crc32#crc => crc-32 integer
(same asCRC.crc32#finish
)CRC.crc32#digest => crc-32 digest
(likely asDigest::XXXX.digest
)CRC.crc32#hexdigest => crc-32 hex-digest
(likely asDigest::XXXX.hexdigest
)
Example:
x = CRC.crc32.new # => #<CRC::CRC32:00000000> x.update "123" # => #<CRC::CRC32:884863D2> x.update "456789" # => #<CRC::CRC32:CBF43926> x.crc # => 3421780262 x.digest # => "\xCB\xF49&" x.hexdigest # => "CBF43926"
Combine
CRC.combine(crc1, crc2, len2) => combined crc integer
(likely asZlib.crc32_comibne
)CRC#+(right_crc) => combined crc generator
Example-1:
CRC.crc32.combine(CRC.crc32("123"), CRC.crc32("456789"), 6) # => 3421780262
Example-2:
CRC.crc32["123"] + CRC.crc32["456"] + CRC.crc32["789"] # => #<CRC::CRC32:CBF43926>
Create customized crc module
CRC.new(bitsize, poly, initial_crc = 0, refin = true, refout = true, xor_output = ~0) => new crc module class
MyCRC32 = CRC.new(32, 0x04C11DB7) MyCRC32.class # => Class MyCRC32.hexdigest("123456789") # => "CBF43926" MyCRC32.new("123456789") # => #<MyCRC32:CBF43926>
Calcurate arc-crc (EXPERIMENTAL)
CRC.acrc(pre, post = nil, want_crc = 0) => arc-crc byte string
a = "12" c = "789" wantcrc = 0xCBF43926 b = CRC.crc32.acrc(a, c, wantcrc) # => "3456" CRC.crc32[a + b + c] # => #<CRC::CRC32:CBF43926>
See CRC::ModuleClass.acrc for more detail.
Built-in CRC modules
% ruby -rcrc -e 'puts CRC::MODULE_TABLE.values.uniq.map { |m| m.name }.join(", ")'
CRC-1, CRC-3-ROHC, CRC-4-INTERLAKEN, CRC-4-ITU, CRC-5-EPC, CRC-5-ITU, CRC-5-USB, CRC-6-CDMA2000-A, CRC-6-CDMA2000-B, CRC-6-DARC, CRC-6-ITU, CRC-7, CRC-7-MVB, CRC-7-ROHC, CRC-7-UMTS, CRC-8, CRC-8-CCITT, CRC-8-MAXIM, CRC-8-DARC, CRC-8-SAE, CRC-8-WCDMA, CRC-8-CDMA2000, CRC-8-DVB-S2, CRC-8-EBU, CRC-8-I-CODE, CRC-8-ITU, CRC-8-LTE, CRC-8-ROHC, CRC-10, CRC-10-CDMA2000, CRC-11, CRC-11-UMTS, CRC-12-CDMA2000, CRC-12-DECT, CRC-12-UMTS, CRC-13-BBC, CRC-14-DARC, CRC-15, CRC-15-MPT1327, Chakravarty, CRC-16, CRC-16-ARINC, CRC-16-AUG-CCITT, CRC-16-CDMA2000, CRC-16-DECT-R, CRC-16-DECT-X, CRC-16-T10-DIF, CRC-16-DNP, CRC-16-BUYPASS, CRC-16-CCITT-FALSE, CRC-16-DDS-110, CRC-16-EN-13757, CRC-16-GENIBUS, CRC-16-LJ1200, CRC-16-MAXIM, CRC-16-MCRF4XX, CRC-16-RIELLO, CRC-16-TELEDISK, CRC-16-TMS37157, CRC-16-USB, CRC-16-A, CRC-16-KERMIT, CRC-16-MODBUS, CRC-16-X-25, CRC-16-XMODEM, CRC-17-CAN, CRC-21-CAN, CRC-24, CRC-24-Radix-64, CRC-24-OPENPGP, CRC-24-BLE, CRC-24-FLEXRAY-A, CRC-24-FLEXRAY-B, CRC-24-INTERLAKEN, CRC-24-LTE-A, CRC-24-LTE-B, CRC-30, CRC-30-CDMA, CRC-31-PHILIPS, CRC-32, CRC-32-BZIP2, CRC-32C, CRC-32D, CRC-32-MPEG-2, CRC-32-POSIX, CRC-32K, CRC-32K2, CRC-32Q, CRC-32-JAMCRC, CRC-32-XFER, CRC-40-GSM, CRC-64-XZ, CRC-64-ECMA, CRC-64-WE, CRC-64-ISO
Environment variables for behavior
RUBY_CRC_NOFAST=0
: Use "crc-turbo" if posible. When failure required, same asRUBY_CRC_NOFAST=1
.RUBY_CRC_NOFAST=1
: Force use ruby implementation with slice-by-16 algorithm. Not used "crc-turbo".RUBY_CRC_NOFAST=2
: Switch to lookup table algorithm from slice-by-16 algorithm. Slower than about 52% (when CRC-32).RUBY_CRC_NOFAST=3
: Switch to reference algorithm from slice-by-16 algorithm. Slower than about 7% (when CRC-32).
About CRC.combine
CRC.combine is ported from Mark Adler's crccomb.c in https://stackoverflow.com/questions/29915764/generic-crc-8-16-32-64-combine-implementation#29928573.
arc-crc (EXPERIMENTAL)
(Written in japanese from here)
crc-0.3 にて、任意の CRC となるバイト列を逆算する機能が実験的に追加されました。
今のところは、reflect-input/output 限定となっています。
require "crc/acrc"
にて、その機能が利用可能となります。
名前の由来は、arc-sin などの C 関数である asin と同様に、arc-crc => acrc となっています。
以下は使用例です。
文字列 "123456789????" を CRC32 した場合に 0 となるような、???? の部分を逆算する
require "crc/acrc" seq = "123456789" seq << CRC.crc32.acrc(seq) p CRC.crc32[seq] # => #<CRC::CRC32:00000000>
文字列 "123456789????ABCDEFG" の、???? の部分を逆算する
require "crc/acrc" seq1 = "123456789" seq2 = "ABCDEFG" seq = seq1 + CRC.crc32.acrc(seq1, seq2) + seq2 p CRC.crc32[seq] # => #<CRC::CRC32:00000000>
文字列 "123456789????ABCDEFG" を CRC32 した場合に 0x12345678 となるような、???? の部分を逆算する
require "crc/acrc" seq1 = "123456789" seq2 = "ABCDEFG" target_crc = 0x12345678 seq = seq1 + CRC.crc32.acrc(seq1, seq2, target_crc) + seq2 p CRC.crc32[seq] # => #<CRC::CRC32:12345678>
独自仕様の CRC モジュールにも対応
require "crc/acrc" seq1 = "123456789" seq2 = "ABCDEFG" target_crc = 0x12345678 MyCRC = CRC.new(29, rand(1 << 29) | 1) seq = seq1 + MyCRC.acrc(seq1, seq2, target_crc) + seq2 p MyCRC[seq] # => #<MyCRC:12345678>
[EOF]