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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77aec27c0554b78347e7fae144088b66cc038a06
|
4
|
+
data.tar.gz: a670a4d32e830857f1f52eca35c55dce4f9daec4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9106bd5897d640ac339e07d9ae750a6102c6dad97a5e0c7c23e946ec249a600c6c4a1f56df54bd0806ab98d47155ebeb0bb8965a31d467d60ebc687755d5cbe
|
7
|
+
data.tar.gz: db773998a7c2e3542ea30faf93b38628959a4376d8899dca2640a77aae39695b2f5efb8de283e1fce3cf8a1cfd1adb1b57830a5f59c096994984da06514263db
|
data/HISTORY.ja.md
CHANGED
@@ -2,6 +2,54 @@ This document is written in Japanese.
|
|
2
2
|
|
3
3
|
# crc for ruby の更新履歴
|
4
4
|
|
5
|
+
## crc-0.4 (TRYOUT)
|
6
|
+
|
7
|
+
***互換性を損なう変更があります。***
|
8
|
+
|
9
|
+
* **[互換性を損なう変更]** CRC.new と CRC.[] の役割を分担
|
10
|
+
|
11
|
+
* これまで CRC をサブクラスとしたクラスメソッド CRC.new と CRC.[] は全く同じ挙動をしていましたが、役割を分担しました。
|
12
|
+
|
13
|
+
``CRC.new`` は初期化のためのメソッドとし、``CRC.[]`` は CRC インスタンスを返す ``CRC.crc`` のようなメソッドとなるようにしました。
|
14
|
+
|
15
|
+
* ``CRC.new(seq, ...)`` の形では呼び出せなくなりました。
|
16
|
+
|
17
|
+
* ``CRC.[](seq, ...)`` の seq は必須としました。
|
18
|
+
|
19
|
+
* **[互換性を損なう変更]** bin/rbcrc のオプション名を変更
|
20
|
+
|
21
|
+
* ``-M`` および ``-N`` オプションをそれぞれ小文字に変更しました。
|
22
|
+
|
23
|
+
* ``CRC.file`` 及び ``CRC#file`` メソッドの追加
|
24
|
+
|
25
|
+
* ファイルパスを与えると CRC を計算してインスタンスを返す ``CRC.file`` 及び ``CRC#file`` を追加しました。
|
26
|
+
|
27
|
+
* ``CRC.magic``、``CRC.magicnumber``、``CRC.magicdigest``、``CRC.to_magicdigest``、``CRC#magicdigest`` メソッドの追加
|
28
|
+
|
29
|
+
* マジックナンバーを取得・計算するためのメソッドを追加しました。
|
30
|
+
|
31
|
+
これらは CRC-32 の場合であれば RFC1570 で出てくるマジックナンバー 0xdebb20e3 のことです。
|
32
|
+
|
33
|
+
* 任意の CRC 値から逆算してバイト列を生成する機能 CRC.acrc (crc/acrc.rb) を正式に追加
|
34
|
+
|
35
|
+
* crc-0.3 で実験的に追加された同機能を、正式なものとしました。
|
36
|
+
|
37
|
+
この機能は入出力の正順・逆順に関わらずに利用可能です。
|
38
|
+
|
39
|
+
* ``CRC.shiftbits`` ``CRC.shiftbytes`` ``CRC.unshiftbits`` ``CRC.unshiftbytes`` を追加
|
40
|
+
|
41
|
+
* 任意長のビット列を与えて内部状態を更新する ``CRC.shiftbits`` を追加しました。
|
42
|
+
|
43
|
+
* 任意長の8ビット列を与えて内部状態を更新する ``CRC.shiftbytes`` を追加しました。
|
44
|
+
* ``CRC.update`` とは異なり、整数値で構成される配列を渡すことが出来ます。
|
45
|
+
|
46
|
+
* 任意長のビット列を与えて内部状態を差し戻す ``CRC.unshiftbits`` を追加しました。
|
47
|
+
|
48
|
+
* 任意長の8ビット列を与えて内部状態を差し戻す ``CRC.unshiftbytes`` を追加しました。
|
49
|
+
|
50
|
+
* **[BUG FIX]** 入出力のビット送り方向が異なる場合、CRC.reset が不正な初期化を行っていた問題を修正
|
51
|
+
|
52
|
+
|
5
53
|
## crc-0.3.1.1 (平成28年11月10日 木曜日)
|
6
54
|
|
7
55
|
* rbcrc において reflect-input/output が既定値となっていなかったため修正
|
data/README.md
CHANGED
@@ -1,28 +1,31 @@
|
|
1
1
|
|
2
|
-
# crc - CRC
|
2
|
+
# crc - CRC calcurator for ruby
|
3
3
|
|
4
|
-
This is a general CRC (Cyclic Redundancy Check)
|
4
|
+
This is a general CRC (Cyclic Redundancy Check) calcurator for ruby.
|
5
5
|
|
6
6
|
It is written by pure ruby with based on slice-by-eight algorithm (slice-by-16 algorithm with byte-order free).
|
7
7
|
|
8
|
-
Included built-in CRC modules are CRC-32, CRC-
|
8
|
+
Included built-in CRC modules are CRC-32, CRC-32C, CRC-64-XZ, CRC-16, CRC-8-MAXIM, CRC-5-USB and many more.
|
9
9
|
|
10
10
|
Customization is posible for 1 to 64 bit width, any polynomials, and with/without bit reflection input/output.
|
11
11
|
|
12
12
|
This library is slower than ×85+ of zlib/crc32, and slower than ×120+ of extlzma/crc32 on FreeBSD 10.3R amd64.
|
13
13
|
|
14
|
-
If you need more speed, please use [crc-turbo](https://rubygems/gems/crc-turbo).
|
14
|
+
If you need more speed, please use with [crc-turbo](https://rubygems/gems/crc-turbo).
|
15
15
|
|
16
16
|
|
17
17
|
## Summary
|
18
18
|
|
19
19
|
* package name: crc
|
20
|
-
* author: dearblue (mailto:dearblue@users.
|
21
|
-
* report issue to: <https://
|
20
|
+
* author: dearblue (mailto:dearblue@users.noreply.github.com)
|
21
|
+
* report issue to: <https://github.com/dearblue/ruby-crc/issues>
|
22
22
|
* how to install: ``gem install crc``
|
23
|
-
* version: 0.
|
24
|
-
*
|
25
|
-
* licensing:
|
23
|
+
* version: 0.4
|
24
|
+
* production quality: TECHNICAL PREVIEW
|
25
|
+
* licensing:
|
26
|
+
* ***BSD-2-Clause : MAIN LICENSE***
|
27
|
+
* zlib-style License : ``lib/crc/_combine.rb``
|
28
|
+
* Creative Commons License Zero (CC0 / Public Domain) : ``lib/crc/_byruby.rb``, ``lib/crc/_modules.rb``
|
26
29
|
* dependency gems: none
|
27
30
|
* dependency external C libraries: none
|
28
31
|
* bundled external C libraries: none
|
@@ -34,83 +37,85 @@ If you need more speed, please use [crc-turbo](https://rubygems/gems/crc-turbo).
|
|
34
37
|
|
35
38
|
This examples are used CRC-32 module. Please see CRC for more details.
|
36
39
|
|
37
|
-
|
40
|
+
### Calcurate by direct
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
* ``CRC.crc32.new(seq, init = 0, current_length = 0) -> crc-32 generator``
|
42
|
+
* ``CRC.crc32(seq, init = CRC::CRC32.initial_crc) => crc-32 integer`` (likely as ``Zlib.crc32``)
|
43
|
+
* ``CRC.crc32.crc(seq, init = CRC::CRC32.initial_crc) => crc-32 integer`` (likely as ``Zlib.crc32``)
|
44
|
+
* ``CRC.crc32.digest(seq, init = CRC::CRC32.initial_crc) => crc-32 digest`` (likely as ``Digest::XXXX.digest``)
|
45
|
+
* ``CRC.crc32.hexdigest(seq, init = 0) -> crc-32 hex-digest`` (likely as ``Digest::XXXX.hexdigest``)
|
46
|
+
* ``CRC.crc32[seq, init = 0, current_length = 0] -> crc-32 calcurator``
|
45
47
|
|
46
|
-
|
48
|
+
### Calcurate by streaming
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
* ``CRC::CRC32#hexdigest => crc-32 hex-digest`` (likely as ``Digest::XXXX.hexdigest``)
|
50
|
+
* ``CRC.crc32.new(init = 0, current_length = 0) => crc-32 calcurator``
|
51
|
+
* ``CRC::CRC32#update(seq) => self`` (likely as ``Digest::XXXX.update``)
|
52
|
+
* ``CRC::CRC32#finish => crc-32 integer`` (likely as ``Digest::XXXX.finish``)
|
53
|
+
* ``CRC::CRC32#crc => crc-32 integer`` (same as ``CRC::CRC32#finish``)
|
54
|
+
* ``CRC::CRC32#digest => crc-32 digest`` (likely as ``Digest::XXXX.digest``)
|
55
|
+
* ``CRC::CRC32#hexdigest => crc-32 hex-digest`` (likely as ``Digest::XXXX.hexdigest``)
|
55
56
|
|
56
|
-
|
57
|
+
Example ::
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
59
|
+
``` ruby:ruby
|
60
|
+
x = CRC.crc32.new # => #<CRC::CRC32:00000000>
|
61
|
+
x.update "123" # => #<CRC::CRC32:884863D2>
|
62
|
+
x.update "456789" # => #<CRC::CRC32:CBF43926>
|
63
|
+
x.crc # => 3421780262
|
64
|
+
x.digest # => "\xCB\xF49&"
|
65
|
+
x.hexdigest # => "CBF43926"
|
66
|
+
```
|
66
67
|
|
67
|
-
|
68
|
+
### Combine
|
68
69
|
|
69
|
-
|
70
|
-
|
70
|
+
* ``CRC.combine(crc1, crc2, len2) => combined crc integer`` (likely as ``Zlib.crc32_comibne``)
|
71
|
+
* ``CRC#+(right_crc) => combined crc calcurator``
|
71
72
|
|
72
|
-
|
73
|
+
Example-1 ::
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
75
|
+
``` ruby:ruby
|
76
|
+
CRC.crc32.combine(CRC.crc32("123"), CRC.crc32("456789"), 6) # => 3421780262
|
77
|
+
```
|
77
78
|
|
78
|
-
|
79
|
+
Example-2 ::
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
``` ruby:ruby
|
82
|
+
CRC.crc32["123"] + CRC.crc32["456"] + CRC.crc32["789"] # => #<CRC::CRC32:CBF43926>
|
83
|
+
```
|
83
84
|
|
84
|
-
|
85
|
+
### Create customized crc module
|
85
86
|
|
86
|
-
|
87
|
+
* ``CRC.new(bitsize, poly, initial_crc = 0, refin = true, refout = true, xor_output = ~0) => new crc module class``
|
87
88
|
|
88
|
-
|
89
|
-
MyCRC32 = CRC.new(32, 0x04C11DB7)
|
90
|
-
MyCRC32.class # => Class
|
91
|
-
MyCRC32.hexdigest("123456789") # => "CBF43926"
|
92
|
-
MyCRC32.new("123456789") # => #<MyCRC32:CBF43926>
|
93
|
-
```
|
89
|
+
Example ::
|
94
90
|
|
95
|
-
|
91
|
+
``` ruby:ruby
|
92
|
+
MyCRC32 = CRC.new(32, 0x04C11DB7)
|
93
|
+
MyCRC32.class # => Class
|
94
|
+
MyCRC32.hexdigest("123456789") # => "CBF43926"
|
95
|
+
MyCRC32["123456789"] # => #<MyCRC32:CBF43926>
|
96
|
+
```
|
96
97
|
|
97
|
-
|
98
|
+
### Calcurate arc-crc
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
* ``CRC::XXX.acrc(pre, post = nil, want_crc = 0) => arc-crc byte string``
|
101
|
+
|
102
|
+
Example ::
|
103
|
+
|
104
|
+
``` ruby:ruby
|
105
|
+
a = "12"
|
106
|
+
c = "789"
|
107
|
+
wantcrc = CRC.crc32("123456789")
|
108
|
+
b = CRC.crc32.acrc(a, c, wantcrc) # => "3456"
|
109
|
+
CRC.crc32[a + b + c] # => #<CRC::CRC32:CBF43926>
|
110
|
+
```
|
106
111
|
|
107
|
-
|
112
|
+
See CRC::Calcurate.acrc or below for more detail.
|
108
113
|
|
109
114
|
|
110
115
|
## Built-in CRC modules
|
111
116
|
|
112
|
-
```
|
113
|
-
$
|
117
|
+
```
|
118
|
+
$ rbcrc -lq
|
114
119
|
```
|
115
120
|
|
116
121
|
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-ROHC, CRC-7-UMTS, 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, CRC-16, 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-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-CDMA, CRC-31-PHILIPS, CRC-32, CRC-32-BZIP2, CRC-32C, CRC-32D, CRC-32-MPEG-2, CRC-32-POSIX, CRC-32Q, CRC-32-JAMCRC, CRC-32-XFER, CRC-40-GSM, CRC-64-XZ, CRC-64-JONES, CRC-64-ECMA, CRC-64-WE, CRC-64-ISO
|
@@ -138,11 +143,11 @@ Algorithm is slicing-by-16 only for ruby and javascript.
|
|
138
143
|
For C, be able choose into bit-by-bit, bit-by-bit-fast, halfbyte-table,
|
139
144
|
standard-table, slicing-by-4, slicing-by-8, and slicing-by-16.
|
140
145
|
|
141
|
-
```
|
146
|
+
```
|
142
147
|
$ rbcrc --help
|
143
148
|
usage: rbcrc [options] output-filename...
|
144
|
-
-
|
145
|
-
-
|
149
|
+
-m crcname choose included crc name in library (``-l'' to print list)
|
150
|
+
-n crcname declare function name or class name [DEFAULT is filename]
|
146
151
|
-s bitsize declare crc bit size [REQUIRED for customized crc]
|
147
152
|
-p polynom declare crc polynomial [REQUIRED for customized crc]
|
148
153
|
-c initcrc declare initial crc (not internal state) [DEFAULT: 0]
|
@@ -175,33 +180,53 @@ Support export file types:
|
|
175
180
|
(executable for mruby and limitation bitsize by fixnum)
|
176
181
|
|
177
182
|
examples:
|
178
|
-
* create crc-32
|
183
|
+
* create crc-32 calcurator to c source (and header file)
|
179
184
|
$ rbcrc crc32.c
|
180
185
|
|
181
|
-
* create crc-32c
|
186
|
+
* create crc-32c calcurator to ruby source
|
182
187
|
$ rbcrc crc32c.rb
|
183
188
|
|
184
|
-
* create crc-30-cdma
|
189
|
+
* create crc-30-cdma calcurator to javascript source
|
185
190
|
$ rbcrc crc30cdma.js
|
186
191
|
|
187
|
-
* create crc-32
|
188
|
-
$ rbcrc -
|
192
|
+
* create crc-32 calcurator to ``crc.c'', ``crc.rb'' and ``crc.js''
|
193
|
+
$ rbcrc -mcrc32 crc.c crc.rb crc.js
|
189
194
|
|
190
|
-
* create customized crc
|
191
|
-
$ rbcrc -s15 -p0x6789 -io -
|
195
|
+
* create customized crc calcurator (as mycrc function) to ``mycrc.c''
|
196
|
+
$ rbcrc -s15 -p0x6789 -io -x~0 mycrc.c
|
192
197
|
|
193
|
-
* create customized crc
|
194
|
-
$ rbcrc -s39 -p0x987654321 -IO -
|
198
|
+
* create customized crc calcurator (as MyCRC class) to ``mycrc_1.rb''
|
199
|
+
$ rbcrc -s39 -p0x987654321 -IO -x1 -nMyCRC mycrc_1.rb
|
195
200
|
```
|
196
201
|
|
202
|
+
- - - -
|
203
|
+
|
204
|
+
And, this command has feature too that is print for each CRC specifications as YAML format.
|
205
|
+
|
206
|
+
``` text
|
207
|
+
$ rbcrc -lvv
|
208
|
+
...snip...
|
209
|
+
"CRC-32":
|
210
|
+
bitsize: 32
|
211
|
+
polynomial: 0x04C11DB7
|
212
|
+
reflect input: true
|
213
|
+
reflect output: true
|
214
|
+
initial crc: 0x00000000
|
215
|
+
xor output: 0xFFFFFFFF
|
216
|
+
magic number: 0x2144DF1C
|
217
|
+
another names:
|
218
|
+
- "CRC-32-ADCCP"
|
219
|
+
- "CRC-32-PKZIP"
|
220
|
+
- "PKZIP"
|
221
|
+
...snip...
|
222
|
+
```
|
197
223
|
|
198
|
-
## arc-crc (***EXPERIMENTAL***)
|
199
224
|
|
200
|
-
|
225
|
+
## arc-crc
|
201
226
|
|
202
|
-
|
227
|
+
(Written in japanese from here)
|
203
228
|
|
204
|
-
|
229
|
+
crc-0.4 にて、任意の CRC となるバイト列を逆算する機能が正式に追加されました。
|
205
230
|
|
206
231
|
``require "crc/acrc"`` にて、その機能が利用可能となります。
|
207
232
|
|
data/bin/rbcrc
CHANGED
@@ -27,7 +27,7 @@ forceoverwrite = false
|
|
27
27
|
verbose = 1
|
28
28
|
|
29
29
|
OptionParser.new("usage: #{File.basename $0} [options] output-filename...", 12, " ").instance_eval do
|
30
|
-
on("-
|
30
|
+
on("-m crcname", "choose included crc name in library (``-l'' to print list)") do |x|
|
31
31
|
begin
|
32
32
|
crc = CRC.lookup(x)
|
33
33
|
rescue
|
@@ -35,7 +35,7 @@ OptionParser.new("usage: #{File.basename $0} [options] output-filename...", 12,
|
|
35
35
|
"not matched crc name - #{x.strip} (if check name, use ``-l'' switch)"
|
36
36
|
end
|
37
37
|
end
|
38
|
-
on("-
|
38
|
+
on("-n crcname", "declare function name or class name [DEFAULT is filename]") { |x| crcname = x.strip }
|
39
39
|
on("-s bitsize", "declare crc bit size [REQUIRED for customized crc]") do |x|
|
40
40
|
bitsize = x.to_i
|
41
41
|
unless bitsize >= 1 && bitsize <= 64
|
@@ -116,13 +116,13 @@ examples:
|
|
116
116
|
$ rbcrc crc30cdma.js
|
117
117
|
|
118
118
|
* create crc-32 generator to ``crc.c'', ``crc.rb'' and ``crc.js''
|
119
|
-
$ rbcrc -
|
119
|
+
$ rbcrc -mcrc32 crc.c crc.rb crc.js
|
120
120
|
|
121
121
|
* create customized crc generator (as mycrc function) to ``mycrc.c''
|
122
|
-
$ rbcrc -s15 -p0x6789 -io -
|
122
|
+
$ rbcrc -s15 -p0x6789 -io -x~0 mycrc.c
|
123
123
|
|
124
124
|
* create customized crc generator (as MyCRC class) to ``mycrc_1.rb''
|
125
|
-
$ rbcrc -s39 -p0x987654321 -IO -
|
125
|
+
$ rbcrc -s39 -p0x987654321 -IO -x1 -nMyCRC mycrc_1.rb
|
126
126
|
EOS
|
127
127
|
|
128
128
|
begin
|
@@ -183,7 +183,9 @@ begin
|
|
183
183
|
case mode
|
184
184
|
when :list
|
185
185
|
case verbose
|
186
|
-
when 0
|
186
|
+
when 0
|
187
|
+
puts CRC::LIST.map {|e| e[7] }.join(", ")
|
188
|
+
when 1
|
187
189
|
puts CRC::LIST.map {|e| e[7 .. -1] }.join(", ")
|
188
190
|
when 2
|
189
191
|
puts CRC::LIST.map {|e| e[7 .. -1].join(", ") }.join("\n")
|
@@ -210,7 +212,8 @@ begin
|
|
210
212
|
reflect input: #{e[2].inspect}
|
211
213
|
reflect output: #{e[3].inspect}
|
212
214
|
initial crc: #{hex[e[4]]}
|
213
|
-
xor output: #{hex[e[5]]}
|
215
|
+
xor output: #{hex[e[5]]}
|
216
|
+
magic number: #{hex[CRC[e[7]].magicnumber]}#{names}
|
214
217
|
YAML_FORMAT
|
215
218
|
end
|
216
219
|
end
|
data/gemstub.rb
CHANGED
@@ -9,19 +9,19 @@ ver = $1
|
|
9
9
|
GEMSTUB = Gem::Specification.new do |s|
|
10
10
|
s.name = "crc"
|
11
11
|
s.version = ver
|
12
|
-
s.summary = "general CRC
|
12
|
+
s.summary = "general CRC calcurator"
|
13
13
|
s.description = <<EOS
|
14
|
-
Pure ruby implemented general CRC (Cyclic Redundancy Check)
|
14
|
+
Pure ruby implemented general CRC (Cyclic Redundancy Check) calcurator.
|
15
15
|
Customization is posible for 1 to 64 bit width, any polynomials, and with/without bit reflection input/output.
|
16
16
|
If you need more speed, please use crc-turbo.
|
17
17
|
EOS
|
18
|
-
s.homepage = "https://
|
18
|
+
s.homepage = "https://github.com/dearblue/ruby-crc-turbo"
|
19
19
|
s.licenses = ["BSD-2-Clause", "Zlib", "CC0-1.0"]
|
20
20
|
s.author = "dearblue"
|
21
|
-
s.email = "dearblue@users.
|
21
|
+
s.email = "dearblue@users.noreply.github.com"
|
22
22
|
|
23
|
-
s.required_ruby_version = ">= 2.
|
24
|
-
s.add_development_dependency "rake"
|
23
|
+
s.required_ruby_version = ">= 2.2"
|
24
|
+
s.add_development_dependency "rake"
|
25
25
|
end
|
26
26
|
|
27
27
|
verfile = "lib/crc/version.rb"
|
data/lib/crc.rb
CHANGED
@@ -5,9 +5,10 @@ if ENV["RUBY_CRC_NOFAST"].to_i > 0
|
|
5
5
|
CRC::IMPLEMENT = :ruby
|
6
6
|
else
|
7
7
|
begin
|
8
|
+
gem "crc-turbo", "~> 0.4.A"
|
8
9
|
require File.join("crc", RUBY_VERSION[/\d+\.\d+/], "_turbo.so")
|
9
10
|
CRC::IMPLEMENT = :turbo
|
10
|
-
rescue LoadError
|
11
|
+
rescue LoadError, Gem::MissingSpecVersionError
|
11
12
|
require_relative "crc/_byruby"
|
12
13
|
CRC::IMPLEMENT = :ruby
|
13
14
|
end
|
@@ -16,15 +17,15 @@ end
|
|
16
17
|
require_relative "crc/version"
|
17
18
|
|
18
19
|
#
|
19
|
-
# This is a general CRC
|
20
|
+
# This is a general CRC calcurator.
|
20
21
|
#
|
21
22
|
# When you want to use CRC-32 module, there are following ways:
|
22
23
|
#
|
23
|
-
# 1.
|
24
|
+
# 1. Calcurate CRC-32'd value at direct:
|
24
25
|
#
|
25
26
|
# CRC.crc32("123456789") # => 3421780262
|
26
27
|
#
|
27
|
-
# 2.
|
28
|
+
# 2. Calcurate CRC-32'd hex-digest at direct:
|
28
29
|
#
|
29
30
|
# CRC::CRC32.hexdigest("123456789") # => "CBF43926"
|
30
31
|
#
|
@@ -44,169 +45,31 @@ class CRC
|
|
44
45
|
|
45
46
|
extend Utils
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
module Utils
|
51
|
-
extend self
|
52
|
-
|
53
|
-
def bitreflect_reference(num, bitsize)
|
54
|
-
n = 0
|
55
|
-
bitsize.times { n <<= 1; n |= (num & 0x01); num >>= 1 }
|
56
|
-
n
|
57
|
-
end
|
58
|
-
|
59
|
-
def bitreflect(num, bitsize)
|
60
|
-
case
|
61
|
-
when bitsize > 128
|
62
|
-
bitreflect_reference(num, bitsize)
|
63
|
-
when bitsize > 64
|
64
|
-
bitreflect128(num) >> (128 - bitsize)
|
65
|
-
when bitsize > 32
|
66
|
-
bitreflect64(num) >> (64 - bitsize)
|
67
|
-
when bitsize > 16
|
68
|
-
bitreflect32(num) >> (32 - bitsize)
|
69
|
-
when bitsize > 8
|
70
|
-
bitreflect16(num) >> (16 - bitsize)
|
71
|
-
else
|
72
|
-
bitreflect8(num) >> (8 - bitsize)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def build_table(bitsize, polynomial, unfreeze = false, slice: 16)
|
77
|
-
bitmask = ~(~0 << bitsize)
|
78
|
-
table = []
|
79
|
-
Aux.slide_to_head(bitsize, 0, bitmask & polynomial, bitmask) do |xx, poly, csh, head, carries, pad|
|
80
|
-
table << (t = [])
|
81
|
-
256.times do |b|
|
82
|
-
b <<= csh
|
83
|
-
8.times { b = (b[head] == 0) ? (b << 1) : (((carries & b) << 1) ^ poly) }
|
84
|
-
t << b
|
85
|
-
end
|
86
|
-
t.freeze unless unfreeze
|
87
|
-
|
88
|
-
carries8 = carries >> 7
|
89
|
-
(1...slice).step do
|
90
|
-
tt = table[-1]
|
91
|
-
table << (t = [])
|
92
|
-
256.times do |b|
|
93
|
-
t << (table[0][tt[b] >> csh] ^ ((carries8 & tt[b]) << 8))
|
94
|
-
end
|
95
|
-
t.freeze unless unfreeze
|
96
|
-
end
|
97
|
-
0
|
98
|
-
end
|
99
|
-
table.freeze unless unfreeze
|
100
|
-
table
|
101
|
-
end
|
102
|
-
|
103
|
-
def build_reflect_table(bitsize, polynomial, unfreeze = false, slice: 16)
|
104
|
-
polynomial = bitreflect(polynomial, bitsize)
|
105
|
-
table = []
|
106
|
-
|
107
|
-
table << (t = [])
|
108
|
-
256.times do |b|
|
109
|
-
8.times { b = (b[0] == 0) ? (b >> 1) : ((b >> 1) ^ polynomial) }
|
110
|
-
t << b
|
111
|
-
end
|
112
|
-
t.freeze unless unfreeze
|
113
|
-
|
114
|
-
(1...slice).step do
|
115
|
-
tt = table[-1]
|
116
|
-
table << (t = [])
|
117
|
-
256.times do |b|
|
118
|
-
t << (table[0][tt[b] & 0xff] ^ (tt[b] >> 8))
|
119
|
-
end
|
120
|
-
t.freeze unless unfreeze
|
121
|
-
end
|
122
|
-
|
123
|
-
table.freeze unless unfreeze
|
124
|
-
table
|
125
|
-
end
|
126
|
-
|
127
|
-
def export_table(table, bitsize, linewidth, indentsize = 2)
|
128
|
-
bitsize0 = bitsize.to_i
|
129
|
-
indent = " " * indentsize.to_i
|
130
|
-
case
|
131
|
-
when bitsize0 > 64 || bitsize0 < 1
|
132
|
-
raise "invalid bitsize (expected to 1..64, but given #{bitsize})"
|
133
|
-
when bitsize0 > 32
|
134
|
-
packformat = "Q>"
|
135
|
-
hexwidth = 16
|
136
|
-
when bitsize0 > 16
|
137
|
-
packformat = "N"
|
138
|
-
hexwidth = 8
|
139
|
-
when bitsize0 > 8
|
140
|
-
packformat = "n"
|
141
|
-
hexwidth = 4
|
142
|
-
else # when bitsize0 > 0
|
143
|
-
packformat = "C"
|
144
|
-
hexwidth = 2
|
145
|
-
end
|
146
|
-
table = table.to_a.pack("#{packformat}*").unpack("H*")[0]
|
147
|
-
table.gsub!(/(?<=\w)(?=\w{#{hexwidth}}{#{linewidth}}+$)/, "\n")
|
148
|
-
table.gsub!(/(?<=\w)(?=\w{#{hexwidth}}+$)/, " ")
|
149
|
-
table.gsub!(/(?<=\w)(?=\s|$)/, ",")
|
150
|
-
table.gsub!(/(?:(?<=^)|(?<=\s))(?=\w)/, "0x")
|
151
|
-
table.gsub!(/^/, "#{indent} ")
|
152
|
-
<<-EOS
|
153
|
-
#{indent}TABLE = [
|
154
|
-
#{table}
|
155
|
-
#{indent}].freeze
|
156
|
-
EOS
|
157
|
-
end
|
158
|
-
end
|
48
|
+
require_relative "crc/_extensions"
|
49
|
+
require_relative "crc/_utils"
|
50
|
+
require_relative "crc/_aux"
|
159
51
|
|
160
|
-
|
161
|
-
|
162
|
-
#
|
163
|
-
# Internal using module.
|
164
|
-
#
|
165
|
-
module Aux
|
166
|
-
def self.DIGEST(num, bitsize)
|
167
|
-
bits = (bitsize + 7) / 8 * 8
|
168
|
-
seq = ""
|
169
|
-
(bits - 8).step(0, -8) { |i| seq << yield((num >> i) & 0xff) }
|
170
|
-
seq
|
171
|
-
end
|
52
|
+
using Extensions
|
172
53
|
|
173
|
-
|
174
|
-
|
54
|
+
module Calcurator
|
55
|
+
def [](seq, *args)
|
56
|
+
c = new(*args)
|
57
|
+
c.update(seq) if seq
|
58
|
+
c
|
175
59
|
end
|
176
60
|
|
177
|
-
def self.hexdigest(num, bitsize)
|
178
|
-
DIGEST(num, bitsize) { |n| "%02X" % n }
|
179
|
-
end
|
180
|
-
|
181
|
-
#
|
182
|
-
# call-seq:
|
183
|
-
# slide_to_head(bitsize, state, polynomial, bitmask) { |padded_state, padded_polynomial, shift_input, off_msb, carries_mask, padding_size| padded_new_state } -> new_state
|
184
|
-
#
|
185
|
-
# YIELD(padded_state, padded_polynomial, shift_input, off_msb, carries_mask, padding_size) -> padded_new_state
|
186
|
-
#
|
187
|
-
def self.slide_to_head(bitsize, state, polynomial, bitmask)
|
188
|
-
pad = bitsize & 0x07
|
189
|
-
if pad == 0
|
190
|
-
yield(state, polynomial, bitsize - 8, bitsize - 1, bitmask >> 1, 0)
|
191
|
-
else
|
192
|
-
pad = 8 - pad
|
193
|
-
yield(state << pad, polynomial << pad, bitsize - 8 + pad, bitsize - 1 + pad, (bitmask << pad >> 1) | 0x7f, pad) >> pad
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
module ModuleClass
|
199
61
|
def setup(crc = nil)
|
200
62
|
crc ||= initial_crc
|
63
|
+
crc ^= xor_output
|
201
64
|
crc = CRC.bitreflect(crc, bitsize) if reflect_input? ^ reflect_output?
|
202
|
-
crc
|
65
|
+
crc & bitmask
|
203
66
|
end
|
204
67
|
|
205
68
|
alias init setup
|
206
69
|
|
207
70
|
def finish(state)
|
208
71
|
state = CRC.bitreflect(state, bitsize) if reflect_input? ^ reflect_output?
|
209
|
-
state ^ xor_output
|
72
|
+
state ^ xor_output & bitmask
|
210
73
|
end
|
211
74
|
|
212
75
|
def crc(seq, crc = nil)
|
@@ -222,24 +85,7 @@ class CRC
|
|
222
85
|
end
|
223
86
|
|
224
87
|
def variant?(obj)
|
225
|
-
|
226
|
-
when obj.kind_of?(CRC)
|
227
|
-
mod = obj.class
|
228
|
-
when obj.kind_of?(Class) && obj < CRC
|
229
|
-
mod = obj
|
230
|
-
else
|
231
|
-
return false
|
232
|
-
end
|
233
|
-
|
234
|
-
if bitsize == mod.bitsize &&
|
235
|
-
polynomial == mod.polynomial &&
|
236
|
-
reflect_input? == mod.reflect_input? &&
|
237
|
-
reflect_output? == mod.reflect_output? &&
|
238
|
-
xor_output == mod.xor_output
|
239
|
-
true
|
240
|
-
else
|
241
|
-
false
|
242
|
-
end
|
88
|
+
obj.variant_for?(self)
|
243
89
|
end
|
244
90
|
|
245
91
|
#
|
@@ -309,26 +155,22 @@ class CRC
|
|
309
155
|
#
|
310
156
|
# call-seq:
|
311
157
|
# initialize(initial_crc = nil, size = 0)
|
312
|
-
# initialize(seq, initial_crc = nil, size = 0)
|
313
158
|
#
|
314
|
-
def initialize(
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
@size = size.to_i
|
319
|
-
update(seq) if seq
|
320
|
-
end
|
159
|
+
def initialize(initial_crc = nil, size = 0)
|
160
|
+
m = get_crc_module
|
161
|
+
@state = m.setup((initial_crc || m.initial_crc).to_i)
|
162
|
+
@size = size.to_i
|
321
163
|
end
|
322
164
|
|
323
165
|
def reset(initial_crc = nil, size = 0)
|
324
|
-
m =
|
166
|
+
m = get_crc_module
|
325
167
|
@state = m.setup((initial_crc || m.initial_crc).to_i)
|
326
168
|
@size = size.to_i
|
327
169
|
self
|
328
170
|
end
|
329
171
|
|
330
172
|
def update(seq)
|
331
|
-
@state =
|
173
|
+
@state = get_crc_module.update(seq, state)
|
332
174
|
@size += seq.bytesize
|
333
175
|
self
|
334
176
|
end
|
@@ -336,19 +178,14 @@ class CRC
|
|
336
178
|
alias << update
|
337
179
|
|
338
180
|
def crc
|
339
|
-
|
181
|
+
get_crc_module.finish(state)
|
340
182
|
end
|
341
183
|
|
342
184
|
def +(crc2)
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
unless
|
347
|
-
m1.polynomial == m2.polynomial &&
|
348
|
-
m1.reflect_input? == m2.reflect_input? &&
|
349
|
-
m1.reflect_output? == m2.reflect_output? &&
|
350
|
-
# m1.initial_crc == m2.initial_crc &&
|
351
|
-
m1.xor_output == m2.xor_output
|
185
|
+
m1 = get_crc_module
|
186
|
+
m2 = crc2.get_crc_module
|
187
|
+
raise ArgumentError, "not a CRC instance (#{crc2.inspect})" unless m2
|
188
|
+
unless m2.variant_for?(m1)
|
352
189
|
raise ArgumentError, "different CRC module (#{m1.inspect} and #{m2.inspect})"
|
353
190
|
end
|
354
191
|
m1.new(m1.combine(crc, crc2.crc, crc2.size), size + crc2.size)
|
@@ -357,15 +194,7 @@ class CRC
|
|
357
194
|
def ==(a)
|
358
195
|
case a
|
359
196
|
when CRC
|
360
|
-
|
361
|
-
m2 = a.class
|
362
|
-
if m1.bitsize == m2.bitsize &&
|
363
|
-
m1.polynomial == m2.polynomial &&
|
364
|
-
m1.reflect_input? == m2.reflect_input? &&
|
365
|
-
m1.reflect_output? == m2.reflect_output? &&
|
366
|
-
# m1.initial_crc == m2.initial_crc &&
|
367
|
-
m1.xor_output == m2.xor_output &&
|
368
|
-
state == a.state
|
197
|
+
if variant_for?(a) && state == a.state
|
369
198
|
true
|
370
199
|
else
|
371
200
|
false
|
@@ -385,58 +214,34 @@ class CRC
|
|
385
214
|
end
|
386
215
|
|
387
216
|
def digest
|
388
|
-
Aux.digest(crc,
|
217
|
+
Aux.digest(crc, get_crc_module.bitsize)
|
389
218
|
end
|
390
219
|
|
391
220
|
# return digest as internal state
|
392
221
|
def digest!
|
393
|
-
Aux.digest(state,
|
222
|
+
Aux.digest(state, get_crc_module.bitsize)
|
394
223
|
end
|
395
224
|
|
396
225
|
def hexdigest
|
397
|
-
Aux.hexdigest(crc,
|
226
|
+
Aux.hexdigest(crc, get_crc_module.bitsize)
|
398
227
|
end
|
399
228
|
|
400
229
|
# return hex-digest as internal state
|
401
230
|
def hexdigest!
|
402
|
-
Aux.hexdigest(state,
|
231
|
+
Aux.hexdigest(state, get_crc_module.bitsize)
|
403
232
|
end
|
404
233
|
|
405
234
|
alias to_str hexdigest
|
406
235
|
alias to_s hexdigest
|
407
236
|
|
408
237
|
def inspect
|
409
|
-
"\#<#{
|
238
|
+
"\#<#{get_crc_module}:#{hexdigest}>"
|
410
239
|
end
|
411
240
|
|
412
241
|
def pretty_inspect(q)
|
413
242
|
q.text inspect
|
414
243
|
end
|
415
244
|
|
416
|
-
private
|
417
|
-
def initialize_args(args)
|
418
|
-
case args.size
|
419
|
-
when 0
|
420
|
-
yield nil, nil, 0
|
421
|
-
when 1
|
422
|
-
if args[0].kind_of?(String)
|
423
|
-
yield args[0], nil, 0
|
424
|
-
else
|
425
|
-
yield nil, args[0], 0
|
426
|
-
end
|
427
|
-
when 2
|
428
|
-
if args[0].kind_of?(String)
|
429
|
-
yield args[0], args[1], 0
|
430
|
-
else
|
431
|
-
yield nil, args[0], args[1].to_i
|
432
|
-
end
|
433
|
-
when 3
|
434
|
-
yield args[0], args[1], args[2].to_i
|
435
|
-
else
|
436
|
-
raise ArgumentError, "wrong argument size (given #{args.size}, expect 0..3)"
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
245
|
MODULE_TABLE = {}
|
441
246
|
|
442
247
|
class << self
|
@@ -463,6 +268,9 @@ class CRC
|
|
463
268
|
|
464
269
|
require_relative "crc/_modules"
|
465
270
|
require_relative "crc/_combine"
|
271
|
+
require_relative "crc/_shift"
|
272
|
+
require_relative "crc/_magic"
|
273
|
+
require_relative "crc/_file"
|
466
274
|
|
467
275
|
#
|
468
276
|
# Create CRC module classes.
|
@@ -477,7 +285,7 @@ class CRC
|
|
477
285
|
names.each do |nm|
|
478
286
|
nm1 = nm.downcase.gsub(/[\W_]+/, "")
|
479
287
|
if MODULE_TABLE.key?(nm1)
|
480
|
-
raise NameError, "collision crc-module name: #{nm} (#{crc
|
288
|
+
raise NameError, "collision crc-module name: #{nm} ({#{crc.to_str}} and {#{MODULE_TABLE[nm1].to_str}})"
|
481
289
|
end
|
482
290
|
MODULE_TABLE[nm1] = crc
|
483
291
|
|
@@ -497,34 +305,4 @@ class CRC
|
|
497
305
|
check = Integer(check.to_i) if check
|
498
306
|
crc.const_set :CHECK, check
|
499
307
|
end
|
500
|
-
|
501
|
-
if $0 == __FILE__
|
502
|
-
$stderr.puts "#{__FILE__}:#{__LINE__}: SELF CHECK for CRC modules (#{File.basename($".grep(/_(?:byruby|turbo)/)[0]||"")})\n"
|
503
|
-
MODULE_TABLE.values.uniq.each do |crc|
|
504
|
-
check = crc::CHECK
|
505
|
-
checked = crc.crc("123456789")
|
506
|
-
case check
|
507
|
-
when nil
|
508
|
-
$stderr.puts "| %20s(\"123456789\" * 1) = %16X (check only)\n" % [crc.name, checked]
|
509
|
-
when checked
|
510
|
-
;
|
511
|
-
else
|
512
|
-
$stderr.puts "| %20s(\"123456789\" * 1) = %16X (expect to %X)\n" % [crc.name, checked, check]
|
513
|
-
end
|
514
|
-
|
515
|
-
check = 9.times.reduce(crc.new) { |a, x| a + crc[crc::CHECK, 9] }
|
516
|
-
checked = crc["123456789" * 9]
|
517
|
-
case check
|
518
|
-
when nil
|
519
|
-
$stderr.puts "| %20s(\"123456789\" * 9) = %16X (check only)\n" % [crc.name, checked]
|
520
|
-
when checked
|
521
|
-
;
|
522
|
-
else
|
523
|
-
$stderr.puts "| %20s(\"123456789\" * 9) = %16X (expect to %X)\n" % [crc.name, checked, check]
|
524
|
-
end
|
525
|
-
end
|
526
|
-
$stderr.puts "#{__FILE__}:#{__LINE__}: DONE SELF CHECK\n"
|
527
|
-
|
528
|
-
exit
|
529
|
-
end
|
530
308
|
end
|