Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
CRC32 returns negative on big files
Message
From
30/07/2011 03:32:11
 
 
To
29/07/2011 15:22:42
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
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:
01519682
Views:
42
>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.

From the algorithm it looks as if you could easily end up with a negative result regardless of file size.
I don't know the inner workings of the calculation but, since it is essentially a bitwise operation, why do you thing negative int representations are invalid (you don't show any usage of the nCRC32 return value) ?

Also, for larger files why not use a larger buffer ?

See you're still not using OPTION STRICT :-}
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform