PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
CRC32 calculation code-VBForums
Results 1 to 9 of 9

Thread: CRC32 calculation code

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Oct 2008
    Posts
    994

    CRC32 calculation code

    This code calculates the CRC32 of a byte array. Put it in a module, and you can use it anywhere in your program.

    Code:
    Dim Table(255) As Long
    Dim RunOnce As Boolean
    Dim TableReady As Boolean
    
    Public Function CRC32(ByRef Data() As Byte) As Long
        Dim Remainder As Long
        Dim i As Long
        Dim j As Long
        
        If RunOnce = False Then 'Check if the table has already been generated.
            RunOnce = True
            For i = 0 To 255
                Remainder = i
                For j = 0 To 7
                    If Remainder And 1 Then
                        Remainder = ShiftRight(Remainder) Xor &HEDB88320
                    Else
                        Remainder = ShiftRight(Remainder)
                    End If
                Next j
                Table(i) = Remainder
            Next i
            TableReady = True
        End If
        If TableReady = False Then Exit Function 'Check if table calculation has started, but not completed, on another thread.
        
        
        'Calculate CRC32 of data.
        CRC32 = &HFFFFFFFF
        For i = 0 To UBound(Data)
            CRC32 = ShiftRight8(CRC32) Xor Table((CRC32 And &HFF&) Xor Data(i))
        Next i
        CRC32 = Not CRC32
    End Function
    
    
    Private Function ShiftRight(ByVal Value As Long) As Long
        Dim TopBit As Boolean
        TopBit = Value And &H80000000
        ShiftRight = (Value And &H7FFFFFFF) \ 2
        If TopBit Then ShiftRight = ShiftRight Or &H40000000
    End Function
    
    Private Function ShiftRight8(ByVal Value As Long) As Long
        ShiftRight8 = ShiftRight(Value)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
        ShiftRight8 = ShiftRight(ShiftRight8)
    End Function
    If you read the comments on the code, you will see that I used some checks to attempt to make it thread safe, but given that VB6 has trouble running other threads, there's no guaranty that it won't crash completely if used from a thread other than the main thread. I haven't tested it yet myself in a multithreaded VB6 program.

    Also, this code I wrote is a VB6 port of the C code for CRC32 shown at https://rosettacode.org/wiki/CRC-32#C though I had to eliminate pointers and also write my own ShiftRight functions, due to VB6 lacking these features. I'm not sure what license attaches to my code I'm posting here, as it is a port of somebody else's code (though not letter-by-letter identical). My intent is to make it public domain, but that might not be possible if the original C code has a license attached to it that states that derivatives must also carry the same license.
    Last edited by Ben321; Dec 10th, 2019 at 02:17 AM.

  2. #2
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,720

    Re: CRC32 calculation code

    FYI, here is a faster version of ShiftRight8

    thinBasic Code:
    1. Private Function ShiftRight8(ByVal Value As Long) As Long
    2.     Dim TopBit As Boolean
    3.     TopBit = Value And &H80000000
    4.     ShiftRight8 = (Value And &H7FFFFFFF) \ 256
    5.     If TopBit Then ShiftRight8 = ShiftRight8 Or &H800000
    6. End Function
    cheers,
    </wqw>

  3. #3
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,720

    Re: CRC32 calculation code

    Here is a small benchmark I did of present ShiftRight8 (A_CRC32) against the new ShiftRight8 (B_CRC32) against cZipArchive class native C implementation (C_CRC32).



    cheers,
    </wqw>

  4. #4

  5. #5
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,720

    Re: CRC32 calculation code

    Quote Originally Posted by The trick View Post
    RtlComputeCrc32
    Benchmark updated. API performance is mid-point between pure VB6 impl of the same 1-byte step algorithm and libdeflate's crc32_slice4 version in cZipArchive class that computes 4-bytes per loop and uses larger 4KB pre-computed table.

    cheers,
    </wqw>

  6. #6

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Oct 2008
    Posts
    994

    Re: CRC32 calculation code

    Quote Originally Posted by wqweto View Post
    Here is a small benchmark I did of present ShiftRight8 (A_CRC32) against the new ShiftRight8 (B_CRC32) against cZipArchive class native C implementation (C_CRC32).



    cheers,
    </wqw>

    So what is D_CRC32 in that picture? Is that your own personal implementation of CRC32, that you wish to keep undocumented/proprietary for business reasons, so you intentionally avoided specifying exactly what D_CRC32 was in the caption?

  8. #8
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,562

    Re: CRC32 calculation code

    You can check the source code wqweto linked to see what it is - D_Crc32 is RtlComputeCrc32. It's a proprietary closed source undocumented function, but it's from Microsoft. The declaration:

    Code:
    Private Declare Function RtlComputeCrc32 Lib "ntdll" (ByVal dwInitial As Long, pData As Any, ByVal iLen As Long) As Long
    Some more info: https://weekly-geekly.github.io/arti...287/index.html

  9. #9
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,720

    Re: CRC32 calculation code

    Quote Originally Posted by jpbro View Post
    It's a proprietary closed source undocumented function, but it's from Microsoft.
    My evil master-plan is foiled now that the source code leaked! :-))
    Code:
     ULONG NTAPI
     RtlComputeCrc32(IN ULONG Initial,
                     IN PUCHAR Data,
                     IN ULONG Length)
     {
       ULONG CrcValue = ~Initial;
     
       DPRINT("(%u,%p,%u)\n", Initial, Data, Length);
     
       while (Length > 0)
       {
         CrcValue = CrcTable[(CrcValue ^ *Data) & 0xff] ^ (CrcValue >> 8);
         Data++;
         Length--;
       }
       return ~CrcValue;
     }
    cheers,
    </wqw>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width