simxinzi 发表于 2009-1-17 16:07:47

AU3如何实现分块校验CRC32?

有一个文件 Test.rar 比如有8.8MB

用工具把这个文件分成了1M一个,分成了9份
分别是:
test.rar.1
test.rar.2
...
test.rar.9

用COPY/B合并后和原来没有分块的文件CRC,SHA1完全相同

我想实现用Au3分块导出原来未分块的文件Test.rar的CRC,比如说第0字节到第1048576字节导出一份CRC32,第1048577到2097152再导出一份CRC32,于是我写了下边的代码,但我发现第1M字节导出来的是正确的,也就说和分割后的文件一样,但后边的却不同,代码可能存在错误,所以,请大家帮忙:

我写的代码如下:; Created by Yudin Dmitry (Lazycat)

Global $nBufSize = 16384 * 16
Global $Blocksize = 1048576
Global $CRC32 = 0
Global $sFile = FileOpenDialog("Open file", "", "Any file (*.*)")
If $sFile = "" Then Exit

Global $timer = TimerInit()
Global $hFile = FileOpen($sFile, 16)
For $z=1 to Ceiling(FileGetSize($sFile) / $Blocksize)
For $i = 1 To Ceiling($Blocksize / $nBufSize)
    $CRC32 = FastCRC32(FileRead($hFile, $nBufSize), BitNot($CRC32))
Next
MsgBox (0, "Result", Hex($CRC32, 8) & " in " & Round(TimerDiff($timer)) & " ms")
Next
FileClose($hFile)



Func FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)
    Local $nLen, $vTemp
    If DllStructGetSize($vBuffer) = 0 Then ; String passed
      If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
      Else
            $nLen = StringLen($vBuffer)
      EndIf
      $vTemp = DllStructCreate("byte[" & $nLen & "]")
      DllStructSetData($vTemp, 1, $vBuffer)
      $vBuffer = $vTemp
    EndIf

    ; Machine code hex strings (created by Laszlo)
    Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072DB5E8B4510F7D05DC3"

    ; Create machine code stubs
    Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)

    ; Structure for CRC32 Lookup table
    Local $CRC32LookupTable = DllStructCreate("int["& 256 &"]")

    ; CallWindowProc under WinXP can have 0 or 4 parameters only, so pad remain params with zeros
    ; Execute stub for fill lookup table
    DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
                                                   "ptr", DllStructGetPtr($CRC32LookupTable), _
                                                   "int", 0, _
                                                   "int", 0, _
                                                   "int", 0)
    ; Execute main stub
    Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
                                                               "ptr", DllStructGetPtr($vBuffer), _
                                                               "uint", DllStructGetSize($vBuffer), _
                                                               "uint", $nCRC32, _
                                                               "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret
EndFunc
页: [1]
查看完整版本: AU3如何实现分块校验CRC32?