Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
CRC32 returns negative on big files
Message
From
29/07/2011 15:22:42
 
 
To
All
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
Title:
CRC32 returns negative on big files
Environment versions
Environment:
VB 9.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Web
Miscellaneous
Thread ID:
01519635
Message ID:
01519635
Views:
101
I have this class which returns a CRC32:
Imports System.IO

Namespace Framework

    Public Class CRC32

        Public cMessage As String = ""
        Public cFileName As String = ""
        Public lLogError As Boolean = True
        Public nCRC32 As Integer = 0
        Public oApp As Framework.App
        Private cFileDoesNotExist As String = ""
        Private nBufferSize As Integer = 1024
        Private nCRC32Table() As Integer
        Private nLanguage As Integer = 0
        Private oProcess As Framework.LXProcess

        ' This is when we access the data provider in desktop and Web service mode
        Sub New(ByVal toApplication As Framework.App)
            oApp = toApplication
            nLanguage = oApp.nLanguage
            Init()
            Initialize()
        End Sub

        ' This is when we access the data provider in a Web mode
        Public Sub New(ByVal toProcess As Framework.LXProcess)
            oProcess = toProcess
            oApp = oProcess.oApp
            nLanguage = oProcess.nLanguage
            Init()
            Initialize()
        End Sub

        Private Function Init() As Boolean

            ' Based on the language
            Select Case nLanguage

                ' English
                Case 1
                    cFileDoesNotExist = "The file ##File## does not exist."

                    ' French
                Case 2
                    cFileDoesNotExist = "Le fichier ##File## n'existe pas."

                    ' Spanish
                Case 3
                    cFileDoesNotExist = "The file ##File## does not exist."

                    ' Portuguese
                Case 4
                    cFileDoesNotExist = "The file ##File## does not exist."

            End Select

            Return True
        End Function

        ' This is the official polynomial used by CRC32 in PKZip.
        ' Often the polynomial is shown reversed (04C11DB7).
        ' Initialize
        Private Function Initialize() As Boolean
            Dim lnDWPolynomial As Integer = &HEDB88320
            Dim lnCounter As Integer = 0
            Dim lnCounter2 As Integer = 0
            ReDim nCRC32Table(256)
            Dim lnDWCRC As Integer

            For lnCounter = 0 To 255
                lnDWCRC = lnCounter

                For lnCounter2 = 8 To 1 Step -1

                    If (lnDWCRC And 1) Then
                        lnDWCRC = ((lnDWCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                        lnDWCRC = lnDWCRC Xor lnDWPolynomial
                    Else
                        lnDWCRC = ((lnDWCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                    End If

                Next

                nCRC32Table(lnCounter) = lnDWCRC
            Next

            Return True
        End Function

        ' This is the main method to call
        Public Function GetCRC() As Boolean
            Dim lcMessage As String = ""
            Dim lnCounter As Integer = 0
            Dim lnDelay As Integer = 250
            Dim lnRetry As Integer = 8
            Dim loStream As Stream = Nothing

            ' Reset the values
            cMessage = ""
            nCRC32 = 0

            For lnCounter = 1 To lnRetry

                Try

                    ' If the file exists
                    If oApp.FileExist(cFileName) Then
                        loStream = New FileStream(cFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
                    Else
                        lcMessage = oApp.StrTran(cFileDoesNotExist, "##File##", cFileName)

                        ' If we log the error
                        If lLogError Then

                            ' Get the proper definition as per the current scope
                            If oProcess Is Nothing Then
                                oApp.ErrorSetup(, "CRC32: " + lcMessage)
                            Else
                                oProcess.ErrorSetup(, "CRC32: " + lcMessage)
                            End If

                        Else
                            Return False
                        End If

                    End If

                    Exit For

                Catch loError As Exception

                    ' If we have not reached the maximum tries of 8, we retry
                    If lnCounter < 8 Then

                        ' Wait for a timeout before retrying
                        System.Threading.Thread.Sleep(lnDelay)

                        Continue For
                    End If

                    ' If we log the error
                    If lLogError Then

                        ' Get the proper definition as per the current scope
                        If oProcess Is Nothing Then
                            oApp.ErrorSetup(loError)
                        Else
                            oProcess.ErrorSetup(loError)
                        End If

                    Else
                        cMessage = loError.Message
                    End If

                End Try

            Next

            nCRC32 = GetCrc32(loStream)
            loStream.Close()
            Return True
        End Function

        Private Function GetCrc32(ByRef toStream As System.IO.Stream) As Integer
            Dim lnCRC32Result As Integer = &HFFFFFFFF
            Dim loBuffer(nBufferSize) As Byte
            Dim lnReadSize As Integer = nBufferSize
            Dim lnCount As Integer = 0
            Dim lnCounter As Integer = 0
            Dim lnLookup As Integer = 0

            lnCount = toStream.Read(loBuffer, 0, lnReadSize)
            Do While lnCount > 0
                For lnCounter = 0 To lnCount - 1
                    lnLookup = (lnCRC32Result And &HFF) Xor loBuffer(lnCounter)

                    ' Nasty shr 8 with vb :/
                    lnCRC32Result = ((lnCRC32Result And &HFFFFFF00) \ &H100) And 16777215

                    lnCRC32Result = lnCRC32Result Xor nCRC32Table(lnLookup)
                Next
                lnCount = toStream.Read(loBuffer, 0, lnReadSize)
            Loop

            Return Not lnCRC32Result
        End Function

    End Class

End Namespace
So, on files which are about lower than 5 MB, I get the proper result. For files which are bigger, I get a negative value, which, of course, doesn't match the proper CRC32 of the file. Could it be that I would have to change the declaration to a double instead of an integer, in cases where I have big numbers? I am wondering if this could be the problem.
Michel Fournier
Level Extreme Inc.
Designer, architect, owner of the Level Extreme Platform
Subscribe to the site at https://www.levelextreme.com/Home/DataEntry?Activator=55&NoStore=303
Subscription benefits https://www.levelextreme.com/Home/ViewPage?Activator=7&ID=52
Next
Reply
Map
View

Click here to load this message in the networking platform