CRC校验类VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "CCRC32" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Option ExplicitPrivate Const mlPOLY As Long = &HEDB88320 ' starting reverse polynomial for the CRC table Private mlcrc32table(255) As Long ' table to hold our 256 itemsPrivate Const mclBlockSize As Long = (64 * 1024&) ' 64K buffer Private Const GENERIC_READ = &H80000000 Private Const FILE_SHARE_READ = &H1 Private Const FILE_SHARE_WRITE = &H2 Private Const FILE_SHARE_DELETE = &H4 Private Const FILE_ATTRIBUTE_NORMAL = &H0 Private Const OPEN_EXISTING = 3 Private Const INVALID_HANDLE_VALUE = -1 Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _ ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Byte, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPublic Event eProgress(ByVal iPercent As Integer)Private Sub CreateTable() Dim i As Long Dim j As Long Dim lCRC As Long For i = 1 To 255 lCRC = i j = 8 Do If (lCRC And 1) Then lCRC = ((lCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF lCRC = lCRC Xor mlPOLY Else lCRC = ((lCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF End If j = j - 1 Loop While j mlcrc32table(i) = lCRC Next i End Sub' pass an non-empty zero based array ' this function can be slightly faster than Forward, but of course yields different results. Public Function GetCRCFromArrayReverse(ByRef aInput() As Byte) As Long Dim lCRC As Long Dim lCounter As Long Dim lLookup As Long lCounter = UBound(aInput) lCRC = -1 Do lLookup = (lCRC And &HFF) Xor aInput(lCounter) lCRC = ((lCRC And &HFFFFFF00) \ &H100) And &HFFFFFF lCRC = lCRC Xor mlcrc32table(lLookup) lCounter = lCounter - 1 ' dec Loop While lCounter >= 0 ' jns GetCRCFromArrayReverse = Not lCRC End Function' Pass a zero based array ' lCrc is typically set to -1 (&HFFFFFFFF) to start ' The return of the function is fed back to lCrc for a progressive CRC32 ' This code can process in chunks, make sure to take the bitwise NOT of the return when (completely) done. Public Function GetCRCFromArrayForward(ByVal lCRC As Long, ByVal lStartOffset As Long, ByVal lLength As Long, ByRef aInput() As Byte) As Long Dim lLookup As Long Dim lMax As Long Dim lTemp As Long lMax = lStartOffset + lLength Do lLookup = (lCRC And &HFF) Xor aInput(lStartOffset) lCRC = ((lCRC And &HFFFFFF00) \ &H100) And &HFFFFFF ' nasty shr 8 with vb :/ lStartOffset = lStartOffset + 1 lCRC = lCRC Xor mlcrc32table(lLookup) Loop While lStartOffset < lMax GetCRCFromArrayForward = lCRC End FunctionPublic Function GetCRCFromFile(ByVal sFile As String) As Long Dim lCRC As Long, lFileHandle As Long, bData() As Byte, lRead As Long Dim lNumBlocks As Long Dim lTotalBlocks As Long lCRC = -1 lFileHandle = CreateFile(sFile, _ GENERIC_READ, _ FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE, _ 0, _ OPEN_EXISTING, _ FILE_ATTRIBUTE_NORMAL, _ 0) If lFileHandle <> INVALID_HANDLE_VALUE Then lTotalBlocks = (GetFileSize(lFileHandle, 0&) + mclBlockSize - 1) \ mclBlockSize lNumBlocks = 1 lRead = mclBlockSize Do While lRead = mclBlockSize And lNumBlocks <= lTotalBlocks ReDim bData(mclBlockSize - 1) As Byte ReadFile lFileHandle, bData(0), mclBlockSize, lRead, 0 If lRead < mclBlockSize Then ReDim Preserve bData(lRead - 1) As Byte lCRC = GetCRCFromArrayForward(lCRC, 0, lRead, bData) RaiseEvent eProgress(CInt((lNumBlocks / lTotalBlocks) * 100)) lNumBlocks = lNumBlocks + 1 Loop End If If lFileHandle <> INVALID_HANDLE_VALUE Then CloseHandle lFileHandle lFileHandle = INVALID_HANDLE_VALUE End If GetCRCFromFile = Not lCRC End FunctionPrivate Sub Class_Initialize() Call CreateTable End Sub
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "CCRC32"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option ExplicitPrivate Const mlPOLY As Long = &HEDB88320 ' starting reverse polynomial for the CRC table
Private mlcrc32table(255) As Long ' table to hold our 256 itemsPrivate Const mclBlockSize As Long = (64 * 1024&) ' 64K buffer
Private Const GENERIC_READ = &H80000000
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const FILE_SHARE_DELETE = &H4
Private Const FILE_ATTRIBUTE_NORMAL = &H0
Private Const OPEN_EXISTING = 3
Private Const INVALID_HANDLE_VALUE = -1
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Byte, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPublic Event eProgress(ByVal iPercent As Integer)Private Sub CreateTable()
Dim i As Long
Dim j As Long
Dim lCRC As Long
For i = 1 To 255
lCRC = i
j = 8
Do
If (lCRC And 1) Then
lCRC = ((lCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
lCRC = lCRC Xor mlPOLY
Else
lCRC = ((lCRC And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
End If
j = j - 1
Loop While j
mlcrc32table(i) = lCRC
Next i
End Sub' pass an non-empty zero based array
' this function can be slightly faster than Forward, but of course yields different results.
Public Function GetCRCFromArrayReverse(ByRef aInput() As Byte) As Long
Dim lCRC As Long
Dim lCounter As Long
Dim lLookup As Long
lCounter = UBound(aInput)
lCRC = -1
Do
lLookup = (lCRC And &HFF) Xor aInput(lCounter)
lCRC = ((lCRC And &HFFFFFF00) \ &H100) And &HFFFFFF
lCRC = lCRC Xor mlcrc32table(lLookup)
lCounter = lCounter - 1 ' dec
Loop While lCounter >= 0 ' jns
GetCRCFromArrayReverse = Not lCRC
End Function' Pass a zero based array
' lCrc is typically set to -1 (&HFFFFFFFF) to start
' The return of the function is fed back to lCrc for a progressive CRC32
' This code can process in chunks, make sure to take the bitwise NOT of the return when (completely) done.
Public Function GetCRCFromArrayForward(ByVal lCRC As Long, ByVal lStartOffset As Long, ByVal lLength As Long, ByRef aInput() As Byte) As Long
Dim lLookup As Long
Dim lMax As Long
Dim lTemp As Long
lMax = lStartOffset + lLength
Do
lLookup = (lCRC And &HFF) Xor aInput(lStartOffset)
lCRC = ((lCRC And &HFFFFFF00) \ &H100) And &HFFFFFF ' nasty shr 8 with vb :/
lStartOffset = lStartOffset + 1
lCRC = lCRC Xor mlcrc32table(lLookup)
Loop While lStartOffset < lMax
GetCRCFromArrayForward = lCRC
End FunctionPublic Function GetCRCFromFile(ByVal sFile As String) As Long
Dim lCRC As Long, lFileHandle As Long, bData() As Byte, lRead As Long
Dim lNumBlocks As Long
Dim lTotalBlocks As Long
lCRC = -1
lFileHandle = CreateFile(sFile, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE, _
0, _
OPEN_EXISTING, _
FILE_ATTRIBUTE_NORMAL, _
0)
If lFileHandle <> INVALID_HANDLE_VALUE Then
lTotalBlocks = (GetFileSize(lFileHandle, 0&) + mclBlockSize - 1) \ mclBlockSize
lNumBlocks = 1
lRead = mclBlockSize
Do While lRead = mclBlockSize And lNumBlocks <= lTotalBlocks
ReDim bData(mclBlockSize - 1) As Byte
ReadFile lFileHandle, bData(0), mclBlockSize, lRead, 0
If lRead < mclBlockSize Then ReDim Preserve bData(lRead - 1) As Byte
lCRC = GetCRCFromArrayForward(lCRC, 0, lRead, bData)
RaiseEvent eProgress(CInt((lNumBlocks / lTotalBlocks) * 100))
lNumBlocks = lNumBlocks + 1
Loop
End If
If lFileHandle <> INVALID_HANDLE_VALUE Then
CloseHandle lFileHandle
lFileHandle = INVALID_HANDLE_VALUE
End If
GetCRCFromFile = Not lCRC
End FunctionPrivate Sub Class_Initialize()
Call CreateTable
End Sub