View in color | View documentation | License |
Download script | History | Other scripts by: vincentecuye |
18-Mar 7:29 UTC
[0.056] 19.454k
[0.056] 19.454k
crc32.rREBOL [
Title: "CRC-32"
Date: 30-Jan-2013
Version: 1.2.0
Type: module
File: %crc32.r
Exports: [crc-32]
Author: "Vincent Ecuyer"
Purpose: "CRC32 checksum function"
Usage: {
Calculates a 32 bits cyclic redundancy code as used
in gzip/pkzip/etc.
Returns a binary:
>> crc-32 "a string"
== #{99A255DA}
>> crc-32 #{112233445566}
== #{345913D6}
or an integer:
>> crc-32/integer "a string"
== -1717414438
To compute the checksum part by part:
>> crc-32 "a str"
== #{61AD7C35}
>> crc-32/continue "ing" #{61AD7C35}
== #{99A255DA}
>> crc-32/continue data none
is a synonym of:
>> crc-32 data
Usage of /continue in a loop:
; initial crc
crc: none
until [
...
; a new crc is computed from the previous one and the new data
crc: crc-32/continue data-part crc
...
]
; at the end of this loop, 'crc holds the crc-32 of the whole data
The /direct mode, with a specified buffer size,
works directly on files (useful for big files):
; calculates the checksum of a remote file with a 64 kb buffer
>> crc-32/direct ftp://192.168.1.33/rebol.exe 64 * 1024
== #{67AD9CF6}
Note: In the case of a file access error, connection timeout, or an
execution halted by the user, the opened file can still be locked.
Any new invocation of 'crc-32 will release (close) the file and clear
the internal buffer. Example:
>> crc-32 ""
}
Comment: {
Contains a precalculated table for speedup.
REBOL VM isn't really suited for fast bitwise operations, so this
code is quite slow. If the rebcode VM is available, it's used to
achieve a more usable speed (between checksum/method 'md5 and
checksum/method 'sha1).
}
Library: [
level: 'advanced
platform: 'all
type: [module function rebcode]
domain: [math security]
tested-under: [
core 2.101.0.2.5 on [Macintosh osx-x86]
view 2.7.8.2.5 on [Macintosh osx-x86]
core 2.6.2.3.1 on [Win2K]
view 1.3.2.3.1 on [Win2K]
view 1.3.61.3.1 on [Win2K]
base 2.5.4.3.1 on [Win2K]
view 1.2.1.1.1 on [AmigaOS30]
core 2.5.0.1.1 on [AmigaOS30]
]
support: none
license: 'bsd
see-also: %rebzip.r
]
History: [
1.2.0 30-Jan-2013
"r3 compatibility and module declaration"
1.1.0 6-Apr-2006
"/direct mode, /continue and /integer added"
1.0.0 26-Mar-2006
"First published version"
]
]
ctx-crc-32: context [
crc-long: [
0 1996959894 -301047508 -1727442502 124634137 1886057615
-379345611 -1637575261 249268274 2044508324 -522852066 -1747789432
162941995 2125561021 -407360249 -1866523247 498536548 1789927666
-205950648 -2067906082 450548861 1843258603 -187386543 -2083289657
325883990 1684777152 -43845254 -1973040660 335633487 1661365465
-99664541 -1928851979 997073096 1281953886 -715111964 -1570279054
1006888145 1258607687 -770865667 -1526024853 901097722 1119000684
-608450090 -1396901568 853044451 1172266101 -589951537 -1412350631
651767980 1373503546 -925412992 -1076862698 565507253 1454621731
-809855591 -1195530993 671266974 1594198024 -972236366 -1324619484
795835527 1483230225 -1050600021 -1234817731 1994146192 31158534
-1731059524 -271249366 1907459465 112637215 -1614814043 -390540237
2013776290 251722036 -1777751922 -519137256 2137656763 141376813
-1855689577 -429695999 1802195444 476864866 -2056965928 -228458418
1812370925 453092731 -2113342271 -183516073 1706088902 314042704
-1950435094 -54949764 1658658271 366619977 -1932296973 -69972891
1303535960 984961486 -1547960204 -725929758 1256170817 1037604311
-1529756563 -740887301 1131014506 879679996 -1385723834 -631195440
1141124467 855842277 -1442165665 -586318647 1342533948 654459306
-1106571248 -921952122 1466479909 544179635 -1184443383 -832445281
1591671054 702138776 -1328506846 -942167884 1504918807 783551873
-1212326853 -1061524307 -306674912 -1698712650 62317068 1957810842
-355121351 -1647151185 81470997 1943803523 -480048366 -1805370492
225274430 2053790376 -468791541 -1828061283 167816743 2097651377
-267414716 -2029476910 503444072 1762050814 -144550051 -2140837941
426522225 1852507879 -19653770 -1982649376 282753626 1742555852
-105259153 -1900089351 397917763 1622183637 -690576408 -1580100738
953729732 1340076626 -776247311 -1497606297 1068828381 1219638859
-670225446 -1358292148 906185462 1090812512 -547295293 -1469587627
829329135 1181335161 -882789492 -1134132454 628085408 1382605366
-871598187 -1156888829 570562233 1426400815 -977650754 -1296233688
733239954 1555261956 -1026031705 -1244606671 752459403 1541320221
-1687895376 -328994266 1969922972 40735498 -1677130071 -351390145
1913087877 83908371 -1782625662 -491226604 2075208622 213261112
-1831694693 -438977011 2094854071 198958881 -2032938284 -237706686
1759359992 534414190 -2118248755 -155638181 1873836001 414664567
-2012718362 -15766928 1711684554 285281116 -1889165569 -127750551
1634467795 376229701 -1609899400 -686959890 1308918612 956543938
-1486412191 -799009033 1231636301 1047427035 -1362007478 -640263460
1088359270 936918000 -1447252397 -558129467 1202900863 817233897
-1111625188 -893730166 1404277552 615818150 -1160759803 -841546093
1423857449 601450431 -1285129682 -1000256840 1567103746 711928724
-1274298825 -1022587231 1510334235 755167117
]
right-shift-8: func [
"Right-shifts the value by 8 bits and returns it."
value [integer!] "The value to shift"
][
either negative? value [
-1 xor value and -256 / 256 xor -1 and 16777215
][
-256 and value / 256
]
]
update-crc: either value? 'rebcode [
rebcode [
"Returns the data crc."
data [any-string! binary!] "Data to checksum"
crc [integer!] "Initial value"
/local char i
][
tail? data
iff [
until [
pick char data 1
set.i i crc
xor i char
and i 255
lsr crc 8
pickz i crc-long i
xor crc i
next data
tail? data
]
]
return crc
]
][
func [
"Returns the data crc."
data [any-string! binary!] "Data to checksum"
crc [integer!] "Initial value"
][
foreach char data [
crc: (right-shift-8 crc) xor pick crc-long crc and 255 xor char + 1
]
crc
]
]
any-file?: func [
"Returns TRUE for file and url values." value [any-type!]
][any [file? value url? value]]
file: none
buffer: none
set 'crc-32 func [
"Returns a CRC32 checksum."
source [binary! string! file! url!] "Data or file to checksum"
/direct "For file! and url! sources, uses /direct mode"
buffer-size [integer!] "Buffer size (in bytes)"
/integer "Returns an integer! instead of a binary!"
/continue "Continues a checksum with more data"
crc [integer! binary! none!] "Previous CRC32 value."
][
crc: -1 xor to-integer any [crc 0]
if file [error? try [close file ] file: none]
if buffer [error? try [clear buffer] buffer: none]
either all [direct any-file? source system/version < 2.100.0] [
file: source: open/direct/read/binary source
buffer: make binary! buffer-size
until [
clear buffer
read-io source buffer buffer-size
crc: update-crc buffer crc
wait 0.002
zero? length? buffer
]
clear buffer
close source
buffer: file: source: none
][
if any-file? source [
source: either system/version < 2.100.0 [
read/binary source
][
read source
]
]
if string? source [source: to-binary source]
either any [continue system/version < 2.100.0] [
crc: update-crc source crc
][
crc: -1 xor checksum/method source 'crc32
]
source: none
]
either integer [-1 xor crc][
copy at tail load join "#{" [next mold to-hex -1 xor crc "}"] -4
]
]
]
; Verification
either #{CBF43926} <> crc-32 "123456789" [
make error! "Test failed - CRC-32 doesn't work with this VM."
][true] Notes
|