Hi Mike,
thank you for your comments. Your Checksum function uses the same polynomial as the asm code of \inc\chaos.inc and I tried to port the code to Oxygen:
'Ported from FBSL C-code (Mike Lobanowsky)
$ filename "CheckSumCRC32.exe"
'uses rtl32
'uses rtl64
uses console
ulong crc32_table[256] ' Lookup table array
' Utility functions
function Reflect(uint ref, byte ch) as uint
' Used only by Init_CRC32_Table()
uint value = 0
' Swap bit 0 for bit 7
' bit 1 for bit 6, etc.
int i
for i = 1 to ch + 1
if (ref and 1) then value = value or 1 << (ch - i)
ref = ref >> 1
next i
return value
end function
' Call this function only once to initialize the CRC table.
sub Init_CRC32_Table()
' This is the official polynomial used by CRC-32
' in PKZip, WinZip and Ethernet.
uint ulPolynomial = 0x04c11db7
' 256 values representing ASCII character codes.
int i
for i = 0 to 0xFF
crc32_table[i] = Reflect(i, 8) << 24
int j
for j = 0 to 7
uint mask = crc32_table[i] and (1 << 31)
if mask then
crc32_table[i] = (crc32_table[i] << 1) xor ulPolynomial
else
crc32_table[i] = (crc32_table[i] << 1) xor 0
end if
next j
crc32_table[i] = Reflect(crc32_table[i], 32)
next i
end sub
' Main function
function CheckSum(string buffer) as uint
if (crc32_table[1] == 0) then Init_CRC32_Table() ' do table init once
' Be sure to use unsigned variables,
' because negative values introduce high bits
' where zero bits are required.
' Start out with all bits set high.
uint ulCRC = 0xffffffff
' Perform the algorithm on each character
' in the string, using the lookup table values.
int datalen=len(buffer)
int ix=1
while dataLen
dataLen -= 1
'older oxygen.dll
'int idx = (ulCRC and 0xFF) xor asc(mid(buffer,ix,1))
'ulCRC = (ulCRC >> 8) xor crc32_table[idx]
'newer oxygen.dll
ulCRC = (ulCRC >> 8) xor crc32_table[(ulCRC and 0xFF) xor asc(mid(buffer,ix,1))]
ix+=1
wend
' Exclusive OR the result with the beginning value.
return ulCRC xor 0xffffffff
end function
' ------ main ------
string s = "The quick brown fox jumps over the lazy dog"
printl "Text = " s
printl "The CRC-32 checksum = " right (hex(CheckSum(s)),8) '414FA339
string fname= "CheckSumCRC32.o2bas"
getfile fname, s
printl
printl "Filename = " fname
printl "The CRC-32 checksum = " right (hex(CheckSum(s)),8)
printl "Enter ..."
waitkey
I also tried to apply the algorithm found at Rossettacode (using a different polynomial) which is derived from W3C:
'https://www.w3.org/TR/PNG/#D-CRCAppendix
$ filename "CheckCRC32.exe"
'uses rtl32
'uses rtl64
uses console
function crc32(string buf) as uint
indexbase 0
static uint crc_table[256]
static uint crc_table_computed
uint crc
int n, k
if crc_table_computed = 0 then
for n = 0 to 255
crc = n
for k = 0 to 7
if (crc and 1) then crc = (crc >> 1) xor 0xedb88320 else crc = crc >> 1
crc_table[n] = crc
next k
next n
crc_table_computed = 1
end if
crc = 0xffffffff
for n = 1 to len(buf)
'older oxygen.dll
'int idx = (crc and 0xff) xor asc(mid(buf,n,1)))
'crc = (crc >> 8) xor crc_table[idx]
'newer oxygen.dll
crc = (crc >> 8) xor crc_table[(crc and 0xff) xor asc(mid(buf,n,1))]
next
return not crc
end function
' ------ main ------
string s = "The quick brown fox jumps over the lazy dog"
printl "Text = " s
printl "The CRC-32 checksum = " right (hex(crc32(s)),8) '414FA339
string fname= "CheckCRC32.o2bas"
getfile fname, s
printl
printl "Filename = " fname
printl "The CRC-32 checksum = " right (hex(crc32(s)),8)
printl "Enter..."
waitkey
The code of the two examples works correctly only with oxygen.dll of OXSC19 path, especially when creating exe files. It is interesting to compare the different solutions. The asc(mid(buf,n,1)) expression could be optimized, but I wanted to use a simple way.
The MapFileAndCheckSum function is new to me but it is very interesting. I will do my next experiments with it.
Roland