16-bit CRC (Cyclic Redundancy Checksum) of Memory

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by El_Choni.

Don't know why it crashes, haven't got wXP. Anyway, here's the very same code with command line support. If you discard the OpenWindow and TextGadget thing, you can get the MessageRequester alone just by dropping a file in the executable.

Code: Select all

;==============================================================================
;
; CRC32 - Calculate a CCITT 32-bit For a buffer
; Copyright (c) 1998 by PowerBASIC, Inc.
; Translated to PureBasic by El_Choni
;
; This source will compile unmodified in PureBasic 2.90 with Inline Asm enabled
;
;==============================================================================

Global Address.l, Length.l, Seed.l, number.l, operand.l

Procedure.l Crc32(Address.l, Length.l, Seed.l)
! mov edi, [v_Address]     ; address in EDI
! mov ecx, [v_Length]      ; length in ecx
! jecxz CrcDone            ; exit is zero length
! cld                      ; clear the direction flag
!BuildCRC:
! movzx ebx, byte [edi]    ; get a char
! mov ax, [v_Seed+1]       ; get 2nd and 3rd bytes of seed
! xor dx, dx               ; clear DX
! mov dl, [v_Seed+3]       ; get 4th byte of seed
! xor bl, [v_Seed]         ; 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 [v_Seed], ax         ; save the result
! mov [v_Seed+2], dx       ; ...
! inc edi                  ; move to next char
! loop BuildCRC            ; do ECX times
!CrcDone:
ProcedureReturn Seed
EndProcedure

Procedure.l Xor(number.l, operand.l)
! mov eax, [v_number]
! mov edx, [v_operand]
! xor eax, edx
! mov [v_number], eax
  ProcedureReturn number
EndProcedure

!jmp EndTable
!CrcTable:
! dd $000000000, $077073096, $0EE0E612C, $0990951BA
! dd $0076DC419, $0706AF48F, $0E963A535, $09E6495A3
! dd $00EDB8832, $079DCB8A4, $0E0D5E91E, $097D2D988
! dd $009B64C2B, $07EB17CBD, $0E7B82D07, $090BF1D91
! dd $01DB71064, $06AB020F2, $0F3B97148, $084BE41DE
! dd $01ADAD47D, $06DDDE4EB, $0F4D4B551, $083D385C7
! dd $0136C9856, $0646BA8C0, $0FD62F97A, $08A65C9EC
! dd $014015C4F, $063066CD9, $0FA0F3D63, $08D080DF5
! dd $03B6E20C8, $04C69105E, $0D56041E4, $0A2677172
! dd $03C03E4D1, $04B04D447, $0D20D85FD, $0A50AB56B
! dd $035B5A8FA, $042B2986C, $0DBBBC9D6, $0ACBCF940
! dd $032D86CE3, $045DF5C75, $0DCD60DCF, $0ABD13D59
! dd $026D930AC, $051DE003A, $0C8D75180, $0BFD06116
! dd $021B4F4B5, $056B3C423, $0CFBA9599, $0B8BDA50F
! dd $02802B89E, $05F058808, $0C60CD9B2, $0B10BE924
! dd $02F6F7C87, $058684C11, $0C1611DAB, $0B6662D3D
! dd $076DC4190, $001DB7106, $098D220BC, $0EFD5102A
! dd $071B18589, $006B6B51F, $09FBFE4A5, $0E8B8D433
! dd $07807C9A2, $00F00F934, $09609A88E, $0E10E9818
! dd $07F6A0DBB, $0086D3D2D, $091646C97, $0E6635C01
! dd $06B6B51F4, $01C6C6162, $0856530D8, $0F262004E
! dd $06C0695ED, $01B01A57B, $08208F4C1, $0F50FC457
! dd $065B0D9C6, $012B7E950, $08BBEB8EA, $0FCB9887C
! dd $062DD1DDF, $015DA2D49, $08CD37CF3, $0FBD44C65
! dd $04DB26158, $03AB551CE, $0A3BC0074, $0D4BB30E2
! dd $04ADFA541, $03DD895D7, $0A4D1C46D, $0D3D6F4FB
! dd $04369E96A, $0346ED9FC, $0AD678846, $0DA60B8D0
! dd $044042D73, $033031DE5, $0AA0A4C5F, $0DD0D7CC9
! dd $05005713C, $0270241AA, $0BE0B1010, $0C90C2086
! dd $05768B525, $0206F85B3, $0B966D409, $0CE61E49F
! dd $05EDEF90E, $029D9C998, $0B0D09822, $0C7D7A8B4
! dd $059B33D17, $02EB40D81, $0B7BD5C3B, $0C0BA6CAD
! dd $0EDB88320, $09ABFB3B6, $003B6E20C, $074B1D29A
! dd $0EAD54739, $09DD277AF, $004DB2615, $073DC1683
! dd $0E3630B12, $094643B84, $00D6D6A3E, $07A6A5AA8
! dd $0E40ECF0B, $09309FF9D, $00A00AE27, $07D079EB1
! dd $0F00F9344, $08708A3D2, $01E01F268, $06906C2FE
! dd $0F762575D, $0806567CB, $0196C3671, $06E6B06E7
! dd $0FED41B76, $089D32BE0, $010DA7A5A, $067DD4ACC
! dd $0F9B9DF6F, $08EBEEFF9, $017B7BE43, $060B08ED5
! dd $0D6D6A3E8, $0A1D1937E, $038D8C2C4, $04FDFF252
! dd $0D1BB67F1, $0A6BC5767, $03FB506DD, $048B2364B
! dd $0D80D2BDA, $0AF0A1B4C, $036034AF6, $041047A60
! dd $0DF60EFC3, $0A867DF55, $0316E8EEF, $04669BE79
! dd $0CB61B38C, $0BC66831A, $0256FD2A0, $05268E236
! dd $0CC0C7795, $0BB0B4703, $0220216B9, $05505262F
! dd $0C5BA3BBE, $0B2BD0B28, $02BB45A92, $05CB36A04
! dd $0C2D7FFA7, $0B5D0CF31, $02CD99E8B, $05BDEAE1D
! dd $09B64C2B0, $0EC63F226, $0756AA39C, $0026D930A
! dd $09C0906A9, $0EB0E363F, $072076785, $005005713
! dd $095BF4A82, $0E2B87A14, $07BB12BAE, $00CB61B38
! dd $092D28E9B, $0E5D5BE0D, $07CDCEFB7, $00BDBDF21
! dd $086D3D2D4, $0F1D4E242, $068DDB3F8, $01FDA836E
! dd $081BE16CD, $0F6B9265B, $06FB077E1, $018B74777
! dd $088085AE6, $0FF0F6A70, $066063BCA, $011010B5C
! dd $08F659EFF, $0F862AE69, $0616BFFD3, $0166CCF45
! dd $0A00AE278, $0D70DD2EE, $04E048354, $03903B3C2
! dd $0A7672661, $0D06016F7, $04969474D, $03E6E77DB
! dd $0AED16A4A, $0D9D65ADC, $040DF0B66, $037D83BF0
! dd $0A9BCAE53, $0DEBB9EC5, $047B2CF7F, $030B5FFE9
! dd $0BDBDF21C, $0CABAC28A, $053B39330, $024B4A3A6
! dd $0BAD03605, $0CDD70693, $054DE5729, $023D967BF
! dd $0B3667A2E, $0C4614AB8, $05D681B02, $02A6F2B94
! dd $0B40BBE37, $0C30C8EA1, $05A05DF1B, $02D02EF8D
!EndTable:

PbMain:

a.b

Filename.s = ProgramParameter()

If CreateMenu(0)
  MenuTitle("&File")
    MenuItem(0, "&Open")
    MenuBar()
    MenuItem(1, "&Quit")
EndIf

InitGadget(1)

If OpenWindow(0, #CW_USEDEFAULT, #CW_USEDEFAULT, 320, 128, 0, "CRC32")

  AttachMenu(0, WindowID())

  If CreateGadgetList(WindowID())
    TextGadget(0, 5, 5, WindowWidth()-10, WindowHeight()-10, "CRC32.EXE - Calculate 32-bit CRC of a file"+Chr(10)+"Copyright (c) 1998 by PowerBASIC, Inc."+Chr(10)+"Translated to PureBasic by El_Choni")
  EndIf
  If Len(Filename) > 0
    Gosub OpenFile
  EndIf

  Repeat

    EventID.l = WaitWindowEvent()

    Select EventID
      Case #PB_EventMenu
        Select EventMenuID()
          Case 0 ; Open
            If Len(Filename) = 0
              Filename = OpenFileRequester("Open file","","All files (*.*)|*.*", 0)
            EndIf
            Gosub OpenFile
          Case 1 ; Quit
            Quit = 1
        EndSelect
      Case #PB_EventCloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
EndIf

End

OpenFile:

If Len(Filename) > 0
  If ReadFile(0, Filename)
    Length = FileSize(Filename)
    Address = AllocateMemory(0, Length, 0)
    ReadData(Address, Length)
    CloseFile(0)
    Seed = -1
    number = Crc32(Address, Length, Seed)
    operand = -1
    Crc = Xor(number, operand) ;compute PKZIP/ZMODEM compatible CRC result
    MessageRequester("CRC32:", "Result for "+Filename+" is: "+Chr(10)+Chr(10)+Hex(Crc), 0)
  EndIf
  Filename = ""
EndIf

Return
Bye,

El_Choni
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by horst.

Here is another one.
I had used CRC32 under DOS, and changed the routine for Win32.
The CRC table is not constant, but built up by CR32ini().
Here is CRC32.pbi to include, and a test program.
Any suggestions welcome (tested under Win98).

; ---------------------------------------------------------------
; CRC32.pbi
; ---------------------------------------------------------------
; include CRC32.pbi:
; token for AllocateMemory (0,1,2..) must be supplied as
; constant #CRCtableMem (before IncludeFile statement)
;
; CRC32ini()
; makes table that will be used by CRC computation;
; table pointer by UseMemory(#CRCtableMem);
; returns 0 if AllocateMemory() failed.
;
; CRCcompute(*mem_,size_)
; Computes CRC32 for data area given by *mem_ pointer and size_

Procedure CRC32ini()
*CRCtable = AllocateMemory(#CRCtableMem,1024,0)
If *CRCtable
mov EDI,*CRCtable
!sub EDX,EDX
!.rpt_DX:
!mov EAX,EDX
!mov EBX,8
!.rpt_BX:
!shr EAX,1
!jnc .cont
!xor EAX,0EDB88320h
!.cont:
!dec EBX
!jnz .rpt_BX
!stosd
!inc EDX
!cmp EDX,256
!jb .rpt_DX
ProcedureReturn 1
EndIf
EndProcedure

Procedure CRC32compute(*mem_,size_)
*CRCtable = UseMemory(#CRCtableMem)
CRCret.l
mov EDI,*CRCtable
mov ESI,*mem_
mov EDX,size_
!mov EAX,-1
!.rpt_DX:
!xor EBX,EBX
!mov BL,AL
!xor BL,[ESI]
!shl EBX,2
!shr EAX,8
!xor EAX,[edi+ebx]
!inc ESI
!dec EDX
!jnz .rpt_DX
!not EAX
mov CRCret,EAX
ProcedureReturn CRCret
EndProcedure

; end of CR32.pbi

; ---------------------------------------------------------------
; CRC test Program
; ---------------------------------------------------------------

#CRCtableMem = 0 ; for memory allocation
IncludeFile "CRC32.pbi"

If CRC32ini()
fn.s = OpenFileRequester("CRC32",".\", "*.*",0)
If Len(fn)
If ReadFile(0,fn)
size = Lof()
*mem = AllocateMemory(1,size,0)
If *mem
ReadData(*mem,size)
CloseFile(0)
crc = CRC32compute(*mem,size)
MessageRequester("CRC",Hex(crc),0)
Else
MessageRequester("error","Not enough memory for file",0)
EndIf
Else
MessageRequester("Error","File not found",0)
EndIf
EndIf
EndIf
End

;------------------------------

Horst
PureBasic Explorer
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.

Nice, short and fully functional!
(As far as I can tell...)

Danke Horst


Have a nice day...
Franco

Sometimes you have to go a lonely way to accomplish genius things.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.
"Assembly Error - Please email this source..."
Joe B.
This error message comes on my computer only if 'inline-asm' in not enabled.

Therapy: ENABLE IT !

Some times an elecTRONics DOCtor needs a doctor itself


Have a nice day...
Franco

Sometimes you have to go a lonely way to accomplish genius things.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by TronDoc.

heh heh heh Thank You Franco...I may be an elecTRONics DOCtor, I've never claimed to be a programming Guru -jb

Edited by - TronDoc on 14 February 2002 08:31:08
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by horst.
I tried your code and kept having
include errors..
..I inserted ! on the ASM lines
which did not have them..

Joe B.
What kind of "include errors"?

Don't omit the "!"
Only without "!" the PureBasic variable names are
converted to the names used by the assembler.

horst
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by TronDoc.
What kind of "include errors"?
Don't omit the "!"
Only without "!" the PureBasic variable names are
converted to the names used by the assembler.
horst
my apologies Horst. I forgot to edit that out of my post.
Your code works AS IS in your posting. I just neglected
to enable the 'inline asm' function of the compiler and
was trying all kinds of ideas to get it to work on my own....

Edited by - TronDoc on 14 February 2002 08:27:20
Post Reply