@haifutw 能发现一下源码吗
虽然网上有开源的,但是我看不懂(不知道为什么算出来的答案不一样)
地址:https://bbs.kanxue.com/thread-120018.htm
[Visual Basic] 纯文本查看 复制代码 '*************************************************************************
'**模 块 名:mCRC
'**说 明:E_mail:xa04@qq.com 版权所有2008 - 2009(C)1
'**创 建 人:瞧红尘
'**日 期:2010-09-03 02:19:08
'**修 改 人:
'**日 期:
'**描 述:
'**版 本:V1.0.0
'*************************************************************************
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, Optional ByVal Length As Long = 4)
Private Type t_CRCdata
num1 As Byte
num2 As Byte
num3 As Byte
num4 As Byte
End Type
' ******************** CRC32编码 与 编辑 ********************
'第一参数传入字节数组,
'第二个写偏移覆盖(覆盖掉4字节),
'第三个写你想反回个什么样的crc,
'四个就是你的返回值
Public Function CRC32Edit(pByte() As Byte, _
Optional lOffset As Long = -1, _
Optional lCRC32 As Long, _
Optional retlCRC As Long) As String
Dim crc32Result As Long
Dim i As Long
Dim j As Long
Dim dwCrc As Long
Dim iLookup As Long
Dim Lb As Long
Dim Ub As Long
Dim Buffer() As Byte
Dim Buffer2() As Byte
Dim k As Long
Dim cr1 As t_CRCdata
Dim cr2 As t_CRCdata
'常数
Const Num0 As Long = &H0
Const Num1 As Long = &H1
Const Num2 As Long = &H2
Const Num8 As Long = &H8
Const Num255 As Long = &HFF
Const Num256 As Long = &H100
Const Num16777215 As Long = &HFFFFFF
Const dwPolynomial As Long = &HEDB88320
Const Num2147483647 As Long = &H7FFFFFFF
Const NumNegative1 As Long = &HFFFFFFFF
Const NumNegative2 As Long = &HFFFFFFFE
Const NumNegative256 As Long = &HFFFFFF00
'CRC32表
Dim crc32Table(&HFF) As Long
Dim CRCdata(255) As t_CRCdata
'初始化CRC32表*****************************
For i = Num0 To Num255
dwCrc = i
For j = Num8 To Num1 Step NumNegative1
If (dwCrc And Num1) Then
dwCrc = ((dwCrc And NumNegative2) \ Num2) And Num2147483647
dwCrc = dwCrc Xor dwPolynomial
Else
dwCrc = ((dwCrc And NumNegative2) \ Num2) And Num2147483647
End If
Next
crc32Table(i) = dwCrc
CopyMemory CRCdata(i), crc32Table(i)
Next
crc32Result = NumNegative1 '初始化
If lOffset < 0 Then
lOffset = UBound(pByte) + 1
Else
If lOffset > UBound(pByte) Then
lOffset = UBound(pByte) + 1
End If
End If
If lOffset > 0 Then
ReDim Buffer(lOffset - 1)
CopyMemory Buffer(0), pByte(0), lOffset '数据拷贝
'Debug.Print "lOffset:", lOffset
'计算CRC32码*******************************
Lb = LBound(Buffer)
Ub = UBound(Buffer)
For i = Lb To Ub
iLookup = (crc32Result And Num255) Xor Buffer(i) '第四位 xor 新字节
crc32Result = ((crc32Result And NumNegative256) \ Num256) And Num16777215 '前三位
crc32Result = crc32Result Xor crc32Table(iLookup) '前三位*3 xor 表(第四位*1 xor 新字节*1)*4
Next i
End If
CRC32Edit = Hex$(Not (crc32Result)) '计算前面的crc值,返回是什么样的
'计算后面的
k = UBound(pByte) - lOffset - 3
If k > 0 Then '后面是否有数据
ReDim Buffer2(k - 1)
CopyMemory Buffer2(0), pByte(lOffset + 4), k
k = Not (lCRC32)
CopyMemory cr1, k
'反向CRC计算
For j = UBound(Buffer2) To 0 Step -1
For i = 0 To 255
If cr1.num4 = CRCdata(i).num4 Then
Exit For
End If
Next
If i > 255 Then
Debug.Assert False
End If
cr1.num4 = cr1.num3 Xor CRCdata(i).num3
cr1.num3 = cr1.Num2 Xor CRCdata(i).Num2
cr1.Num2 = cr1.Num1 Xor CRCdata(i).Num1
cr1.Num1 = i Xor Buffer2(j)
Next
Else
k = Not (lCRC32)
CopyMemory cr1, k
End If
'要得出文件CRC值=lCRC32 之前部分的CRC必须满足的条件:cr1的值
'计算
For j = 0 To 3
For i = 0 To 255
If cr1.num4 = CRCdata(i).num4 Then
Exit For
End If
Next
' If i > 255 Then
' Debug.Assert False
' End If
cr1.num4 = cr1.num3 Xor CRCdata(i).num3
cr1.num3 = cr1.Num2 Xor CRCdata(i).Num2
cr1.Num2 = cr1.Num1 Xor CRCdata(i).Num1
cr1.Num1 = i
Next
CopyMemory k, cr1
k = k Xor crc32Result
retlCRC = k '计算出来的是4字节覆盖的值,不是crc
End Function |