|
#If Not %def(%WINAPI)
#Include Once "win32api.inc"
#EndIf
'翻译自C++代码 http://blog.csdn.net/barenx/archive/2008/03/30/2230053.aspx
%MAX_BUFFER_SIZE = &H1000
Class CCrc32Dynamic
Instance s_arrdwCrc32Table() As Dword
Class Method Create
ReDim s_arrdwCrc32Table(256) As Instance Dword
Array Assign s_arrdwCrc32Table() = _
&H000000000, &H077073096, &H0EE0E612C, &H0990951BA, _
&H0076DC419, &H0706AF48F, &H0E963A535, &H09E6495A3, _
&H00EDB8832, &H079DCB8A4, &H0E0D5E91E, &H097D2D988, _
&H009B64C2B, &H07EB17CBD, &H0E7B82D07, &H090BF1D91, _
&H01DB71064, &H06AB020F2, &H0F3B97148, &H084BE41DE, _
&H01ADAD47D, &H06DDDE4EB, &H0F4D4B551, &H083D385C7, _
&H0136C9856, &H0646BA8C0, &H0FD62F97A, &H08A65C9EC, _
&H014015C4F, &H063066CD9, &H0FA0F3D63, &H08D080DF5, _
&H03B6E20C8, &H04C69105E, &H0D56041E4, &H0A2677172, _
&H03C03E4D1, &H04B04D447, &H0D20D85FD, &H0A50AB56B, _
&H035B5A8FA, &H042B2986C, &H0DBBBC9D6, &H0ACBCF940, _
&H032D86CE3, &H045DF5C75, &H0DCD60DCF, &H0ABD13D59, _
&H026D930AC, &H051DE003A, &H0C8D75180, &H0BFD06116, _
&H021B4F4B5, &H056B3C423, &H0CFBA9599, &H0B8BDA50F, _
&H02802B89E, &H05F058808, &H0C60CD9B2, &H0B10BE924, _
&H02F6F7C87, &H058684C11, &H0C1611DAB, &H0B6662D3D, _
&H076DC4190, &H001DB7106, &H098D220BC, &H0EFD5102A, _
&H071B18589, &H006B6B51F, &H09FBFE4A5, &H0E8B8D433, _
&H07807C9A2, &H00F00F934, &H09609A88E, &H0E10E9818, _
&H07F6A0DBB, &H0086D3D2D, &H091646C97, &H0E6635C01, _
&H06B6B51F4, &H01C6C6162, &H0856530D8, &H0F262004E, _
&H06C0695ED, &H01B01A57B, &H08208F4C1, &H0F50FC457, _
&H065B0D9C6, &H012B7E950, &H08BBEB8EA, &H0FCB9887C, _
&H062DD1DDF, &H015DA2D49, &H08CD37CF3, &H0FBD44C65, _
&H04DB26158, &H03AB551CE, &H0A3BC0074, &H0D4BB30E2, _
&H04ADFA541, &H03DD895D7, &H0A4D1C46D, &H0D3D6F4FB, _
&H04369E96A, &H0346ED9FC, &H0AD678846, &H0DA60B8D0, _
&H044042D73, &H033031DE5, &H0AA0A4C5F, &H0DD0D7CC9, _
&H05005713C, &H0270241AA, &H0BE0B1010, &H0C90C2086, _
&H05768B525, &H0206F85B3, &H0B966D409, &H0CE61E49F, _
&H05EDEF90E, &H029D9C998, &H0B0D09822, &H0C7D7A8B4, _
&H059B33D17, &H02EB40D81, &H0B7BD5C3B, &H0C0BA6CAD, _
&H0EDB88320, &H09ABFB3B6, &H003B6E20C, &H074B1D29A, _
&H0EAD54739, &H09DD277AF, &H004DB2615, &H073DC1683, _
&H0E3630B12, &H094643B84, &H00D6D6A3E, &H07A6A5AA8, _
&H0E40ECF0B, &H09309FF9D, &H00A00AE27, &H07D079EB1, _
&H0F00F9344, &H08708A3D2, &H01E01F268, &H06906C2FE, _
&H0F762575D, &H0806567CB, &H0196C3671, &H06E6B06E7, _
&H0FED41B76, &H089D32BE0, &H010DA7A5A, &H067DD4ACC, _
&H0F9B9DF6F, &H08EBEEFF9, &H017B7BE43, &H060B08ED5, _
&H0D6D6A3E8, &H0A1D1937E, &H038D8C2C4, &H04FDFF252, _
&H0D1BB67F1, &H0A6BC5767, &H03FB506DD, &H048B2364B, _
&H0D80D2BDA, &H0AF0A1B4C, &H036034AF6, &H041047A60, _
&H0DF60EFC3, &H0A867DF55, &H0316E8EEF, &H04669BE79, _
&H0CB61B38C, &H0BC66831A, &H0256FD2A0, &H05268E236, _
&H0CC0C7795, &H0BB0B4703, &H0220216B9, &H05505262F, _
&H0C5BA3BBE, &H0B2BD0B28, &H02BB45A92, &H05CB36A04, _
&H0C2D7FFA7, &H0B5D0CF31, &H02CD99E8B, &H05BDEAE1D, _
&H09B64C2B0, &H0EC63F226, &H0756AA39C, &H0026D930A, _
&H09C0906A9, &H0EB0E363F, &H072076785, &H005005713, _
&H095BF4A82, &H0E2B87A14, &H07BB12BAE, &H00CB61B38, _
&H092D28E9B, &H0E5D5BE0D, &H07CDCEFB7, &H00BDBDF21, _
&H086D3D2D4, &H0F1D4E242, &H068DDB3F8, &H01FDA836E, _
&H081BE16CD, &H0F6B9265B, &H06FB077E1, &H018B74777, _
&H088085AE6, &H0FF0F6A70, &H066063BCA, &H011010B5C, _
&H08F659EFF, &H0F862AE69, &H0616BFFD3, &H0166CCF45, _
&H0A00AE278, &H0D70DD2EE, &H04E048354, &H03903B3C2, _
&H0A7672661, &H0D06016F7, &H04969474D, &H03E6E77DB, _
&H0AED16A4A, &H0D9D65ADC, &H040DF0B66, &H037D83BF0, _
&H0A9BCAE53, &H0DEBB9EC5, &H047B2CF7F, &H030B5FFE9, _
&H0BDBDF21C, &H0CABAC28A, &H053B39330, &H024B4A3A6, _
&H0BAD03605, &H0CDD70693, &H054DE5729, &H023D967BF, _
&H0B3667A2E, &H0C4614AB8, &H05D681B02, &H02A6F2B94, _
&H0B40BBE37, &H0C30C8EA1, &H05A05DF1B, &H02D02EF8D
End Method
Class Method Destroy
Erase s_arrdwCrc32Table()
End Method
Interface ICrc32Dynamic : Inherit IUnknown
Method CalcCrc32(ByVal bByte As Byte, ByRef dwCrc32 As Dword)
dwCrc32 = Int((dwCrc32) / (2 ^ 8)) Xor s_arrdwCrc32Table((bByte) Xor ((dwCrc32) And &H000000FF))
End Method
Method StringCrc32(ByVal szString As String, ByRef dwCrc32 As Dword)
Local i As Long
Local bByte As Byte Ptr
dwCrc32 = &HFFFFFFFF
bByte = StrPtr(szString)
For i = 0 To Len(szString) - 1
Me.CalcCrc32(@bByte, dwCrc32)
Next i
dwCrc32 = dwCrc32 Xor &HFFFFFFFF
End Method
Method FileCrc32Assembly(ByVal szFilename As String, ByRef dwCrc32 As Dword) As Dword
Local dwErrorCode As Dword : dwErrorCode = %NO_ERROR
Local hFile As Long
dwCrc32 = &HFFFFFFFF
Try
'Open the file
hFile = CreateFile(ByVal StrPtr(szFilename),%GENERIC_READ,%FILE_SHARE_READ,ByVal %NULL,_
%OPEN_EXISTING,%FILE_ATTRIBUTE_ARCHIVE Or %FILE_ATTRIBUTE_HIDDEN Or _
%FILE_ATTRIBUTE_READONLY Or %FILE_ATTRIBUTE_SYSTEM Or %FILE_FLAG_SEQUENTIAL_SCAN,%NULL)
If (hFile = %INVALID_HANDLE_VALUE) Then
dwErrorCode = GetLastError()
Else
' There is a bug in the Microsoft compilers where inline assembly
' code cannot access static member variables. This is a work around
' for that bug. For more info see Knowledge base article Q88092
Local ptrCrc32Table As Dword Ptr: ptrCrc32Table = VarPtr(s_arrdwCrc32Table(0))
Dim buffer As Asciiz * %MAX_BUFFER_SIZE
Dim dwBytesRead As Dword
Dim bSuccess As Long : bSuccess = ReadFile(hFile, buffer, SizeOf(buffer), dwBytesRead, ByVal %NULL)
While (bSuccess) And (dwBytesRead)
' Register use:
' eax - CRC32 value
' ebx - a lot of things
' ecx - CRC32 value
' edx - address of end of buffer
' esi - address of start of buffer
' edi - CRC32 table
'Asm
' Save the esi and edi registers
!push esi
!push edi
!mov eax, dwCrc32 ' Load the pointer to dwCrc32
!mov ecx, [eax] ' Dereference the pointer to load dwCrc32
!mov edi, ptrCrc32Table ' Load the CRC32 table
!lea esi, buffer ' Load buffer
!mov ebx, dwBytesRead ' Load dwBytesRead
!lea edx, [esi + ebx] ' Calculate the end of the buffer
crc32loop:
!xor eax, eax ' Clear the eax register
!mov bl, byte ptr [esi] ' Load the current source byte
!mov al, cl ' Copy crc value into eax
!inc esi ' Advance the source pointer
!xor al, bl ' Create the index into the CRC32 table
!shr ecx, 8
!mov ebx, [edi + eax * 4] ' Get the value out of the table
!xor ecx, ebx ' xor with the current byte
!cmp edx, esi ' Have we reached the end of the buffer?
!jne crc32loop
' Restore the edi and esi registers
!pop edi
!pop esi
!mov eax, dwCrc32 ' Load the pointer to dwCrc32
!mov [eax], ecx ' Write the result
'End Asm
bSuccess = ReadFile(hFile, buffer, SizeOf(buffer), dwBytesRead, ByVal %NULL)
Wend
End If
Catch
dwErrorCode = %ERROR_CRC
End Try
If (hFile <> %NULL) Then CloseHandle(hFile)
dwCrc32 = dwCrc32 Xor &HFFFFFFFF
Method = dwErrorCode
End Method
End Interface
End Class |
|