AI
Animation
CGI
Compression
Console
Database
Debug
Dialects
Dialogs
Editor
Email
Encryption
Extension
External Library
File
File Handling
Files
Financial
FTP
Game
Games
Graphics
GUI
HTML
HTTP
Internet
LDC
Markup
Math
Module
Network
Networking
None
Other - Net
Parse
Patch
Printing
Protocol
Rebol
Scheme
Scientific
SDK
Security
Shell
Sound
SQL
TCP
Testing
Text
Text Processing
UI
User Interface
Util
Utility
VID
Visualization
Web
Win API
X-File
XML
REBOL [
    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]

            
            
        
Copyright © 2018 Rebol Software Foundation