crc 0.3.1.1 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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/_utils.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
class CRC
|
2
|
+
#
|
3
|
+
# Utilities.
|
4
|
+
#
|
5
|
+
module Utils
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def bitreflect_reference(num, bitsize)
|
9
|
+
n = 0
|
10
|
+
bitsize.times { n <<= 1; n |= (num & 0x01); num >>= 1 }
|
11
|
+
n
|
12
|
+
end
|
13
|
+
|
14
|
+
def bitreflect(num, bitsize)
|
15
|
+
case
|
16
|
+
when bitsize > 128
|
17
|
+
bitreflect_reference(num, bitsize)
|
18
|
+
when bitsize > 64
|
19
|
+
bitreflect128(num) >> (128 - bitsize)
|
20
|
+
when bitsize > 32
|
21
|
+
bitreflect64(num) >> (64 - bitsize)
|
22
|
+
when bitsize > 16
|
23
|
+
bitreflect32(num) >> (32 - bitsize)
|
24
|
+
when bitsize > 8
|
25
|
+
bitreflect16(num) >> (16 - bitsize)
|
26
|
+
else
|
27
|
+
bitreflect8(num) >> (8 - bitsize)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_table(bitsize, polynomial, unfreeze = false, slice: 16)
|
32
|
+
bitmask = ~(~0 << bitsize)
|
33
|
+
table = []
|
34
|
+
Aux.slide_to_head(bitsize, 0, bitmask & polynomial, bitmask) do |xx, poly, csh, head, carries, pad|
|
35
|
+
table << (t = [])
|
36
|
+
256.times do |b|
|
37
|
+
b <<= csh
|
38
|
+
8.times { b = (b[head] == 0) ? (b << 1) : (((carries & b) << 1) ^ poly) }
|
39
|
+
t << b
|
40
|
+
end
|
41
|
+
t.freeze unless unfreeze
|
42
|
+
|
43
|
+
carries8 = carries >> 7
|
44
|
+
(1...slice).step do
|
45
|
+
tt = table[-1]
|
46
|
+
table << (t = [])
|
47
|
+
256.times do |b|
|
48
|
+
t << (table[0][tt[b] >> csh] ^ ((carries8 & tt[b]) << 8))
|
49
|
+
end
|
50
|
+
t.freeze unless unfreeze
|
51
|
+
end
|
52
|
+
0
|
53
|
+
end
|
54
|
+
table.freeze unless unfreeze
|
55
|
+
table
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_reflect_table(bitsize, polynomial, unfreeze = false, slice: 16)
|
59
|
+
polynomial = bitreflect(polynomial, bitsize)
|
60
|
+
table = []
|
61
|
+
|
62
|
+
table << (t = [])
|
63
|
+
256.times do |b|
|
64
|
+
8.times { b = (b[0] == 0) ? (b >> 1) : ((b >> 1) ^ polynomial) }
|
65
|
+
t << b
|
66
|
+
end
|
67
|
+
t.freeze unless unfreeze
|
68
|
+
|
69
|
+
(1...slice).step do
|
70
|
+
tt = table[-1]
|
71
|
+
table << (t = [])
|
72
|
+
256.times do |b|
|
73
|
+
t << (table[0][tt[b] & 0xff] ^ (tt[b] >> 8))
|
74
|
+
end
|
75
|
+
t.freeze unless unfreeze
|
76
|
+
end
|
77
|
+
|
78
|
+
table.freeze unless unfreeze
|
79
|
+
table
|
80
|
+
end
|
81
|
+
|
82
|
+
def export_table(table, bitsize, linewidth, indentsize = 2)
|
83
|
+
bitsize0 = bitsize.to_i
|
84
|
+
indent = " " * indentsize.to_i
|
85
|
+
case
|
86
|
+
when bitsize0 > 64 || bitsize0 < 1
|
87
|
+
raise "invalid bitsize (expected to 1..64, but given #{bitsize})"
|
88
|
+
when bitsize0 > 32
|
89
|
+
packformat = "Q>"
|
90
|
+
hexwidth = 16
|
91
|
+
when bitsize0 > 16
|
92
|
+
packformat = "N"
|
93
|
+
hexwidth = 8
|
94
|
+
when bitsize0 > 8
|
95
|
+
packformat = "n"
|
96
|
+
hexwidth = 4
|
97
|
+
else # when bitsize0 > 0
|
98
|
+
packformat = "C"
|
99
|
+
hexwidth = 2
|
100
|
+
end
|
101
|
+
table = table.to_a.pack("#{packformat}*").unpack("H*")[0]
|
102
|
+
table.gsub!(/(?<=\w)(?=\w{#{hexwidth}}{#{linewidth}}+$)/, "\n")
|
103
|
+
table.gsub!(/(?<=\w)(?=\w{#{hexwidth}}+$)/, " ")
|
104
|
+
table.gsub!(/(?<=\w)(?=\s|$)/, ",")
|
105
|
+
table.gsub!(/(?:(?<=^)|(?<=\s))(?=\w)/, "0x")
|
106
|
+
table.gsub!(/^/, "#{indent} ")
|
107
|
+
<<-EOS
|
108
|
+
#{indent}TABLE = [
|
109
|
+
#{table}
|
110
|
+
#{indent}].freeze
|
111
|
+
EOS
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/crc/acrc.rb
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
require_relative "../crc"
|
4
4
|
|
5
5
|
class CRC
|
6
|
-
|
6
|
+
using CRC::Extensions
|
7
|
+
|
8
|
+
module Calcurator
|
7
9
|
#
|
8
10
|
# call-seq:
|
9
|
-
# acrc(
|
11
|
+
# acrc(pre, post = nil, targetcrc = 0) -> byte string as arc-code
|
10
12
|
#
|
11
13
|
# 目的となる crc になるように、指定された crc に続くバイト列を逆算します。
|
12
14
|
#
|
13
15
|
# 出力されるバイト列は、crc のビット数を表現できるバイト数となります。
|
14
16
|
#
|
15
|
-
# 現在のところ、reflect-input/output 限定となっています。
|
16
|
-
#
|
17
17
|
# * crc32("123456789????") の結果が 0 となるような、???? の部分を逆算する
|
18
18
|
#
|
19
19
|
# seq = "123456789"
|
@@ -31,75 +31,20 @@ class CRC
|
|
31
31
|
#
|
32
32
|
# seq1 = "123456789"
|
33
33
|
# seq2 = "ABCDEFG"
|
34
|
-
#
|
35
|
-
# seq = seq1 + CRC::CRC32.acrc(seq1, seq2,
|
34
|
+
# targetcrc = 0x12345678
|
35
|
+
# seq = seq1 + CRC::CRC32.acrc(seq1, seq2, targetcrc) + seq2
|
36
36
|
# p CRC::CRC32[seq] # => #<CRC::CRC32:12345678>
|
37
37
|
#
|
38
|
-
def acrc(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rest_seq.bytesize.downto(1) do |i|
|
49
|
-
target_crc = Aux.acrc_loop_reflect(target_crc, rest_seq.getbyte(i - 1), poly, bitsize, 0xff, 8)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
bytes = (bitsize + 7) / 8
|
54
|
-
bits = bytes * 8
|
55
|
-
|
56
|
-
case crc
|
57
|
-
when Numeric
|
58
|
-
state = bitmask & crc ^ xor_output
|
59
|
-
when CRC
|
60
|
-
raise "different crc module (given %p(%p), expect %p)" % [crc, crc.class, self] unless variant?(crc)
|
61
|
-
state = crc.state
|
62
|
-
else
|
63
|
-
state = new(crc).state
|
64
|
-
end
|
65
|
-
|
66
|
-
if bits > bitsize
|
67
|
-
# ビット数が 8 の境界にない場合、その隙間分を埋める。
|
68
|
-
# 現在の実装では、最終結果のバイト列における最終バイト値の
|
69
|
-
# 上位ビットが 0 であるようにしている。
|
70
|
-
pad = bits - bitsize
|
71
|
-
target_crc = Aux.acrc_loop_reflect(target_crc, 0, poly, bitsize, 0xff, pad)
|
72
|
-
end
|
73
|
-
|
74
|
-
target_crc = Aux.acrc_loop_reflect(target_crc, state, poly, bitsize, bitmask, bitsize)
|
75
|
-
|
76
|
-
bytes.times.reduce("") { |a, *| a << (target_crc & 0xff).chr(Encoding::BINARY); target_crc >>= 8; a }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
module Aux
|
81
|
-
def self.acrc_loop_reflect(target_crc, state, poly, crcbits, bitmask, bits)
|
82
|
-
head = bits - 1
|
83
|
-
bitmask1 = bitmask >> 1
|
84
|
-
crchead = crcbits - 1
|
85
|
-
|
86
|
-
#puts "target_crc=0b%016b, state=0b%016b, reversed-polynomial=0b%016b" % [target_crc, state, poly]
|
87
|
-
bits.times do |i|
|
88
|
-
if target_crc[crchead] == 0
|
89
|
-
target_crc <<= 1
|
90
|
-
else
|
91
|
-
target_crc ^= poly
|
92
|
-
target_crc <<= 1
|
93
|
-
target_crc |= 0x01
|
94
|
-
end
|
95
|
-
|
96
|
-
target_crc ^= state[head]
|
97
|
-
#puts " 0_%016b ^ %d" % [target_crc, state[head]]
|
98
|
-
state = (state & bitmask1) << 1
|
99
|
-
end
|
100
|
-
#puts "target_crc=0b%016b" % target_crc
|
101
|
-
|
102
|
-
target_crc
|
38
|
+
def acrc(pre, post = nil, targetcrc = 0)
|
39
|
+
pre = pre.convert_internal_state_for(self)
|
40
|
+
laststate = targetcrc.convert_target_state_for(self)
|
41
|
+
state = unshiftbytes(post, laststate)
|
42
|
+
bytesize = (bitsize + 7) / 8
|
43
|
+
pre <<= (bytesize * 8 - bitsize) unless reflect_input?
|
44
|
+
bytes = pre.splitbytes("".b, bytesize, reflect_input?)
|
45
|
+
state = unshiftbytes(bytes, state)
|
46
|
+
state <<= (bytesize * 8 - bitsize) unless reflect_input?
|
47
|
+
state.splitbytes("".b, bytesize, reflect_input?)
|
103
48
|
end
|
104
49
|
end
|
105
50
|
end
|
data/lib/crc/codegen.rb
CHANGED
@@ -854,7 +854,7 @@ end
|
|
854
854
|
raise ArgumentError, "out of algorithm code (given #{algorithm})"
|
855
855
|
end
|
856
856
|
(<<-EOS).gsub!(/^(?!$)/, " ").gsub!(/^/) { line_prefix }.chomp!
|
857
|
-
A CRC
|
857
|
+
A CRC calculator for #{crcname}.
|
858
858
|
|
859
859
|
This code is auto generated by <https://rubygems.org/gems/crc>.
|
860
860
|
|
data/lib/crc/version.rb
CHANGED
data/test/common.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require "crc"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
alltest = false
|
8
|
+
opt = OptionParser.new(nil, 12, " ")
|
9
|
+
opt.instance_eval do
|
10
|
+
on("--all", "test all crc modules") { alltest = true }
|
11
|
+
order!
|
12
|
+
end
|
13
|
+
|
14
|
+
if alltest
|
15
|
+
$testmodules = CRC::MODULE_TABLE.values.uniq
|
16
|
+
else
|
17
|
+
$testmodules = %w(
|
18
|
+
CRC-32 CRC-32-POSIX CRC-64 CRC-64-ECMA
|
19
|
+
CRC-3-ROHC CRC-5-USB CRC-7-ROHC CRC-7-UMTS CRC-8-CCITT CRC-8-MAXIM
|
20
|
+
CRC-15 CRC-16 CRC-16-XMODEM CRC-24-OPENPGP CRC-24-BLE CRC-31-PHILIPS
|
21
|
+
).map { |e| CRC[e] }
|
22
|
+
end
|
23
|
+
|
data/test/self_check.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "crc"
|
2
|
+
|
3
|
+
$stderr.puts "#{__FILE__}:#{__LINE__}: SELF CHECK for CRC modules (#{File.basename($".grep(/_(?:byruby|turbo)/)[0]||"")})\n"
|
4
|
+
|
5
|
+
class CRC
|
6
|
+
MODULE_TABLE.values.uniq.each do |crc|
|
7
|
+
check = crc::CHECK
|
8
|
+
checked = crc.crc("123456789")
|
9
|
+
case check
|
10
|
+
when nil
|
11
|
+
$stderr.puts "| %20s(\"123456789\" * 1) = %16X (check only)\n" % [crc.name, checked]
|
12
|
+
when checked
|
13
|
+
;
|
14
|
+
else
|
15
|
+
$stderr.puts "| %20s(\"123456789\" * 1) = %16X (expect to %X)\n" % [crc.name, checked, check]
|
16
|
+
end
|
17
|
+
|
18
|
+
check = 9.times.reduce(crc.new) { |a, x| a + crc.new(crc::CHECK, 9) }
|
19
|
+
checked = crc["123456789" * 9]
|
20
|
+
case check
|
21
|
+
when nil
|
22
|
+
$stderr.puts "| %20s(\"123456789\" * 9) = %16X (check only)\n" % [crc.name, checked]
|
23
|
+
when checked
|
24
|
+
;
|
25
|
+
else
|
26
|
+
$stderr.puts "| %20s(\"123456789\" * 9) = %16X (expect to %X)\n" % [crc.name, checked, check]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
$stderr.puts "#{__FILE__}:#{__LINE__}: DONE SELF CHECK\n"
|
data/test/test_block.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require "crc"
|
5
|
+
require_relative "common"
|
6
|
+
|
7
|
+
class TestCRC < Test::Unit::TestCase
|
8
|
+
$testmodules.each do |crc|
|
9
|
+
next unless crc.const_defined?(:CHECK) && crc::CHECK
|
10
|
+
class_eval(<<-"EOS", __FILE__, __LINE__ + 1)
|
11
|
+
def test_block_#{crc.to_s.slice(/\w+$/)}
|
12
|
+
assert_equal(#{crc}::CHECK, #{crc}.crc("123456789"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_stream_#{crc.to_s.slice(/\w+$/)}
|
16
|
+
s = #{crc}.new
|
17
|
+
s << "123456789"
|
18
|
+
assert_equal(#{crc}::CHECK, s.crc)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_stream2_#{crc.to_s.slice(/\w+$/)}
|
22
|
+
s = #{crc}.new
|
23
|
+
"123456789".each_char { |ch| s << ch }
|
24
|
+
assert_equal(#{crc}::CHECK, s.crc)
|
25
|
+
end
|
26
|
+
EOS
|
27
|
+
end
|
28
|
+
end
|
data/test/test_magic.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require "crc"
|
5
|
+
require_relative "common"
|
6
|
+
|
7
|
+
class TestCRCMagic < Test::Unit::TestCase
|
8
|
+
$testmodules.each do |crc|
|
9
|
+
next unless crc.const_defined?(:CHECK) && crc::CHECK
|
10
|
+
name = crc.to_s.slice(/\w+$/)
|
11
|
+
class_eval(<<-"TESTCODE", __FILE__, __LINE__ + 1)
|
12
|
+
def test_magic_#{name}
|
13
|
+
assert_equal #{crc}.magic, #{crc}.hexdigest(#{crc}.magicdigest(""))
|
14
|
+
assert_equal #{crc}.magic, #{crc}.hexdigest("A" + #{crc}.magicdigest("A"))
|
15
|
+
assert_equal #{crc}.magic, #{crc}.hexdigest("A" * 100 + #{crc}.magicdigest("A" * 100))
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_magicnumber_#{name}
|
19
|
+
assert_equal #{crc}.magicnumber, #{crc}.crc(#{crc}.magicdigest(""))
|
20
|
+
assert_equal #{crc}.magicnumber, #{crc}.crc("A" + #{crc}.magicdigest("A"))
|
21
|
+
assert_equal #{crc}.magicnumber, #{crc}.crc("A" * 100 + #{crc}.magicdigest("A" * 100))
|
22
|
+
end
|
23
|
+
TESTCODE
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dearblue
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
description: |
|
28
|
-
Pure ruby implemented general CRC (Cyclic Redundancy Check)
|
28
|
+
Pure ruby implemented general CRC (Cyclic Redundancy Check) calcurator.
|
29
29
|
Customization is posible for 1 to 64 bit width, any polynomials, and with/without bit reflection input/output.
|
30
30
|
If you need more speed, please use crc-turbo.
|
31
|
-
email: dearblue@users.
|
31
|
+
email: dearblue@users.noreply.github.com
|
32
32
|
executables:
|
33
33
|
- rbcrc
|
34
34
|
extensions: []
|
@@ -37,9 +37,15 @@ extra_rdoc_files:
|
|
37
37
|
- LICENSE
|
38
38
|
- README.md
|
39
39
|
- lib/crc.rb
|
40
|
+
- lib/crc/_aux.rb
|
40
41
|
- lib/crc/_byruby.rb
|
41
42
|
- lib/crc/_combine.rb
|
43
|
+
- lib/crc/_extensions.rb
|
44
|
+
- lib/crc/_file.rb
|
45
|
+
- lib/crc/_magic.rb
|
42
46
|
- lib/crc/_modules.rb
|
47
|
+
- lib/crc/_shift.rb
|
48
|
+
- lib/crc/_utils.rb
|
43
49
|
- lib/crc/acrc.rb
|
44
50
|
- lib/crc/codegen.rb
|
45
51
|
- lib/crc/finder.rb
|
@@ -53,14 +59,24 @@ files:
|
|
53
59
|
- bin/rbcrc
|
54
60
|
- gemstub.rb
|
55
61
|
- lib/crc.rb
|
62
|
+
- lib/crc/_aux.rb
|
56
63
|
- lib/crc/_byruby.rb
|
57
64
|
- lib/crc/_combine.rb
|
65
|
+
- lib/crc/_extensions.rb
|
66
|
+
- lib/crc/_file.rb
|
67
|
+
- lib/crc/_magic.rb
|
58
68
|
- lib/crc/_modules.rb
|
69
|
+
- lib/crc/_shift.rb
|
70
|
+
- lib/crc/_utils.rb
|
59
71
|
- lib/crc/acrc.rb
|
60
72
|
- lib/crc/codegen.rb
|
61
73
|
- lib/crc/finder.rb
|
62
74
|
- lib/crc/version.rb
|
63
|
-
|
75
|
+
- test/common.rb
|
76
|
+
- test/self_check.rb
|
77
|
+
- test/test_block.rb
|
78
|
+
- test/test_magic.rb
|
79
|
+
homepage: https://github.com/dearblue/ruby-crc-turbo
|
64
80
|
licenses:
|
65
81
|
- BSD-2-Clause
|
66
82
|
- Zlib
|
@@ -78,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
94
|
requirements:
|
79
95
|
- - ">="
|
80
96
|
- !ruby/object:Gem::Version
|
81
|
-
version: '2.
|
97
|
+
version: '2.2'
|
82
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
99
|
requirements:
|
84
100
|
- - ">="
|
@@ -86,8 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
102
|
version: '0'
|
87
103
|
requirements: []
|
88
104
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.6.
|
105
|
+
rubygems_version: 2.6.10
|
90
106
|
signing_key:
|
91
107
|
specification_version: 4
|
92
|
-
summary: general CRC
|
108
|
+
summary: general CRC calcurator
|
93
109
|
test_files: []
|