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
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
|