Page 1 of 1

Fletcher16-32 Checksum

Posted: Tue Feb 21, 2012 4:37 am
by Guimauve
Hello everyone,

The Fletcher 16 and 32 Checksum algorithm. Source : http://en.wikipedia.org/wiki/Fletcher%27s_checksum

Edit V1.0.1 : A little optimisation.
Edit V1.0.2 : Bug correction

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Fletcher 16 and 32 Checksum
; File Name : Fletcher16-32.pb
; File version: 1.0.2
; Programming : OK
; Programmed by : Guimauve
; Date : 20-02-2012
; Last Update : 09-03-2012
; PureBasic code : 4.60
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes about Fletcher 16 and 32
;
; Source : http://en.wikipedia.org/wiki/Fletcher%27s_checksum
;
; In Ascii mode :
;
;   Fletcher16("Wikipedia") = 61082
;   Fletcher16("Wikipedia") = EE9A (Hexa)
;   Fletcher32("Wikipedia") = 299697047
;   Fletcher32("Wikipedia") = 11DD0397 (Hexa)
;
; In Unicode mode :
;
;   Fletcher16("Wikipedia") = 56730
;   Fletcher16("Wikipedia") = DD9A (Hexa)
;   Fletcher32("Wikipedia") = 599393175
;   Fletcher32("Wikipedia") = 23BA0397 (Hexa)
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Shortcut like C/C++ language <<<<<
; <<<<< int c1 = (x0 > y0) ? 32 : 0; <<<<<

Macro Interrogation(Variable, Test, If_True, If_False)
  
  If Test
    Variable = (If_True)
  Else 
    Variable = (If_False)
  EndIf 
  
EndMacro

Procedure Fletcher16(*Buffer.Ascii, BufferSize.l)
  
  Sum_01.u = 0
  Sum_02.u = 0
  
  For Index = 1 To BufferSize
    
    Sum_01 = (Sum_01 + *Buffer\a) % 255
    Sum_02 = (Sum_01 + Sum_02) % 255
    *Buffer + 1
    
  Next
  
  ProcedureReturn (Sum_02 << 8) | Sum_01
EndProcedure

Procedure Fletcher32(*Buffer.Ascii, BufferSize.l)
  
  Sum_01.i = $ffff
  Sum_02.i = $ffff
  
  While BufferSize
    
    Interrogation(tLen, BufferSize > 360, 360, BufferSize)
    BufferSize - tLen
    
    Repeat
      
      Sum_01 = Sum_01 + *Buffer\a
      Sum_02 = Sum_02 + Sum_01
      *Buffer + 1
      tLen - 1
      
    Until tLen = 0
    
    Sum_01 = (Sum_01 & $ffff) + (Sum_01 >> 16)
    Sum_02 = (Sum_02 & $ffff) + (Sum_02 >> 16)
    
  Wend
  
  Sum_01 = (Sum_01 & $ffff) + (Sum_01 >> 16)
  Sum_02 = (Sum_02 & $ffff) + (Sum_02 >> 16)
  
  ProcedureReturn (Sum_02 << 16 | Sum_01)
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
; <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<< 
; <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<< 
; <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<< 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

String.s = "Wikipedia"
length = StringByteLength(String)

Checksum16 = Fletcher16(@String, length)
Checksum32 = Fletcher32(@String, length)

Debug "Fletcher16(" + Chr(34) + String + Chr(34) + ") = " + Str(Checksum16)
Debug "Fletcher16(" + Chr(34) + String + Chr(34) + ") = " + Hex(Checksum16) + " (Hexa)"

Debug "Fletcher32(" + Chr(34) + String + Chr(34) + ") = " + Str(Checksum32)
Debug "Fletcher32(" + Chr(34) + String + Chr(34) + ") = " + Hex(Checksum32) + " (Hexa)"

Debug ""
Debug "*******************************************************"
Debug ""

LargeBuffer = AllocateMemory(10000)
FillMemory(LargeBuffer, MemorySize(LargeBuffer), 123456, #PB_Long)

Checksum16 = Fletcher16(LargeBuffer, MemorySize(LargeBuffer))
Checksum32 = Fletcher32(LargeBuffer, MemorySize(LargeBuffer))

Debug "Fletcher16(LargeBuffer) = " + Str(Checksum16)
Debug "Fletcher16(LargeBuffer) = " + Hex(Checksum16) + " (Hexa)"

Debug "Fletcher32(LargeBuffer) = " + Str(Checksum32)
Debug "Fletcher32(LargeBuffer) = " + Hex(Checksum32) + " (Hexa)"

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
Guimauve

Re: Fletcher16-32 Checksum

Posted: Thu Mar 08, 2012 12:07 pm
by wilbert
@Guimauve, something isn't right.
The Fletcher32 checksum for "Wikipedia" should be 11DD0397 (hex result for ascii mode)
( http://www.nitrxgen.net/hashgen/ )

Re: Fletcher16-32 Checksum

Posted: Thu Mar 08, 2012 1:52 pm
by infratec
Hi,

the 'corrected' version:

Code: Select all

Procedure.l Fletcher32(*Buffer, BufferSize.i)
  
  Protected.l Sum_01, Sum_02
  Protected tLen.i
  
  Sum_01 = $ffff
  Sum_02 = $ffff
 
  While BufferSize
   
    If BufferSize > 360
      tLen = 360
    Else
      tLen = BufferSize
    EndIf
    
    BufferSize - tLen
   
    Repeat
      Sum_01 + PeekA(*Buffer)
      *Buffer + 1
      Sum_02 + Sum_01
      tLen - 1
    Until tLen = 0
   
    Sum_01 = (Sum_01 & $ffff) + (Sum_01 >> 16)
    Sum_02 = (Sum_02 & $ffff) + (Sum_02 >> 16)
   
  Wend
 
  Sum_01 = (Sum_01 & $ffff) + (Sum_01 >> 16)
  Sum_02 = (Sum_02 & $ffff) + (Sum_02 >> 16)
 
  ProcedureReturn (Sum_02 << 16 | Sum_01)
EndProcedure
It works now like wilberts test page.
The problem is, that the wikipediacode is only for an even buffersize.
So there should be a check for this.
I don't know if all fletcher32() implementations results are identical for this reason.

Bernd