明晨网络

电话: 136-6532-7492 QQ: 给我发送消息 8507-0741

VB下的CRC32编码类模块

admin,2009-06-12 19:06, 文章标签: VB CRC32

    很多场合需要计算CRC32,这里给出一个好用的VB类模块。该模块可以计算字符串、字节数组、文件的crc32编码。明晨网络Mingchennet.com现在发布的模块,默认计算整个文件的CRC32,也可以通过设置FileStart和FileEnd,来计算文件中指定长度内的CRC32,比如计算1-10200范围内的二进制内容的crc32为123456,而后40个字节空间就用来存储这个结果123456,当x.exe启动时,计算出自身1-10200的crc32,再与后40字节存储的结果比较,看是否一致。这就是传说中的crc32自校检。当然,必须在exe编译后,用其他程序计算其前10200的crc32,再写入该exe的后40位中。
    该类模块对文件进行计算时,需要将文件转成二进制流,使用了FileStream类模块来实现
   罗嗦了一大堆,上代码。
    FileStream类模块

 

  1.   '========================================  
  2.    '模块名称:FileStream  
  3.    '模块说明:本模块用来将文件转为二进制流,对文件进行CRC32编码计算时依赖本模块  
  4.    '最后更新: 明晨网络 www.MingchenNet.com 2009-05-31 21:57  
  5.    '========================================  
  6. Option Explicit  
  7.      
  8. Private m_sFile As String 
  9. Private m_iFile As Integer 
  10. Private m_iLen As Long 
  11. Private m_iOffset As Long 
  12. Private m_Start As Long 
  13. Private m_End As Long 
  14.      
  15. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _  
  16.     lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)  
  17.    
  18. Public Property Get File() As String 
  19.     File = m_sFile  
  20. End Property 
  21. Public Property Let File(ByVal sFile As String)  
  22.     Dispose  
  23.     m_sFile = sFile  
  24.     Dim lErr As Long 
  25.     If (FileExists(m_sFile, lErr)) Then 
  26.         m_iFile = FreeFile  
  27.         Open m_sFile For Binary Access Read Lock Write As #m_iFile  
  28.         m_iLen = LOF(m_iFile)  
  29.         'Seek #m_iFile, m_Start  
  30.    Else 
  31.         Err.Raise lErr, App.EXEName & ".File" 
  32.     End If 
  33. End Property 
  34. '设置读取文件的开始位置  
  35. Public Property Let FileStart(ByVal lStart As Long)  
  36.     m_Start = lStart  
  37. End Property 
  38.    
  39. '设置读取文件的结束位置  
  40. Public Property Let FileEnd(ByVal lEnd As Long)  
  41.     m_End = lEnd  
  42. End Property 
  43.    
  44. Private Function FileExists(ByVal sFile As StringByRef lErr As LongAs Boolean 
  45.      
  46.     lErr = 0  
  47.     On Error Resume Next 
  48.     Dim sDir As String 
  49.     sDir = Dir(sFile, 7)  
  50.     lErr = Err.Number  
  51.     On Error GoTo 0  
  52.      
  53.     If (lErr = 0) Then 
  54.         If (Len(sDir) > 0) Then 
  55.             FileExists = True 
  56.         Else 
  57.             lErr = 53  
  58.         End If 
  59.     End If 
  60.      
  61. End Function 
  62.    
  63. Public Property Get Length() As Long 
  64.     Length = m_iLen  
  65. End Property 
  66.    
  67. Public Function Read( _  
  68.     buffer() As Byte, _  
  69.     ByVal readSize As Long _  
  70.     ) As Long 
  71.      
  72.     Dim lReadSize As Long 
  73.     lReadSize = readSize  
  74.     If (m_iOffset + lReadSize >= m_End) Then 
  75.         readSize = m_End - m_iOffset  
  76.         If (readSize > 0) Then 
  77.             ReDim newBuffer(0 To readSize - 1) As Byte 
  78.             Get #m_iFile, , newBuffer  
  79.             CopyMemory buffer(0), newBuffer(0), readSize  
  80.         Else 
  81.             Dispose  
  82.         End If 
  83.         m_iOffset = m_iOffset + readSize  
  84.     Else 
  85.         ' Can read  
  86.        Get #m_iFile, , buffer  
  87.         m_iOffset = m_iOffset + readSize  
  88.     End If 
  89.     Read = readSize  
  90.      
  91. End Function 
  92.    
  93. Public Sub Dispose()  
  94.     If (m_iFile) Then 
  95.         Close #m_iFile  
  96.         m_iFile = 0  
  97.     End If 
  98. End Sub 
  99.    
  100. Private Sub Class_Terminate()  
  101.     Dispose  
  102. End Sub 

核心CRC32类模块

 

  1. '========================================  
  2.    '模块名称:CRC32  
  3.    '模块说明:本模块用来计算文件及字符串的CRC32编码  
  4.    '最后更新: 明晨网络 www.MingchenNet.com 2009-05-31 21:57  
  5.    '========================================  
  6. Option Explicit  
  7.      
  8.     ' This code is taken from the VB.NET CRC32 algorithm  
  9.    ' provided by Paul (wpsjr1@succeed.net) - Excellent work!  
  10.      
  11. Private crc32Table() As Long 
  12. Private Const BUFFER_SIZE As Long = 8192  
  13.    
  14. Public Function GetByteArrayCrc32(ByRef buffer() As ByteAs Long 
  15.      
  16.     Dim crc32Result As Long 
  17.     crc32Result = &HFFFFFFFF  
  18.      
  19.     Dim i As Integer 
  20.     Dim iLookup As Integer 
  21.      
  22.     For i = LBound(buffer) To UBound(buffer)  
  23.         iLookup = (crc32Result And &HFF) Xor buffer(i)  
  24.         crc32Result = ((crc32Result And &HFFFFFF00)  &H100) And 16777215 ' nasty shr 8 with vb :/  
  25.        crc32Result = crc32Result Xor crc32Table(iLookup)  
  26.     Next i  
  27.      
  28.     GetByteArrayCrc32 = Not (crc32Result)  
  29.      
  30. End Function 
  31.    
  32. Public Function GetStreamCrc32(ByRef stream As FileStream) As Long 
  33.      
  34.     Dim crc32Result As Long 
  35.     crc32Result = &HFFFFFFFF  
  36.      
  37.     Dim buffer(0 To BUFFER_SIZE - 1) As Byte 
  38.     Dim readSize As Long 
  39.     readSize = BUFFER_SIZE  
  40.      
  41.     Dim count As Integer 
  42.     count = stream.Read(buffer, readSize)  
  43.      
  44.     Dim i As Integer 
  45.     Dim iLookup As Integer 
  46.     Dim tot As Integer 
  47.      
  48.     Do While (count > 0)  
  49.         For i = 0 To count - 1  
  50.             iLookup = (crc32Result And &HFF) Xor buffer(i)  
  51.             crc32Result = ((crc32Result And &HFFFFFF00)  &H100) And 16777215 ' nasty shr 8 with vb :/  
  52.            crc32Result = crc32Result Xor crc32Table(iLookup)  
  53.         Next i  
  54.         count = stream.Read(buffer, readSize)  
  55.     Loop 
  56.      
  57.     GetStreamCrc32 = Not (crc32Result)  
  58.      
  59. End Function 
  60.    
  61.    
  62. Public Function GetFileCrc32(ByVal FilePath As StringAs Long 
  63.     Dim cStream As FileStream  
  64.     Set cStream = New FileStream  
  65.     cStream.File = FilePath  
  66.     cStream.FileStart = 1  
  67.     cStream.FileEnd = FileLen(FilePath) - 20  
  68.     GetFileCrc32 = GetStreamCrc32(cStream)  
  69.     Set cStream = Nothing 
  70. End Function 
  71.    
  72. Public Function GetStringCrc32(ByVal Str As StringAs Long 
  73.     GetStringCrc32 = GetByteArrayCrc32(StrConv(Str, vbFromUnicode))  
  74. End Function 
  75.    
  76. Private Sub Class_initialize()  
  77.     ' This is the official polynomial used by CRC32 in PKZip.  
  78.    ' Often the polynomial is shown reversed (04C11DB7).  
  79.    Dim dwPolynomial As Long 
  80.     dwPolynomial = &HEDB88320  
  81.     Dim i As Integer, j As Integer 
  82.      
  83.     ReDim crc32Table(256)  
  84.     Dim dwCrc As Long 
  85.      
  86.     For i = 0 To 255  
  87.         dwCrc = i  
  88.         For j = 8 To 1 Step -1  
  89.             If (dwCrc And 1) Then 
  90.                 dwCrc = ((dwCrc And &HFFFFFFFE)  2&) And &H7FFFFFFF  
  91.                 dwCrc = dwCrc Xor dwPolynomial  
  92.             Else 
  93.                 dwCrc = ((dwCrc And &HFFFFFFFE)  2&) And &H7FFFFFFF  
  94.             End If 
  95.         Next j  
  96.         crc32Table(i) = dwCrc  
  97.     Next i  
  98.      
  99. End Sub 

文章源自:明晨网络,admin,《VB下的CRC32编码类模块》,http://www.mingchennet.com/tec/code/vb/28.htm