Need help translating .net to PB

Just starting out? Need help? Post your questions and find answers here.
PureGuy
Enthusiast
Enthusiast
Posts: 101
Joined: Mon Aug 30, 2010 11:51 am

Need help translating .net to PB

Post by PureGuy »

Hi,
I'm trying to translate this code snipped:
http://stackoverflow.com/questions/1514 ... sing-crc32

I wonder why I get the error

"Line 27: Can't use any of the following operands with floats: <<, >>, &, |, !, %."

cause I don't use any floats?

Code: Select all

Structure Crc32table
  l.l[0]
EndStructure

Structure bytes
  b.b[0]
EndStructure

Global *table.Crc32table = AllocateMemory(256 * SizeOf(Long))
Global *revtable.Crc32table = AllocateMemory(256 * SizeOf(Long))

Global poly = $edb88320
Global startxor = $ffffffff


Procedure FixChecksum(*bytes.bytes, length, fixpos, wantcrc.l)
  
  Protected crc, i
  
  If (fixpos + 4 > length)
    ProcedureReturn 0
  EndIf
  
  crc = startxor
  For i = 0 To fixpos
    crc = Pow(crc >> 8, *table\l[Pow(crc, (*bytes\b[i] & $ff))] )
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
    
  crc = Pow(wantcrc, startxor)
  For i = (length - 1) To fixpos Step -1
    
    crc = Pow(crc << 8), (Pow, (revtable\l[crc >> (3 * 8)], *bytes[i])
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
  
EndProcedure

Procedure BuildCRC32Tables()
  
  Protected uint, fwd, rev, i, j
  
  For i = 0 To 255
    fwd = i
    rev = i << (3 * 8)
    
    For j = 8 To 0 Step -1
      
      If (fwd & 1) = 1
        fwd = Pow((fwd >> 1), poly)        
      Else
        fwd >> 1
      EndIf
      
      If (rev & $80000000) <> 0
        rev = (Pow(rev, poly) << 1) | 1
      Else
        rev << 1
      EndIf
    Next
    
    *table\l[i] = fwd
    *revtable\l[i] = rev
    
  Next
  
EndProcedure


wilbert
PureBasic Expert
PureBasic Expert
Posts: 3749
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need help translating .net to PB

Post by wilbert »

PureGuy wrote:cause I don't use any floats?
You used Pow which is a floating point procedure.
macOS 10.15 Catalina, Windows 10
PureGuy
Enthusiast
Enthusiast
Posts: 101
Joined: Mon Aug 30, 2010 11:51 am

Re: Need help translating .net to PB

Post by PureGuy »

Your right wilbert, Pow() was the problem.

But how else can I do a '^' operation from other languages in PB?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3749
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need help translating .net to PB

Post by wilbert »

'^' can be a confusing operator.
When you translate code from Visual Basic, '^' is used for exponentiation so you need something like Pow.
But when you translate code from C or C#, '^' is used for a xor operation which is the same as '!' in the PureBasic language.
So in this case you need '!'
macOS 10.15 Catalina, Windows 10
PureGuy
Enthusiast
Enthusiast
Posts: 101
Joined: Mon Aug 30, 2010 11:51 am

Re: Need help translating .net to PB

Post by PureGuy »

Thanks a lot wilbert, never had thought it would be a xor operation.
I got further, but it seams the last byte of every created CRC32 table entry is wrong

Code: Select all

Structure Crc32table
  l.l[0]
EndStructure

Structure bytes
  b.b[0]
EndStructure

Global *table.Crc32table = AllocateMemory(256 * SizeOf(Long))
Global *revtable.Crc32table = AllocateMemory(256 * SizeOf(Long))


Procedure FixChecksum(*bytes.bytes, length, fixpos, wantcrc.l)
  
  Protected crc.l, i, startxor.l = $ffffffff
  
  If (fixpos + 4 > length)
    ProcedureReturn 0
  EndIf
  
  crc = startxor
  For i = 0 To fixpos
    crc = (crc >> 8) ! *table\l[(crc ! *bytes\b[i]) & $ff]    
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
    
  crc = wantcrc ! startxor
  For i = (length - 1) To fixpos Step -1    
     crc = (crc << 8) ! *revtable\l[crc >> (3 * 8)] ! *bytes\b[i]
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
  
EndProcedure

Procedure BuildCRC32Tables(polynomial.l = $edb88320)
  
  Protected fwd.l, rev.l, i, j
  
  For i = 0 To 255
    fwd = i
    rev = i << (3 * 8)
    
    For j = 8 To 1 Step -1
      If (fwd & 1) = 1
        fwd = ((fwd >> 1) ! polynomial)
      Else
        fwd >> 1
      EndIf
      
      If (rev & $80000000) <> 0
        rev = ((rev ! polynomial) << 1) | 1
      Else
        rev << 1
      EndIf
    Next
    
    *table\l[i] = fwd
    *revtable\l[i] = rev
    
  Next
  
EndProcedure


BuildCRC32Tables()
ShowMemoryViewer(*table, MemorySize(*table))

; *buffer = AllocateMemory(512)
; RandomData(*buffer, 512)
; Debug Hex(CRC32Fingerprint(*buffer, 512), #PB_Long)
; FixChecksum(*buffer, MemorySize(*buffer), 4, $AABBCCDD)
; Debug Hex(CRC32Fingerprint(*buffer, 512), #PB_Long)
; 
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3749
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need help translating .net to PB

Post by wilbert »

PureGuy wrote:Thanks a lot wilbert, never had thought it would be a xor operation.
I got further, but it seams the last byte of every created CRC32 table entry is wrong
The original code used unsigned 32 bit integers while PB only supports signed 32 bit integers.
It's a limitation you will run into quite often when you want to port code from other languages. :(
You need to add masks to get the correct value or use a procedure which mimics a right shift on an unsigned integer.
Using masks it would be something like this (not tested)

Code: Select all

Structure Crc32table
  l.l[0]
EndStructure

Structure bytes
  b.b[0]
EndStructure

Global *table.Crc32table = AllocateMemory(256 * SizeOf(Long))
Global *revtable.Crc32table = AllocateMemory(256 * SizeOf(Long))


Procedure FixChecksum(*bytes.bytes, length, fixpos, wantcrc.l)
  
  Protected crc.l, i, startxor.l = $ffffffff
  
  If (fixpos + 4 > length)
    ProcedureReturn 0
  EndIf
  
  crc = startxor
  For i = 0 To fixpos
    crc = (crc >> 8 & $ffffff) ! *table\l[(crc ! *bytes\b[i]) & $ff]    
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
    
  crc = wantcrc ! startxor
  For i = (length - 1) To fixpos Step -1    
     crc = (crc << 8) ! *revtable\l[crc >> 24 & $ff] ! *bytes\b[i]
  Next
  
  CopyMemory(@crc, *bytes + fixpos, 4)
  
EndProcedure

Procedure BuildCRC32Tables(polynomial.l = $edb88320)
  
  Protected fwd.l, rev.l, i, j
  
  For i = 0 To 255
    fwd = i
    rev = i << (3 * 8)
    
    For j = 8 To 1 Step -1
      If (fwd & 1) = 1
        fwd = ((fwd >> 1 & $7fffffff) ! polynomial)
      Else
        fwd = fwd >> 1 & $7fffffff
      EndIf
      
      If (rev & $80000000) <> 0
        rev = ((rev ! polynomial) << 1) | 1
      Else
        rev << 1
      EndIf
    Next
    
    *table\l[i] = fwd
    *revtable\l[i] = rev
    
  Next
  
EndProcedure


BuildCRC32Tables()
ShowMemoryViewer(*table, MemorySize(*table))

; *buffer = AllocateMemory(512)
; RandomData(*buffer, 512)
; Debug Hex(CRC32Fingerprint(*buffer, 512), #PB_Long)
; FixChecksum(*buffer, MemorySize(*buffer), 4, $AABBCCDD)
; Debug Hex(CRC32Fingerprint(*buffer, 512), #PB_Long)
; 
macOS 10.15 Catalina, Windows 10
Post Reply