Jump to content

Need help converting a hash function to AutoIT.


Datenshi
 Share

Recommended Posts

Stay a while and listen!, I'm attempting to translate the hash function over at http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes for use in AutoIT. Problem is, I get reeeaaally confused with big numbers. Would you be so kind to lend me a hand and teach me the ways of the samurai coder?

Hash code is based on Media Player Classic. In natural language it calculates: size + 64bit chksum of the first and last 64k (even if they overlap because the file is smaller than 128k).

breakdance.avi test file : correct Hash = "8e245d9679d31e12"

and below is my attempt so far, which isn't working. Don't forget to put breakdance.avi in @scriptdir. Oyeah its written in AutoIT 3.3.2.0

yoinked!

I guess hex() doesn't support the length required, but i was mainly interested in whether my hash calc is correct.

Edited by Datenshi
Link to comment
Share on other sites

Slow... It's on 3.3.0.0. The binary output produces a byte flipped output but the hash should be correct. Just copy the decimal value and paste it in Window's calculator and switch the hex view:

#include <Constants.au3>
#include <WinAPI.au3>

Local $iHash = _Compute_Hash(@ScriptDir & "\breakdance.avi")
ConsoleWrite(Binary($iHash) & @TAB & $iHash & @CRLF)
Exit

Func _Compute_Hash($sFileName)
    Local $hFile, $tRet, $tTmp, $pTmp, $iFileSize, $iRead, $iChunk, $iI

    $hFile = _WinAPI_CreateFile($sFileName, 2, 2, 6)
    If Not $hFile Then Return SetError(1, 0, 0)
    
    $iFileSize = _WinAPI_SetFilePointer($hFile, 0, $FILE_END)
    $iChunk = 65536
    
    If $iFileSize < $iChunk * 2 Then
        _WinAPI_CloseHandle($hFile)
        Return SetError(2, 0, 0)
    EndIf
    
    $tRet = DllStructCreate("uint64")
    $tTmp = DllStructCreate("uint64")
    $pTmp = DllStructGetPtr($tTmp)
    
    DllStructSetData($tRet, 1, $iFileSize)
    _WinAPI_SetFilePointer($hFile, 0, $FILE_BEGIN)
    
    For $iI = 0 To ($iChunk/8)-1
        _WinAPI_ReadFile($hFile, $pTmp, 8, $iRead)
        DllStructSetData($tRet, 1, DllStructGetData($tRet, 1) + DllStructGetData($tTmp, 1))
    Next
    
    _WinAPI_SetFilePointer($hFile, MAX(0, $iFileSize-$iChunk), $FILE_BEGIN)
    
    For $iI = 0 To ($iChunk/8)-1
        _WinAPI_ReadFile($hFile, $pTmp, 8, $iRead)
        DllStructSetData($tRet, 1, DllStructGetData($tRet, 1) + DllStructGetData($tTmp, 1))
    Next

    _WinAPI_CloseHandle($hFile)
    Return SetError(0, 0, DllStructGetData($tRet, 1))
EndFunc

Func MAX($a, $b)
    If $a > $b Then Return $a
    Return $b
EndFunc

Edit: You can do something like this to get the 64bit value hex representation:

Func _HEX($iValue)
    Return StringFormat("%#.8x%.8x", $iValue/4294967296, $iValue)
EndFunc
EndFunc
Edited by Authenticity
Link to comment
Share on other sites

Stay a while and listen!,

lol Diablo much? ;)

Hehe, just a tad! :evil:

Rewrote Authenticity's implementation, for AutoIT 3.3.2.0, its also twice as fast, ~350-400ms on my pc. Anyway, I will put it in the Examples Script Forums.

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

Edited by Datenshi
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...