Code archives/Algorithms/CRC32 checksum calculation

This code has been declared by its author to be Public Domain code.

Download source code

CRC32 checksum calculation by Jake L.2006
Version 1.1: Added buffered streams from Jeremy's code.

Thanks to skidracer and Noel for docmods-support!
superstrict

rem
bbdoc: CRC32 Checksum
endrem
module bt.crc32
moduleinfo "CRC32-Checksum calculation"
moduleinfo "ported to BMax by Jake@bittrap-software.de"
moduleinfo "Original code (BB) written by MrCredo"
moduleinfo "VERSION: 1.1"
moduleinfo "OS: Win32 / MacOS / Linux"
moduleinfo "HISTORY: 1.1 Changed Stream2CRC to buffered version (Credits: JeremytheJJ)"

import brl.stream

private
global table%[256]

local val%
	for local i%=0 to 255
		val=i
		for local j%=0 to 7
			if (val & $1)
				val=(val shr 1) ~ $EDB88320
			else
				val=(val shr 1)
			End If
		Next
		table[i]=val
	Next

	
public

rem
bbdoc:create checksum from String
returns: (Int) CRC32 
endrem	
Function String2CRC32%(s$)
	local crc%=$FFFFFFFF
	for local i%=0 to s.length-1
		crc=(crc shr 8) ~ table[s[i] ~ (crc and $FF)]
	next
	return (crc)
End Function

rem
bbdoc:create checksum from an open stream
returns: (Int) CRC32 
endrem	
Function Stream2CRC32%(stream:TStream,bufferSize:Int=$400000)
	local crc%=$FFFFFFFF
	Local buffPtr:Byte Ptr = MemAlloc(bufferSize)
	
	Repeat
    	Local bytesRead:Int = stream.Read(buffPtr, bufferSize)
        For Local b%=0 Until bytesRead
      		crc = (crc Shr 8) ~ table[buffPtr[b] ~ (crc & $FF)]
    	Next
  	Until stream.Eof()
  
    MemFree(buffPtr)
	return (crc)
End Function

rem
bbdoc:create checksum from url/file
returns: (Int) CRC32 
endrem	
Function URL2CRC32% (url$)
	local st:TStream=OpenStream (url,true,false)
	local crc%=Stream2CRC32(st)
	st.Close()
	return (crc)
End Function

Comments

N2006
Put this above the module bt.crc32 line:
Rem
bbdoc: CRC32 Checksum
EndRem



Yan2006
I did a buffered stream version a while back...
'Adaptation of MrCredo's CRC code
Function CRCFile(FileName:String, bufferSize:Int=$400000) 'default bufferSize = 4MB
	Local crc = $FFFFFFFF
	Global CRCTable[]
	
	If CRCTable = Null
		CRCTable = New Int[256]
	
	  For Local i=0 To 255
	    Local value = i
	    For Local j=0 To 7
	      If value & $1 
	        value = (value Shr 1) ~ $EDB88320
	      Else
	        value = value Shr 1
	      EndIf
	    Next
	    CRCTable[i] = value
	  Next
	EndIf
	
  Local fileStream:TStream = ReadStream(fileName$)
  If fileStream = Null Then Return
  
	Local buffPtr:Byte Ptr = MemAlloc(bufferSize)
	
	Repeat
		Local bytesRead = fileStream.Read(buffPtr, bufferSize)
		
		For Local b=0 Until bytesRead
			crc = (crc Shr 8) ~ CRCTable[buffPtr[b] ~ (crc & $FF)]
		Next
	Until Eof(FileStream)
	
	CloseStream FileStream
	MemFree(buffPtr)
	
	Return ~crc
End Function
Feel free to add it, if you want.


WildStorm2006
you forgot to add the type identifiers
i removed also the ~ @ return ~crc ... it returned a negative integer??
hope i didn't add any bugs

'Adaptation of MrCredo's CRC code
'Edited by Wild-Storm
Function CRCFile:Int(FileName:String, bufferSize:Int=$1500000) 'default bufferSize = 4MB
  Local crc:Int = $FFFFFFFF
  Global CRCTable:Int[]
  
  If CRCTable = Null
    CRCTable = New Int[256]
  
    For Local i%=0 To 255
      Local value% = i
      For Local j%=0 To 7
        If value% & $1 
          value = (value Shr 1) ~ $EDB88320
        Else
          value = value Shr 1
        EndIf
      Next
      CRCTable[i] = value
    Next
  EndIf
  
  Local fileStream:TStream = ReadStream(fileName$)
  If fileStream = Null Then Return -1
  
  Local buffPtr:Byte Ptr = MemAlloc(bufferSize)
  
  Repeat
    Local bytesRead:Int = fileStream.Read(buffPtr, bufferSize)
    
    For Local b%=0 Until bytesRead
      crc = (crc Shr 8) ~ CRCTable[buffPtr[b] ~ (crc & $FF)]
    Next
  Until FileStream.Eof()
  
  FileStream.Close()
  MemFree(buffPtr)
  
  Return crc
End Function



Yan2006
you forgot to add the type identifiers
Erm...No I didn't...I use Strict mode (SuperStrict didn't even exist when this code was written).

i removed also the ~ @ return ~crc ... it returned a negative integer??
I think you'll find that my routine (well, MrCredo's) returns the correct CRC-32 value...
Print Hex$(CRCFile(RequestFile("File to check...", "All Files:*")))
Try comparing the results from other CRC-32 generators.


Jake L.2006
are there any issues yet? My/MrCredo's code should return correct crc32, as I checked the output against some "official" samples.


RifRaf2009
How much faster is Bmax at this than B3D ? I am using the b3d version, and on large files it can chug a bit.

If its ALOT faster, is there any chance someone here can produce a dll from it? im primarily interested in the crcfile portion.


N2009
Could probably do it yourself. It's not terribly complex code.


RifRaf2009
its not the above code, but creating the dll i need help with. I dont own blide ,i do own blitzmax for a few years now but havent so much as wrote hello world with it yet, and i dont have any other compilers that can produce a dll

I was hoping it would be very fast and easy task for someone prepared for it.


Nate the Great2009
you have bmax and all youve written is hello world?!?!??!?! wow.. anyway this is pretty useful stuff


TomToad2014
I know this is pretty old, but there are a couple of bugs in this mod that will prevent it from returning correct crc32 values. you need to change the Return (crc) to Return(~crc) in String2CRC32() and Stream2CRC32() functions. No need to change it in URL2CRC32() as that function already calls Stream2CRC32().

Also change the crc and $FF in the StringtoCRC32() function to crc & $FF.


Code Archives Forum