crc 0.3.1.1 → 0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|