PowerBASIC Forums
  Source Code
  Adler-32 checksum

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   Adler-32 checksum
Wayne Diamond
Member
posted March 20, 2002 09:35 PM     Click Here to See the Profile for Wayne Diamond     Edit/Delete Message   Reply w/Quote
Adler-32 (by Mark Adler) is a checksum algorithm used by ZIP files that is some 33% faster than CRC32. My port might not be that fast as it's not assembly, but it's returning the correct values!

#COMPILE EXE  'PBCC.  Replace STDOUT with MSGBOX to compile in PBDLL
#INCLUDE "win32api.inc"

FUNCTION Adler32(sBuffer AS STRING) AS LONG
DIM Seed AS LONG
DIM S1 AS LONG
DIM S2 AS LONG
DIM N AS LONG
%CrcBase = 65521
Seed = 1
S1 = Seed AND &HFFFF
S2 = (Seed / 65536) AND &HFFFF
FOR N = 1 TO LEN(sBuffer)
S1 = (S1 + ASC(MID$(sBuffer, N,1))) MOD %CrcBase
S2 = (S2 + S1) MOD %CrcBase
NEXT
Adler32 = (S2 * 65536) + S1
END FUNCTION

FUNCTION PBMAIN() AS LONG
ON ERROR RESUME NEXT
DIM TestBuffer AS STRING
DIM Adler AS LONG
TestBuffer = CHR$(17) & CHR$(34) & CHR$(51)
Adler = Adler32(TestBuffer)
IF Adler = 11337831 THEN
STDOUT "Calculated correctly"
ELSE
STDOUT "Calculation failed"
END IF
STDOUT "Adler=" & STR$(Adler)
'WAITKEY$
END FUNCTION

------------------

IP: Logged

Wayne Diamond
Member
posted March 20, 2002 09:42 PM     Click Here to See the Profile for Wayne Diamond     Edit/Delete Message   Reply w/Quote
And here is another simple checksum algorithm designed for speed. The C++ bit shifting has got me a bit confused so if anyone else wants to port it, the challenge is all theirs
It was developed by Sami J. Mäkinen (sjm@pp.inet.fi)
quote:
The goal was to have extremely high speed in 32-bit Pentium platform.

The algorithm is very simple, it works on 32-bit words and requires
2 ADDS, 3 SHIFTS and 1 XOR for one 32-bit word. The core is easy to
represent in C-code:

uint32 *buffer;
uint32 i, tmp;
sum = 1;

for ( i = 0; i < n; i++ )
{
tmp = buffer[i];
tmp = (uint32) (sum >> 29) + tmp;
tmp = (uint32) (sum >> 17) + tmp;
sum = (uint32) (sum << 3) ^ tmp;
}
return sum;

quote:
My C-code implementation is about 33% faster than Adler32 and 5 times
as fast as CRC32.

------------------

IP: Logged

Torsten Rienow
Member
posted March 21, 2002 06:08 AM     Click Here to See the Profile for Torsten Rienow     Edit/Delete Message   Reply w/Quote
Wayne, try this for speed and correctness.
If it works, add a favour for me .

regards,

Torsten


#Compile Exe
'No range testing or buffer address validation, just the algorithm
Function CRC_ASM_FOR_WAYNE(ByRef lpBuffer As Dword Ptr, ByVal lBuffer As Dword) As Dword
#Register None
Dim sum As Dword
!LEA EAX, sum
!MOV DWORD PTR [EAX], 1
!MOV EDI, lBuffer
!SHR EDI, 2
!MOV ECX, lpBuffer
!XOR EDX, EDX
NextDWord:
!MOV EDX, [ECX]
!MOV ESI, [EAX]
!PUSH ESI
!PUSH ESI
!SHR ESI, 29
!ADD EDX, ESI
!POP ESI
!SHR ESI, 17
!ADD EDX, ESI
!POP ESI
!SHL ESI, 3
!XOR ESI, EDX
!MOV DWORD PTR [EAX], ESI
!ADD ECX, 4
!DEC EDI
!JNZ NextDWord
!MOV EAX, [EAX]
GetOut:
!MOV Function, EAX
End Function

Function PbMain

Dim l As Long
l = 1
MsgBox Str$( CRC_ASM_FOR_WAYNE(ByVal VarPtr(l), 4))

End Function

------------------


[This message has been edited by Torsten Rienow (edited March 21, 2002).]

IP: Logged

Wayne Diamond
Member
posted July 11, 2002 01:37 AM     Click Here to See the Profile for Wayne Diamond     Edit/Delete Message   Reply w/Quote
i ported Adler32 over to PB inline asm for a bit of extra speed
FUNCTION Adler32asm(sBuffer AS STRING) AS LONG
#REGISTER NONE
DIM Seed AS LONG, S1 AS LONG, S2 AS LONG, N AS LONG
DIM sPtr AS LONG
sPtr = STRPTR(sBuffer) - 1
N = LEN(sBuffer) + sPtr
'// S1 = Seed AND &HFFFF
! mov Seed, 1
! xor eax, eax
! add eax, Seed
! mov ebx, eax
! and eax, &hFFFF
! mov eax, ebx
! mov S1, eax
'// S2 = (Seed / 65536) AND &HFFFF
! mov eax, Seed
! mov ebx, &h10000
! xor edx, edx
! div ebx
! and eax, &hFFFF
! mov S2, eax
! mov ecx, sPtr
StartLoop: '// FOR N = 1 TO LEN(sBuffer)
! inc ecx
! cmp ecx, N
! jg EndLoop
'//S1 = (S1 + ASC(MID$(sBuffer, N,1))) MOD %CrcBase
! mov eax, S1
! xor ebx, ebx
! mov bl, [ecx]
! add eax, ebx
! mov ebx, &hFFF1
! xor edx, edx
! div ebx
! mov S1, edx
'//S2 = (S2 + S1) MOD %CrcBase
! mov eax, S2
! add eax, S1
! mov ebx, &hFFF1
! xor edx, edx
! div ebx
! mov S2, edx
! jmp StartLoop ;// NEXT
EndLoop:
'// FUNCTION = (S2 * 65536) + S1
! mov eax, S2
! mov ecx, &h10000
! mul ecx
! add eax, S1
! mov N, eax
FUNCTION = N
END FUNCTION


See http://www.wanet.com.au/~diamond/pbcrypto/view.php?algorithm=adler32 for more details

------------------
The PowerBASIC Crypto Archives

IP: Logged

All times are EasternTime (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | PowerBASIC BASIC Compilers

Copyright © 1999-2005 PowerBASIC, Inc. All Rights Reserved.


Ultimate Bulletin Board 5.45c