Jump to content

CRC32 generation


eltorro
 Share

Recommended Posts

It works, but it is slow. The vb source that I converted this from is lightning fast, less than a second on the same file.

If anyone can speed the hash, have at it.

;converted from http://www.vbforums.com/showthread.php?t=412922

#include <GUIConstants.au3>
Global $pInititialized
Global $pTable[256]

$Form1 = GUICreate("CRC32", 403, 239, 209, 164)
$FilePath = GUICtrlCreateInput("C:\Program Files\AutoIt3\Au3Info.exe", 6, 32, 347, 21)
$Browse = GUICtrlCreateButton("...", 360, 32, 28, 22, 0)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$GetCRC = GUICtrlCreateButton("Generate CRC32", 98, 61, 193, 33, 0)
GUICtrlSetState(-1, $GUI_DISABLE)
$Group1 = GUICtrlCreateGroup("Results:", 9, 98, 384, 127)
$FileSize = GUICtrlCreateLabel("", 70, 122, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$FileCRC = GUICtrlCreateLabel("", 70, 145, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$TotTime = GUICtrlCreateLabel("", 70, 168, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$Label5 = GUICtrlCreateLabel("File Size:", 20, 122, 46, 17)
$Label6 = GUICtrlCreateLabel("CRC32:", 20, 145, 41, 17)
$Label7 = GUICtrlCreateLabel("Time:", 20, 168, 30, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Label4 = GUICtrlCreateLabel("File Name:", 6, 8, 54, 17)
GUISetState(@SW_SHOW)

crcInit()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Browse
            GUICtrlSetData($FilePath, FileOpenDialog("Select File", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "All Files (*.*)", 1))
        Case $GetCRC
            If FileExists(GUICtrlRead($FilePath)) Then
                if (StringInStr(FileGetAttrib(GUICtrlRead($FilePath)), "D")) Then
                    MsgBox(266288, "CRC", "Please Select a file instead of a folder.")
                Else
                    $timer = TimerInit()
                    GUICtrlSetData($FileSize, FileGetSize(GUICtrlRead($FilePath)))
                    GUICtrlSetData($FileCRC, "")
                    GUICtrlSetData($TotTime, "")
                    
                    GUICtrlSetData($FileCRC, crc32File(GUICtrlRead($FilePath)))
                    GUICtrlSetData($TotTime, _TicksToTime(TimerDiff($timer)))
                EndIf
            EndIf
    EndSwitch
    If GUICtrlRead($FilePath) <> "" Then
        If BitAND(GUICtrlGetState($GetCRC), $GUI_DISABLE) = $GUI_DISABLE Then GUICtrlSetState($GetCRC, $GUI_ENABLE)
    Else
        If BitAND(GUICtrlGetState($GetCRC), $GUI_ENABLE) = $GUI_ENABLE Then GUICtrlSetState($GetCRC, $GUI_DISABLE)
    EndIf
WEnd


Func crcInit($Poly = 0xEDB88320)
    Local $crc
    Local $i
    Local $j
    For $i = 0 To 255
        $crc = $i
        For $j = 0 To 7
            If BitAND($crc, 0x1) Then
                $crc = BitXOR(BitAND(BitAND($crc, 0xFFFFFFFE) / 0x2, 0x7FFFFFFF), $Poly)
            Else
                $crc = BitAND(($crc / 0x2), 0x7FFFFFFF)
            EndIf
        Next
        $pTable[$i] = $crc
    Next
    $pInititialized = True
EndFunc   ;==>crcInit

Func crc32File($Path)
    Local $Buffer
    Local $BufferSize
    Local $crc
    Local $FileNr
    Local $Length
    Local $i
    If Not $pInititialized Then crcInit()
    $BufferSize = 1024 * 8 ;'8 KB
    $ReadStruct = DllStructCreate("byte[" & $BufferSize & "]")
    $FileNr = FileOpen($Path, 0)
    $Length = FileGetSize($Path)
    Local $Progress = $Length
    $crc = 0xFFFFFFFF
    Local $TotalProgress = 0
    ProgressOn("Calculating CRC", "Working...")
    While $Length
        If $Length < $BufferSize Then
            $BufferSize = $Length
        EndIf
        DllStructSetData($ReadStruct, 1, FileRead($FileNr, $BufferSize))
        
        For $i = 1 To $BufferSize
            ProgressSet(Int(100* (($TotalProgress + $i) / $Progress)))
            $Buffer = (DllStructGetData($ReadStruct, 1, $i))
            ;$crc = (($crc And 0xFFFFFF00) / 0x100) And 0xFFFFFF Xor $pTable($Buffer[$i] Xor $crc And 0xFF)
            $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR($Buffer, $crc), 0xFF) ]))
        Next
        $Length = $Length - $BufferSize
        $TotalProgress = $TotalProgress + $BufferSize
    WEnd
    $ReadStruct = 0
    FileClose($FileNr)
    ProgressOff()
    Return Hex(BitNOT($crc), 8)
EndFunc   ;==>crc32File

;===============================================================================
;
; Description:      Converts the specified tick amount to hours, minutes, and
;                   seconds.
; Parameter(s):     $iTicks - Tick amount
;
; Requirement(s):   None
; Return Value(s):  On Success Array of times
;                   On Failure - 0 and sets @ERROR = 1
; Author(s):        Marc <mrd at gmx de>
;                    This version modified by eltorro gehossafats at netmdc dot com
; Note(s):          None
;
;===============================================================================
Func _TicksToTime($iTicks)
    If Number($iTicks) > 0 Then
        $iTicks = Round($iTicks / 1000)
        Local $iHours = Int($iTicks / 3600)
        $iTicks = Mod($iTicks, 3600)
        Local $iMins = Int($iTicks / 60)
        Local $iSecs = Round(Mod($iTicks, 60))
        ; If $iHours = 0 then $iHours = 24
        Return StringFormat("%02i:%02i:%02i", $iHours, $iMins, $iSecs)
        
    Else
        SetError(1)
        Return ""
    EndIf
EndFunc   ;==>_TicksToTime

So Long,

eltorro

Link to comment
Share on other sites

I don't think you can do much about the time it takes to calculate a CRC32 calculation in AU3. I have tried to write one in AU3 too but just like yours example it did take "forever" to calculate the checksum. I ended up with writing a CRC32 plugin in C for AU3 instead.

Edited by Cyberworld
Link to comment
Share on other sites

  • Moderators

Cutting that While/WEnd out seemed to save a few seconds here and there:

Func crc32File($Path)
    Local $Buffer, $BufferSize, $crc
    Local $FileNr, $Length, $i, $hFRead
    If Not $pInititialized Then crcInit()
    $BufferSize = FileGetSize($Path)
    $ReadStruct = DllStructCreate("byte[" & $BufferSize & "]")
    $FileNr = FileOpen($Path, 0)
    $hFRead = FileRead($FileNr)
    Local $Progress = $Length
    $crc = 0xFFFFFFFF
    DllStructSetData($ReadStruct, 1, $hFRead)
    For $i = 1 To $BufferSize
        ;$crc = (($crc And 0xFFFFFF00) / 0x100) And 0xFFFFFF Xor $pTable($Buffer[$i] Xor $crc And 0xFF)
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i)), $crc), 0xFF) ]))
    Next
    $ReadStruct = 0
    FileClose($FileNr)
    ProgressOff()
    Return Hex(BitNOT($crc), 8)
EndFunc   ;==>crc32File

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Every little bit helps.

Wouldn't one of wOuters asm tricks do wonders here?

Edited by eltorro
Link to comment
Share on other sites

  • Moderators

Every little bit helps.

Wouldn't one of wOuters asm tricks do wonders here?

w0uter hasn't been on much lately.

What about splitting the file up... and using Multiple /AutoIt3ExecuteScript 's to run the loop(s)? I've found that large loops, in this case could be 500k plus sometimes, it drags out pretty bad. If we split the file up into x = parts then that should be quicker? It's just a thought... downside is you'd have to write the results to an .ini or something.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I might try to do that. But I think that the result is based on the cascading result of the loop.

Edited by eltorro
Link to comment
Share on other sites

  • Moderators

I might try to do that. But I think that the result is based on the cascading result of the loop.

It is, I just tested it :)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Link to comment
Share on other sites

  • Moderators

With just the For loop and the below, it's 13 seconds faster on my PC with the same result:

;converted from http://www.vbforums.com/showthread.php?t=412922

#include <GUIConstants.au3>
Global $pInititialized
Global $pTable[256]

$Form1 = GUICreate("CRC32", 403, 239, 209, 164)
$FilePath = GUICtrlCreateInput("C:\Program Files\AutoIt3\Au3Info.exe", 6, 32, 347, 21)
$Browse = GUICtrlCreateButton("...", 360, 32, 28, 22, 0)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$GetCRC = GUICtrlCreateButton("Generate CRC32", 98, 61, 193, 33, 0)
GUICtrlSetState(-1, $GUI_DISABLE)
$Group1 = GUICtrlCreateGroup("Results:", 9, 98, 384, 127)
$FileSize = GUICtrlCreateLabel("", 70, 122, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$FileCRC = GUICtrlCreateLabel("", 70, 145, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$TotTime = GUICtrlCreateLabel("", 70, 168, 315, 17, $SS_SUNKEN)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$Label5 = GUICtrlCreateLabel("File Size:", 20, 122, 46, 17)
$Label6 = GUICtrlCreateLabel("CRC32:", 20, 145, 41, 17)
$Label7 = GUICtrlCreateLabel("Time:", 20, 168, 30, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Label4 = GUICtrlCreateLabel("File Name:", 6, 8, 54, 17)
GUISetState(@SW_SHOW)

crcInit()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Browse
            GUICtrlSetData($FilePath, FileOpenDialog("Select File", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "All Files (*.*)", 1))
        Case $GetCRC
            If FileExists(GUICtrlRead($FilePath)) Then
                if (StringInStr(FileGetAttrib(GUICtrlRead($FilePath)), "D")) Then
                    MsgBox(266288, "CRC", "Please Select a file instead of a folder.")
                Else
                    $timer = TimerInit()
                    GUICtrlSetData($FileSize, FileGetSize(GUICtrlRead($FilePath)))
                    GUICtrlSetData($FileCRC, "")
                    GUICtrlSetData($TotTime, "")
                   
                    GUICtrlSetData($FileCRC, crc32File(GUICtrlRead($FilePath)))
                    GUICtrlSetData($TotTime, _TicksToTime(TimerDiff($timer)))
                EndIf
            EndIf
    EndSwitch
    If GUICtrlRead($FilePath) <> "" Then
        If BitAND(GUICtrlGetState($GetCRC), $GUI_DISABLE) = $GUI_DISABLE Then GUICtrlSetState($GetCRC, $GUI_ENABLE)
    Else
        If BitAND(GUICtrlGetState($GetCRC), $GUI_ENABLE) = $GUI_ENABLE Then GUICtrlSetState($GetCRC, $GUI_DISABLE)
    EndIf
WEnd


Func crcInit($Poly = 0xEDB88320)
    Local $crc
    Local $i
    Local $j
    For $i = 0 To 255
        $crc = $i
        For $j = 0 To 7
            If BitAND($crc, 0x1) Then
                $crc = BitXOR(BitAND(BitAND($crc, 0xFFFFFFFE) / 0x2, 0x7FFFFFFF), $Poly)
            Else
                $crc = BitAND(($crc / 0x2), 0x7FFFFFFF)
            EndIf
        Next
        $pTable[$i] = $crc
    Next
    $pInititialized = True
EndFunc   ;==>crcInit

Func crc32File($Path)
    Local $Buffer, $BufferSize, $crc
    Local $FileNr, $Length, $i, $hFRead
    If Not $pInititialized Then crcInit()
    $BufferSize = FileGetSize($Path)
    $ReadStruct = DllStructCreate("byte[" & $BufferSize & "]")
    ;$FileNr = FileOpen($Path, 0)
    $hFRead = FileRead($Path)
    Local $Progress = $Length
    $crc = 0xFFFFFFFF
    DllStructSetData($ReadStruct, 1, $hFRead)
    For $i = 1 To $BufferSize
        ;$crc = (($crc And 0xFFFFFF00) / 0x100) And 0xFFFFFF Xor $pTable($Buffer[$i] Xor $crc And 0xFF)
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i)), $crc), 0xFF) ]))
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i + 1)), $crc), 0xFF) ]))
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i + 2)), $crc), 0xFF) ]))
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i + 3)), $crc), 0xFF) ]))
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i + 4)), $crc), 0xFF) ]))
        $crc = BitXOR(BitAND((BitAND($crc, 0xFFFFFF00) / 0x100), 0xFFFFFF) , ($pTable[BitAND(BitXOR((DllStructGetData($ReadStruct, 1, $i + 5)), $crc), 0xFF) ]));
        $i += 5
    Next
    $ReadStruct = 0
    ;FileClose($FileNr)
    ProgressOff()
    Return Hex(BitNOT($crc), 8)
EndFunc   ;==>crc32File

;===============================================================================
;
; Description:      Converts the specified tick amount to hours, minutes, and
;                   seconds.
; Parameter(s):     $iTicks - Tick amount
;
; Requirement(s):   None
; Return Value(s):  On Success Array of times
;                   On Failure - 0 and sets @ERROR = 1
; Author(s):        Marc <mrd at gmx de>
;                    This version modified by eltorro gehossafats at netmdc dot com
; Note(s):          None
;
;===============================================================================
Func _TicksToTime($iTicks)
    If Number($iTicks) > 0 Then
        $iTicks = Round($iTicks / 1000)
        Local $iHours = Int($iTicks / 3600)
        $iTicks = Mod($iTicks, 3600)
        Local $iMins = Int($iTicks / 60)
        Local $iSecs = Round(Mod($iTicks, 60))
        ; If $iHours = 0 then $iHours = 24
        Return StringFormat("%02i:%02i:%02i", $iHours, $iMins, $iSecs)
       
    Else
        SetError(1)
        Return ""
    EndIf
EndFunc   ;==>_TicksToTime

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 2 months later...

The wrapper I wrote for the Deep utilities supports six different hashing algorithms.However there is no support for CRC32 as there is no CRC32Deep. ;)

http://www.autoitscript.com/forum/index.php?showtopic=19838

HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code.
Link to comment
Share on other sites

  • 2 years later...

There are these excellent functions: MD5,SHA1,CRC32,RC4,BASE64,XXTEA machine code versions by Ward and CRC32, MD4, MD5, SHA1 by WinAPI by trancexx...

I have the scripts by ward, they seem to have various issues at the moment (vista related). :/

The scripts by trancexx looks promising.

Thanks

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...