Skip to content

A Cyclic Redundancy Check (CRC) library for Ruby.

License

Notifications You must be signed in to change notification settings

manuyavuz-pointr/digest-crc

 
 

Repository files navigation

Digest CRC

Build Status

Description

Adds support for calculating Cyclic Redundancy Check (CRC) to the Digest module.

Features

  • Provides support for the following CRC algorithms:
    • {Digest::CRC1 CRC1}
    • {Digest::CRC5 CRC5}
    • {Digest::CRC8 CRC8}
    • {Digest::CRC8_1Wire CRC8 1-Wire}
    • {Digest::CRC15 CRC15}
    • {Digest::CRC16 CRC16}
    • {Digest::CRC16CCITT CRC16 CCITT}
    • {Digest::CRC16DNP CRC16 DNP}
    • {Digest::CRC16Genibus CRC16 Genibus}
    • {Digest::CRC16Kermit CRC16 Kermit}
    • {Digest::CRC16Modbus CRC16 Modbus}
    • {Digest::CRC16USB CRC16 USB}
    • {Digest::CRC16X25 CRC16 X25}
    • {Digest::CRC16XModem CRC16 XModem}
    • {Digest::CRC16ZModem CRC16 ZModem}
    • {Digest::CRC16QT CRC16 QT}
    • {Digest::CRC24 CRC24}
    • {Digest::CRC32 CRC32}
    • {Digest::CRC32BZip2 CRC32 BZip2}
    • {Digest::CRC32c CRC32c}
    • {Digest::CRC32Jam CRC32 Jam}
    • {Digest::CRC32MPEG CRC32 MPEG}
    • {Digest::CRC32POSIX CRC32 POSIX}
    • {Digest::CRC32XFER CRC32 XFER}
    • {Digest::CRC64 CRC64}
    • {Digest::CRC64Jones CRC64 Jones}
    • {Digest::CRC64XZ CRC64 XZ}
  • Pure Ruby implementation.
  • Provides CRC Tables for optimized calculations.
  • Supports optional C extensions which increases performance by ~40x.
    • If the C extensions cannot be compiled for whatever reason, digest-crc will automatically fallback to the pure-Ruby implementation.

Install

gem install digest-crc

Examples

Calculate a CRC32:

require 'digest/crc32'

Digest::CRC32.hexdigest('hello')
# => "3610a686"

Calculate a CRC32 of a file:

Digest::CRC32.file('README.md')
# => #<Digest::CRC32: 127ad531>

Incrementally calculate a CRC32:

crc = Digest::CRC32.new
crc << 'one'
crc << 'two'
crc << 'three'
crc.hexdigest
# => "09e1c092"

Directly access the checksum:

crc.checksum
# => 165789842

Defining your own CRC class:

require 'digest/crc32'

module Digest
  class CRC3000 < CRC32

    WIDTH = 4

    INIT_CRC = 0xffffffff

    XOR_MASK = 0xffffffff

    TABLE = [
      # ....
    ].freeze

    def update(data)
      data.each_byte do |b|
        @crc = (((@crc >> 8) & 0x00ffffff) ^ @table[(@crc ^ b) & 0xff])
      end

      return self
    end
  end
end

Benchmarks

Pure Ruby (ruby 2.7.1)

$ bundle exec rake clean
$ bundle exec ./benchmarks.rb
Loading Digest::CRC classes ...
Generating 1000 8Kb lengthed strings ...
Benchmarking Digest::CRC classes ...
       user     system      total        real
Digest::CRC1#update  0.349756   0.000002   0.349758 (  0.351427)
Digest::CRC5#update  1.175206   0.000049   1.175255 (  1.180975)
Digest::CRC8#update  1.023536   0.000015   1.023551 (  1.029017)
Digest::CRC8_1Wire#update  1.012156   0.000000   1.012156 (  1.017342)
Digest::CRC15#update  1.187286   0.000005   1.187291 (  1.193634)
Digest::CRC16#update  0.998527   0.000013   0.998540 (  1.003940)
Digest::CRC16CCITT#update  1.179864   0.000005   1.179869 (  1.186134)
Digest::CRC16DNP#update  1.018969   0.000003   1.018972 (  1.025248)
Digest::CRC16Genibus#update  1.196754   0.000065   1.196819 (  1.203605)
Digest::CRC16Modbus#update  1.007367   0.000000   1.007367 (  1.012325)
Digest::CRC16X25#update  1.044127   0.000000   1.044127 (  1.052010)
Digest::CRC16USB#update  1.012804   0.000000   1.012804 (  1.018324)
Digest::CRC16X25#update  1.009694   0.000000   1.009694 (  1.015890)
Digest::CRC16XModem#update  1.210814   0.000000   1.210814 (  1.217951)
Digest::CRC16ZModem#update  1.175239   0.000000   1.175239 (  1.181395)
Digest::CRC24#update  1.207431   0.000000   1.207431 (  1.213373)
Digest::CRC32#update  1.012334   0.000000   1.012334 (  1.017671)
Digest::CRC32BZip2#update  1.190351   0.000000   1.190351 (  1.196567)
Digest::CRC32c#update  1.021147   0.000000   1.021147 (  1.027035)
Digest::CRC32Jam#update  1.002365   0.000000   1.002365 (  1.007202)
Digest::CRC32MPEG#update  1.161925   0.000000   1.161925 (  1.168058)
Digest::CRC32POSIX#update  1.191860   0.000967   1.192827 (  1.198722)
Digest::CRC32XFER#update  1.217692   0.000000   1.217692 (  1.224075)
Digest::CRC64#update  3.084106   0.000000   3.084106 (  3.106840)
Digest::CRC64Jones#update  3.016687   0.000000   3.016687 (  3.038963)
Digest::CRC64XZ#update  3.019690   0.000000   3.019690 (  3.040971)

C extensions (ruby 2.7.1)

$ bundle exec rake build:c_exts
...
$ bundle exec ./benchmarks.rb
Loading Digest::CRC classes ...
Generating 1000 8Kb lengthed strings ...
Benchmarking Digest::CRC classes ...
       user     system      total        real
Digest::CRC1#update  0.356025   0.000016   0.356041 (  0.365345)
Digest::CRC5#update  0.023957   0.000001   0.023958 (  0.024835)
Digest::CRC8#update  0.021254   0.000007   0.021261 (  0.024647)
Digest::CRC8_1Wire#update  0.039129   0.000000   0.039129 (  0.042417)
Digest::CRC15#update  0.030285   0.000000   0.030285 (  0.030560)
Digest::CRC16#update  0.023003   0.000000   0.023003 (  0.023267)
Digest::CRC16CCITT#update  0.028207   0.000000   0.028207 (  0.028467)
Digest::CRC16DNP#update  0.022861   0.000000   0.022861 (  0.023111)
Digest::CRC16Genibus#update  0.028041   0.000000   0.028041 (  0.028359)
Digest::CRC16Modbus#update  0.022931   0.000009   0.022940 (  0.023560)
Digest::CRC16X25#update  0.022808   0.000000   0.022808 (  0.023054)
Digest::CRC16USB#update  0.022258   0.000882   0.023140 (  0.023418)
Digest::CRC16X25#update  0.022816   0.000000   0.022816 (  0.023084)
Digest::CRC16XModem#update  0.027984   0.000000   0.027984 (  0.028269)
Digest::CRC16ZModem#update  0.027968   0.000000   0.027968 (  0.028214)
Digest::CRC24#update  0.028426   0.000000   0.028426 (  0.028687)
Digest::CRC32#update  0.022805   0.000000   0.022805 (  0.023043)
Digest::CRC32BZip2#update  0.025519   0.000000   0.025519 (  0.025797)
Digest::CRC32c#update  0.022807   0.000000   0.022807 (  0.023069)
Digest::CRC32Jam#update  0.023006   0.000000   0.023006 (  0.023231)
Digest::CRC32MPEG#update  0.025536   0.000000   0.025536 (  0.025861)
Digest::CRC32POSIX#update  0.025557   0.000000   0.025557 (  0.025841)
Digest::CRC32XFER#update  0.025310   0.000000   0.025310 (  0.025599)
Digest::CRC64#update  0.023182   0.000000   0.023182 (  0.023421)
Digest::CRC64Jones#update  0.022916   0.000000   0.022916 (  0.023139)
Digest::CRC64XZ#update  0.022879   0.000000   0.022879 (  0.023131)

Pure Ruby (jruby 9.2.12.0)

$ bundle exec ./benchmarks.rb
Loading Digest::CRC classes ...
Generating 1000 8Kb lengthed strings ...
Benchmarking Digest::CRC classes ...
       user     system      total        real
Digest::CRC1#update  1.030000   0.090000   1.120000 (  0.511189)
Digest::CRC5#update  1.620000   0.060000   1.680000 (  1.096031)
Digest::CRC8#update  1.560000   0.070000   1.630000 (  1.083921)
Digest::CRC8_1Wire#update  0.930000   0.040000   0.970000 (  0.927024)
Digest::CRC15#update  1.590000   0.070000   1.660000 (  1.132566)
Digest::CRC16#update  1.650000   0.060000   1.710000 (  1.074508)
Digest::CRC16CCITT#update  1.610000   0.060000   1.670000 (  1.190860)
Digest::CRC16DNP#update  1.270000   0.010000   1.280000 (  0.938132)
Digest::CRC16Genibus#update  1.620000   0.030000   1.650000 (  1.148556)
Digest::CRC16Modbus#update  1.070000   0.020000   1.090000 (  0.881455)
Digest::CRC16X25#update  1.110000   0.010000   1.120000 (  0.945366)
Digest::CRC16USB#update  1.140000   0.000000   1.140000 (  0.984367)
Digest::CRC16X25#update  0.920000   0.010000   0.930000 (  0.872541)
Digest::CRC16XModem#update  1.530000   0.010000   1.540000 (  1.092838)
Digest::CRC16ZModem#update  1.720000   0.010000   1.730000 (  1.164787)
Digest::CRC24#update  1.810000   0.020000   1.830000 (  1.084953)
Digest::CRC32#update  1.590000   0.010000   1.600000 (  1.105553)
Digest::CRC32BZip2#update  1.520000   0.010000   1.530000 (  1.070839)
Digest::CRC32c#update  0.960000   0.010000   0.970000 (  0.881989)
Digest::CRC32Jam#update  1.030000   0.010000   1.040000 (  0.907208)
Digest::CRC32MPEG#update  1.420000   0.010000   1.430000 (  0.994035)
Digest::CRC32POSIX#update  1.530000   0.020000   1.550000 (  1.106366)
Digest::CRC32XFER#update  1.650000   0.010000   1.660000 (  1.097647)
Digest::CRC64#update  3.440000   0.030000   3.470000 (  2.771806)
Digest::CRC64Jones#update  2.630000   0.010000   2.640000 (  2.628016)
Digest::CRC64XZ#update  3.200000   0.020000   3.220000 (  2.913442)

Thanks

Special thanks go out to the pycrc library which is able to generate C source-code for all of the CRC algorithms, including their CRC Tables.

License

Copyright (c) 2010-2020 Hal Brodigan

See {file:LICENSE.txt} for license information.

About

A Cyclic Redundancy Check (CRC) library for Ruby.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C 52.3%
  • Ruby 47.7%