2024-04-29

Navigation

Skip Navigation Links

Hash algorithms

Asymmetric Algorithms

Symmetric Cipher Algorithms

Encoding Algorithms

Compression Algorithms

Pseudo Random Number Algorithms

Steganography

Library Wrappers

String Comparison

Others

Syntax highlighting by Prism
PBCrypto.com Mirror

CRC-32

Algorithm creator(s)

n/a


PB author(s)

Marc Sven Schulte, Dave Navarro, Semen Matusovski, Wayne Diamond


Description

A relatively fast algorithm that creates a 32-bit checksum. CRC32 is the most commonly-used 32-bit checksum algorithm.


Note

Four different implementations of CRC32.


Source

https://forum.powerbasic.com/forum/user-to-user-discussions/programming/18709-true-crc32


See also

n/a


Source Code

Download source code file crc32.bas (Right-click -> "Save as ...")

'################################################################
'CRC32, by Hans Joerg Viechtbauer and Marc Sven Schulte, 26th July 2003.
'Currently the fastest CRC32 implementation for PB.
FUNCTION CRC32(BYVAL Address AS DWORD, _
  BYVAL Length AS LONG, BYVAL Seed AS LONG) AS LONG
  ! MOV EBX, Seed
  ! XOR EBX, &HFFFFFFFF
  ! MOV ESI, Length
  ! CMP ESI, 0
  ! JZ  QuitLoop
  ! MOV EDI, Address
  ! XOR EAX, EAX
  NextByte:
  ! MOV AL, BL
  ! XOR AL, [EDI]
  ! MOV ECX, CrcTable[4*EAX]
  ! SHR EBX, 8
  ! XOR EBX, ECX
  ! INC EDI
  ! DEC ESI
  ! JNZ NextByte
  QuitLoop:
  ! XOR EBX, &HFFFFFFFF
  ! MOV Function, EBX
  EXIT FUNCTION
  CrcTable:
  ! dd &H000000000&, &H077073096&, &H0EE0E612C&, &H0990951BA&
  ! dd &H0076DC419&, &H0706AF48F&, &H0E963A535&, &H09E6495A3&
  ! dd &H00EDB8832&, &H079DCB8A4&, &H0E0D5E91E&, &H097D2D988&
  ! dd &H009B64C2B&, &H07EB17CBD&, &H0E7B82D07&, &H090BF1D91&
  ! dd &H01DB71064&, &H06AB020F2&, &H0F3B97148&, &H084BE41DE&
  ! dd &H01ADAD47D&, &H06DDDE4EB&, &H0F4D4B551&, &H083D385C7&
  ! dd &H0136C9856&, &H0646BA8C0&, &H0FD62F97A&, &H08A65C9EC&
  ! dd &H014015C4F&, &H063066CD9&, &H0FA0F3D63&, &H08D080DF5&
  ! dd &H03B6E20C8&, &H04C69105E&, &H0D56041E4&, &H0A2677172&
  ! dd &H03C03E4D1&, &H04B04D447&, &H0D20D85FD&, &H0A50AB56B&
  ! dd &H035B5A8FA&, &H042B2986C&, &H0DBBBC9D6&, &H0ACBCF940&
  ! dd &H032D86CE3&, &H045DF5C75&, &H0DCD60DCF&, &H0ABD13D59&
  ! dd &H026D930AC&, &H051DE003A&, &H0C8D75180&, &H0BFD06116&
  ! dd &H021B4F4B5&, &H056B3C423&, &H0CFBA9599&, &H0B8BDA50F&
  ! dd &H02802B89E&, &H05F058808&, &H0C60CD9B2&, &H0B10BE924&
  ! dd &H02F6F7C87&, &H058684C11&, &H0C1611DAB&, &H0B6662D3D&
  ! dd &H076DC4190&, &H001DB7106&, &H098D220BC&, &H0EFD5102A&
  ! dd &H071B18589&, &H006B6B51F&, &H09FBFE4A5&, &H0E8B8D433&
  ! dd &H07807C9A2&, &H00F00F934&, &H09609A88E&, &H0E10E9818&
  ! dd &H07F6A0DBB&, &H0086D3D2D&, &H091646C97&, &H0E6635C01&
  ! dd &H06B6B51F4&, &H01C6C6162&, &H0856530D8&, &H0F262004E&
  ! dd &H06C0695ED&, &H01B01A57B&, &H08208F4C1&, &H0F50FC457&
  ! dd &H065B0D9C6&, &H012B7E950&, &H08BBEB8EA&, &H0FCB9887C&
  ! dd &H062DD1DDF&, &H015DA2D49&, &H08CD37CF3&, &H0FBD44C65&
  ! dd &H04DB26158&, &H03AB551CE&, &H0A3BC0074&, &H0D4BB30E2&
  ! dd &H04ADFA541&, &H03DD895D7&, &H0A4D1C46D&, &H0D3D6F4FB&
  ! dd &H04369E96A&, &H0346ED9FC&, &H0AD678846&, &H0DA60B8D0&
  ! dd &H044042D73&, &H033031DE5&, &H0AA0A4C5F&, &H0DD0D7CC9&
  ! dd &H05005713C&, &H0270241AA&, &H0BE0B1010&, &H0C90C2086&
  ! dd &H05768B525&, &H0206F85B3&, &H0B966D409&, &H0CE61E49F&
  ! dd &H05EDEF90E&, &H029D9C998&, &H0B0D09822&, &H0C7D7A8B4&
  ! dd &H059B33D17&, &H02EB40D81&, &H0B7BD5C3B&, &H0C0BA6CAD&
  ! dd &H0EDB88320&, &H09ABFB3B6&, &H003B6E20C&, &H074B1D29A&
  ! dd &H0EAD54739&, &H09DD277AF&, &H004DB2615&, &H073DC1683&
  ! dd &H0E3630B12&, &H094643B84&, &H00D6D6A3E&, &H07A6A5AA8&
  ! dd &H0E40ECF0B&, &H09309FF9D&, &H00A00AE27&, &H07D079EB1&
  ! dd &H0F00F9344&, &H08708A3D2&, &H01E01F268&, &H06906C2FE&
  ! dd &H0F762575D&, &H0806567CB&, &H0196C3671&, &H06E6B06E7&
  ! dd &H0FED41B76&, &H089D32BE0&, &H010DA7A5A&, &H067DD4ACC&
  ! dd &H0F9B9DF6F&, &H08EBEEFF9&, &H017B7BE43&, &H060B08ED5&
  ! dd &H0D6D6A3E8&, &H0A1D1937E&, &H038D8C2C4&, &H04FDFF252&
  ! dd &H0D1BB67F1&, &H0A6BC5767&, &H03FB506DD&, &H048B2364B&
  ! dd &H0D80D2BDA&, &H0AF0A1B4C&, &H036034AF6&, &H041047A60&
  ! dd &H0DF60EFC3&, &H0A867DF55&, &H0316E8EEF&, &H04669BE79&
  ! dd &H0CB61B38C&, &H0BC66831A&, &H0256FD2A0&, &H05268E236&
  ! dd &H0CC0C7795&, &H0BB0B4703&, &H0220216B9&, &H05505262F&
  ! dd &H0C5BA3BBE&, &H0B2BD0B28&, &H02BB45A92&, &H05CB36A04&
  ! dd &H0C2D7FFA7&, &H0B5D0CF31&, &H02CD99E8B&, &H05BDEAE1D&
  ! dd &H09B64C2B0&, &H0EC63F226&, &H0756AA39C&, &H0026D930A&
  ! dd &H09C0906A9&, &H0EB0E363F&, &H072076785&, &H005005713&
  ! dd &H095BF4A82&, &H0E2B87A14&, &H07BB12BAE&, &H00CB61B38&
  ! dd &H092D28E9B&, &H0E5D5BE0D&, &H07CDCEFB7&, &H00BDBDF21&
  ! dd &H086D3D2D4&, &H0F1D4E242&, &H068DDB3F8&, &H01FDA836E&
  ! dd &H081BE16CD&, &H0F6B9265B&, &H06FB077E1&, &H018B74777&
  ! dd &H088085AE6&, &H0FF0F6A70&, &H066063BCA&, &H011010B5C&
  ! dd &H08F659EFF&, &H0F862AE69&, &H0616BFFD3&, &H0166CCF45&
  ! dd &H0A00AE278&, &H0D70DD2EE&, &H04E048354&, &H03903B3C2&
  ! dd &H0A7672661&, &H0D06016F7&, &H04969474D&, &H03E6E77DB&
  ! dd &H0AED16A4A&, &H0D9D65ADC&, &H040DF0B66&, &H037D83BF0&
  ! dd &H0A9BCAE53&, &H0DEBB9EC5&, &H047B2CF7F&, &H030B5FFE9&
  ! dd &H0BDBDF21C&, &H0CABAC28A&, &H053B39330&, &H024B4A3A6&
  ! dd &H0BAD03605&, &H0CDD70693&, &H054DE5729&, &H023D967BF&
  ! dd &H0B3667A2E&, &H0C4614AB8&, &H05D681B02&, &H02A6F2B94&
  ! dd &H0B40BBE37&, &H0C30C8EA1&, &H05A05DF1B&, &H02D02EF8D&
END FUNCTION
FUNCTION PBMAIN() AS LONG
  DIM buffer AS STRING, crc AS LONG
  buffer = "1234567890"
  crc = CRC32(STRPTR(buffer), LEN(buffer), crc)
  MSGBOX "CRC32: " & HEX$(crc, 8) & " (should be: 261DAEE5)"
END FUNCTION


'################################################################
'CRC32, by Wayne Diamond, 9th December 2002. For PBCC/PBDLL/PBWIN
'Usage: dwHash = CRC32(BYVAL STRPTR(Buffer), BYVAL LEN(Buffer))
FUNCTION CRC32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD) AS DWORD
#REGISTER NONE
 ! mov esi, dwOffset  ;esi = ptr to buffer
 ! mov edi, dwLen     ;edi = length of buffer
 ! mov ecx, -1        ;ecx = -1
 ! mov edx, ecx       ;edx = -1
 nextbyte:           ';next byte from butter
 ! xor eax, eax       ;eax = 0
 ! xor ebx, ebx       ;ebx = 0
 ! lodsb              ;get next byte
 ! xor al, cl         ;xor al with cl
 ! mov cl, ch         ;cl = ch
 ! mov ch, dl         ;ch = dl
 ! mov dl, dh         ;dl = dh
 ! mov dh, 8          ;dh = 8
 nextbit:            ';next bit in the byte
 ! shr bx, 1          ;shift bits in bx right by 1
 ! rcr ax, 1          ;(rotate through carry) bits in ax by 1
 ! jnc nocarry        ;jump to nocarry if carry flag not set
 ! xor ax, &h08320    ;xor ax with 33568
 ! xor bx, &h0EDB8    ;xor bx with 60856
 nocarry:            ';if carry flag wasn't set
 ! dec dh             ;dh = dh - 1
 ! jnz nextbit        ;if dh isnt zero, jump to nextbit
 ! xor ecx, eax       ;xor ecx with eax
 ! xor edx, ebx       ;xor edx with ebx
 ! dec edi            ;finished with that byte, decrement counter
 ! jnz nextbyte       ;if edi counter isnt at 0, jump to nextbyte
 ! not edx            ;invert edx bits - 1s complement
 ! not ecx            ;invert ecx bits - 1s complement
 ! mov eax, edx       ;mov edx into eax
 ! rol eax, 16        ;rotate bits in eax left by 16 places
 ! mov ax, cx         ;mov cx into ax
 ! mov FUNCTION, eax  ;crc32 result is in eax
END FUNCTION
'################################################################
 
 
'==============================================================================
'  CRC32 - Calculate a CCITT 32-bit for a buffer
'  Copyright (c) 1998 by PowerBASIC, Inc.
'  This source will compile unmodified in PB/CC.  The Crc32 function itself
'  is compatible with PB/DLL 5.0.
'==============================================================================
FUNCTION PBCrc32(BYVAL Address AS DWORD, _
         BYVAL Length AS LONG, _
         BYVAL Seed AS LONG) AS LONG
  ! push    EBX             ; save EBX for PowerBASIC
  ! push    EDI             ; save EDI for PowerBASIC
  ! mov   EDI,Address         ; address in EDI
  ! mov   ECX,Length          ; length in ECX
  ! jecxz   CrcDone           ; exit is zero length
  ! cld                   ; clear the direction flag
BuildCRC:
  ! movzx   EBX, Byte Ptr [EDI]   ; get a char
  ! mov   AX, Seed[1]         ; get 2nd and 3rd bytes of seed
  ! xor   DX, DX            ; clear DX
  ! mov   DL, Seed[3]         ; get 4th byte of seed
  ! xor   BL, Seed[0]         ; xor char against first byte of seed
  ! xor   BH, BH            ; clear BH
  ! shl   BX, 2             ; shift the index
  ! xor   AX, CrcTable[EBX]     ; xor low-half against the table
  ! xor   DX, CrcTable[EBX+2]   ; xor high-half against the table
  ! mov   Seed[0], AX         ; save the result
  ! mov   Seed[2], DX         ;   ...
  ! inc   EDI             ; move to next char
  ! loop    BuildCRC          ; do ECX times
CrcDone:
  ! pop   EDI             ; restore EDI
  ! pop   EBX             ; restore EBX
  FUNCTION = Seed
  EXIT FUNCTION
CrcTable:
  ! dd &H000000000&, &H077073096&, &H0EE0E612C&, &H0990951BA&
  ! dd &H0076DC419&, &H0706AF48F&, &H0E963A535&, &H09E6495A3&
  ! dd &H00EDB8832&, &H079DCB8A4&, &H0E0D5E91E&, &H097D2D988&
  ! dd &H009B64C2B&, &H07EB17CBD&, &H0E7B82D07&, &H090BF1D91&
  ! dd &H01DB71064&, &H06AB020F2&, &H0F3B97148&, &H084BE41DE&
  ! dd &H01ADAD47D&, &H06DDDE4EB&, &H0F4D4B551&, &H083D385C7&
  ! dd &H0136C9856&, &H0646BA8C0&, &H0FD62F97A&, &H08A65C9EC&
  ! dd &H014015C4F&, &H063066CD9&, &H0FA0F3D63&, &H08D080DF5&
  ! dd &H03B6E20C8&, &H04C69105E&, &H0D56041E4&, &H0A2677172&
  ! dd &H03C03E4D1&, &H04B04D447&, &H0D20D85FD&, &H0A50AB56B&
  ! dd &H035B5A8FA&, &H042B2986C&, &H0DBBBC9D6&, &H0ACBCF940&
  ! dd &H032D86CE3&, &H045DF5C75&, &H0DCD60DCF&, &H0ABD13D59&
  ! dd &H026D930AC&, &H051DE003A&, &H0C8D75180&, &H0BFD06116&
  ! dd &H021B4F4B5&, &H056B3C423&, &H0CFBA9599&, &H0B8BDA50F&
  ! dd &H02802B89E&, &H05F058808&, &H0C60CD9B2&, &H0B10BE924&
  ! dd &H02F6F7C87&, &H058684C11&, &H0C1611DAB&, &H0B6662D3D&
  ! dd &H076DC4190&, &H001DB7106&, &H098D220BC&, &H0EFD5102A&
  ! dd &H071B18589&, &H006B6B51F&, &H09FBFE4A5&, &H0E8B8D433&
  ! dd &H07807C9A2&, &H00F00F934&, &H09609A88E&, &H0E10E9818&
  ! dd &H07F6A0DBB&, &H0086D3D2D&, &H091646C97&, &H0E6635C01&
  ! dd &H06B6B51F4&, &H01C6C6162&, &H0856530D8&, &H0F262004E&
  ! dd &H06C0695ED&, &H01B01A57B&, &H08208F4C1&, &H0F50FC457&
  ! dd &H065B0D9C6&, &H012B7E950&, &H08BBEB8EA&, &H0FCB9887C&
  ! dd &H062DD1DDF&, &H015DA2D49&, &H08CD37CF3&, &H0FBD44C65&
  ! dd &H04DB26158&, &H03AB551CE&, &H0A3BC0074&, &H0D4BB30E2&
  ! dd &H04ADFA541&, &H03DD895D7&, &H0A4D1C46D&, &H0D3D6F4FB&
  ! dd &H04369E96A&, &H0346ED9FC&, &H0AD678846&, &H0DA60B8D0&
  ! dd &H044042D73&, &H033031DE5&, &H0AA0A4C5F&, &H0DD0D7CC9&
  ! dd &H05005713C&, &H0270241AA&, &H0BE0B1010&, &H0C90C2086&
  ! dd &H05768B525&, &H0206F85B3&, &H0B966D409&, &H0CE61E49F&
  ! dd &H05EDEF90E&, &H029D9C998&, &H0B0D09822&, &H0C7D7A8B4&
  ! dd &H059B33D17&, &H02EB40D81&, &H0B7BD5C3B&, &H0C0BA6CAD&
  ! dd &H0EDB88320&, &H09ABFB3B6&, &H003B6E20C&, &H074B1D29A&
  ! dd &H0EAD54739&, &H09DD277AF&, &H004DB2615&, &H073DC1683&
  ! dd &H0E3630B12&, &H094643B84&, &H00D6D6A3E&, &H07A6A5AA8&
  ! dd &H0E40ECF0B&, &H09309FF9D&, &H00A00AE27&, &H07D079EB1&
  ! dd &H0F00F9344&, &H08708A3D2&, &H01E01F268&, &H06906C2FE&
  ! dd &H0F762575D&, &H0806567CB&, &H0196C3671&, &H06E6B06E7&
  ! dd &H0FED41B76&, &H089D32BE0&, &H010DA7A5A&, &H067DD4ACC&
  ! dd &H0F9B9DF6F&, &H08EBEEFF9&, &H017B7BE43&, &H060B08ED5&
  ! dd &H0D6D6A3E8&, &H0A1D1937E&, &H038D8C2C4&, &H04FDFF252&
  ! dd &H0D1BB67F1&, &H0A6BC5767&, &H03FB506DD&, &H048B2364B&
  ! dd &H0D80D2BDA&, &H0AF0A1B4C&, &H036034AF6&, &H041047A60&
  ! dd &H0DF60EFC3&, &H0A867DF55&, &H0316E8EEF&, &H04669BE79&
  ! dd &H0CB61B38C&, &H0BC66831A&, &H0256FD2A0&, &H05268E236&
  ! dd &H0CC0C7795&, &H0BB0B4703&, &H0220216B9&, &H05505262F&
  ! dd &H0C5BA3BBE&, &H0B2BD0B28&, &H02BB45A92&, &H05CB36A04&
  ! dd &H0C2D7FFA7&, &H0B5D0CF31&, &H02CD99E8B&, &H05BDEAE1D&
  ! dd &H09B64C2B0&, &H0EC63F226&, &H0756AA39C&, &H0026D930A&
  ! dd &H09C0906A9&, &H0EB0E363F&, &H072076785&, &H005005713&
  ! dd &H095BF4A82&, &H0E2B87A14&, &H07BB12BAE&, &H00CB61B38&
  ! dd &H092D28E9B&, &H0E5D5BE0D&, &H07CDCEFB7&, &H00BDBDF21&
  ! dd &H086D3D2D4&, &H0F1D4E242&, &H068DDB3F8&, &H01FDA836E&
  ! dd &H081BE16CD&, &H0F6B9265B&, &H06FB077E1&, &H018B74777&
  ! dd &H088085AE6&, &H0FF0F6A70&, &H066063BCA&, &H011010B5C&
  ! dd &H08F659EFF&, &H0F862AE69&, &H0616BFFD3&, &H0166CCF45&
  ! dd &H0A00AE278&, &H0D70DD2EE&, &H04E048354&, &H03903B3C2&
  ! dd &H0A7672661&, &H0D06016F7&, &H04969474D&, &H03E6E77DB&
  ! dd &H0AED16A4A&, &H0D9D65ADC&, &H040DF0B66&, &H037D83BF0&
  ! dd &H0A9BCAE53&, &H0DEBB9EC5&, &H047B2CF7F&, &H030B5FFE9&
  ! dd &H0BDBDF21C&, &H0CABAC28A&, &H053B39330&, &H024B4A3A6&
  ! dd &H0BAD03605&, &H0CDD70693&, &H054DE5729&, &H023D967BF&
  ! dd &H0B3667A2E&, &H0C4614AB8&, &H05D681B02&, &H02A6F2B94&
  ! dd &H0B40BBE37&, &H0C30C8EA1&, &H05A05DF1B&, &H02D02EF8D&
END FUNCTION

FUNCTION PBMAIN() AS LONG
'// Test both of the CRC32 functions...
'// This section by PowerBASIC Inc., 1998
  LOCAL Buffer   AS STRING
  LOCAL Crc    AS LONG
  LOCAL Filename AS STRING
  PRINT "CRC32.EXE - Calculate 32-bit CRC of a file"
  PRINT "Copyright (c) 1998 by PowerBASIC, Inc."
  PRINT
  Filename = COMMAND$
  IF LEN(DIR$(Filename)) = 0 THEN
    PRINT "Usage:  CRC32 filename"
    WAITKEY$
    EXIT FUNCTION
  END IF
  OPEN Filename FOR BINARY AS #1
    GET$ 1, LOF(1), Buffer
  CLOSE 1
  Buffer = CHR$(0) & "Testing 1 2 3" & CHR$(255)
  Crc = PBCrc32(STRPTR(Buffer), LEN(Buffer), -1)
  Crc = Crc XOR -1&  'compute PKZIP/ZMODEM compatible CRC result
  STDOUT "PB's CRC32 result:   " & HEX$(Crc,8)
  
'// This section added by Wayne Diamond, Dec 2002
  Crc = CRC32(BYVAL STRPTR(Buffer), BYVAL LEN(Buffer))
  STDOUT "Waynes CRC32 result: " & HEX$(Crc,8)
  WAITKEY$
END FUNCTION






'################################################################
'CRC32, by Semen Matusovski.
'Modified by Wayne Diamond to use a global CRCTable which only
'needs to be initialised once.
 
#COMPILE EXE
 
GLOBAL sCrcTable AS STRING * 1024, PtrCRC AS DWORD POINTER
 
SUB Crc32_BuildTable(BYVAL MagWord AS LONG)
    DIM x AS DWORD POINTER
    x = VARPTR(sCrcTable)
      ! MOV EDI, PtrCRC
      ! MOV EDX, 0
 Crc32_BuildTable_Lb1:
      ! MOV EBX, EDX
      ! MOV ECX, 8
 Crc32_BuildTable_Lb2:
      ! MOV EAX, EBX
      ! AND EAX, 1
      ! JE Crc32_BuildTable_Lb3
      ! SHR EBX, 1
      ! MOV EAX, MagWord
      ! XOR EBX, EAX
      ! JMP Crc32_BuildTable_Lb4
 Crc32_BuildTable_Lb3:
      ! SHR EBX, 1
 Crc32_BuildTable_Lb4:
      ! DEC ECX
      ! JNZ Crc32_BuildTable_Lb2
      ! MOV [EDI], EBX
      ! ADD EDI, 4
      ! INC EDX
      ! CMP EDX, 255
      ! JLE Crc32_BuildTable_Lb1
END SUB

FUNCTION Crc32_Calculate (BYVAL Address AS DWORD, BYVAL Length AS LONG, _
      sCrcTable AS STRING * 1024, BYVAL InitCrc AS LONG, BYVAL Inverse AS LONG) AS LONG
      ! MOV EBX, InitCrc
      ! MOV EDI, Address
      ! MOV ESI, EDI
      ! ADD ESI, Length
 Crc32_Calculate_Lb1:
      ! CMP EDI, ESI
      ! JGE  Crc32_Calculate_Lb2
      ! MOV EAX, 0
      ! MOV AL, [EDI]
      ! XOR EAX, EBX
      ! AND EAX, &HFF
      ! SHL EAX, 2
      ! add EaX, PtrCRC  ;sCrcTable
      ! MOV EAX, [EAX]
      ! SHR EBX, 8
      ! AND EBX, &H00FFFFFF
      ! XOR EBX, EAX
      ! INC EDI
      ! JMP Crc32_Calculate_Lb1
  Crc32_Calculate_Lb2:
      ! CMP Inverse, 0
      ! JE  Crc32_Calculate_Lb3
      ! XOR EBX, &HFFFFFFFF
 Crc32_Calculate_Lb3:
      ! MOV Function, EBX
END FUNCTION

FUNCTION PBMAIN() AS LONG
     DIM Buffer AS STRING, Crc AS LONG
     PtrCRC = VARPTR(sCrcTable)
     Buffer = "1234567890"
     Crc32_BuildTable &HEDB88320
     Crc = Crc32_Calculate (STRPTR(Buffer), LEN(Buffer), sCrcTable, &HFFFFFFFF, 1)
     MSGBOX HEX$(Crc) & " (should be 261DAEE5)",, "Winzip compatible CRC"
END FUNCTION
'################################################################

Mirror provided by Knuth Konrad