MD5 wert ist gleich bei verschiedenen files?

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 06:35

Wenn es Dir zu lange dauert, kannst Du auch noch kleinere Werte ausprobieren. Manche Windows API-Funktionen akzeptieren zwar große Speicherbereiche, brauchen dann aber unverhältnismäßig mehr Zeit (und Ressourcen).
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 08:06

Da Hashes und Hashfunktionen mich doch immer wieder faszinieren, melde ich mich kurz aus meiner Abstinenz zu Wort :D

bcrypt war bei mir ca 5-10 % schneller
lässt ich aber beide bestimmt noch verbessern

Code: Select all

; GLOBAL SETTINGS ===============================================================================================================

#NoEnv
#SingleInstance Force

SetBatchLines -1

global InitQPC  := DllCall("QueryPerformanceFrequency", "int64*", QPF)
global FileName := "C:\Windows\System32\MRT.exe"

; SCRIPT ========================================================================================================================


DllCall("QueryPerformanceCounter", "int64*", S1)
loop 5
	H1 := File_MD5(FileName)
DllCall("QueryPerformanceCounter", "int64*", E1)

DllCall("QueryPerformanceCounter", "int64*", S2)
loop 5
	H2 := bcrypt_md5_file(FileName)
DllCall("QueryPerformanceCounter", "int64*", E2)

MsgBox % "File_MD5:`t" ((E1 - S1) / QPF) * 1000 "`n" H1 "`n`nbcrypt_md5_file:`t" ((E2 - S2) / QPF) * 1000 "`n" H2


; FUNCTIONS =====================================================================================================================

bcrypt_md5_file(filename)
{
    static BCRYPT_MD5_ALGORITHM := "MD5"
    static BCRYPT_OBJECT_LENGTH := "ObjectLength"
    static BCRYPT_HASH_LENGTH   := "HashDigestLength"

    if !(hBCRYPT := DllCall("LoadLibrary", "str", "bcrypt.dll", "ptr"))
        throw Exception("Failed to load bcrypt.dll", -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptOpenAlgorithmProvider", "ptr*", hAlgo, "ptr", &BCRYPT_MD5_ALGORITHM, "ptr", 0, "uint", 0) != 0)
        throw Exception("BCryptOpenAlgorithmProvider: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_OBJECT_LENGTH, "uint*", cbHashObject, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_HASH_LENGTH, "uint*", cbHash, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    VarSetCapacity(pbHashObject, cbHashObject, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptCreateHash", "ptr", hAlgo, "ptr*", hHash, "ptr", &pbHashObject, "uint", cbHashObject, "ptr", 0, "uint", 0, "uint", 0) != 0)
        throw Exception("BCryptCreateHash: " NT_STATUS, -1)

    if !(f := FileOpen(filename, "r", "UTF-8"))
        throw Exception("Failed to open file: " filename, -1)
    f.Seek(0)
    while (dataread := f.RawRead(data, 262144))
        if (NT_STATUS := DllCall("bcrypt\BCryptHashData", "ptr", hHash, "ptr", &data, "uint", dataread, "uint", 0) != 0)
            throw Exception("BCryptHashData: " NT_STATUS, -1)
    f.Close()

    VarSetCapacity(pbHash, cbHash, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptFinishHash", "ptr", hHash, "ptr", &pbHash, "uint", cbHash, "uint", 0) != 0)
        throw Exception("BCryptFinishHash: " NT_STATUS, -1)

    loop % cbHash
        hash .= Format("{:02x}", NumGet(pbHash, A_Index - 1, "uchar"))

    DllCall("bcrypt\BCryptDestroyHash", "ptr", hHash)
    DllCall("bcrypt\BCryptCloseAlgorithmProvider", "ptr", hAlgo, "uint", 0)
    DllCall("FreeLibrary", "ptr", hBCRYPT)

    return hash
}

File_MD5(FilePath) {
   Static MaxSize := 64 * 1024 * 1024 ; 64 MB 
   MD5 := ""
   If !(File := FileOpen(FilePath, "r"))
      Return "" ; hier vielleicht noch eine aussagekräftigere Fehlerbehandlung einfügen
   File.Pos := 0
   FileSize := File.Length
   VarSetCapacity(MD5_CTX, 104, 0)
   DllCall("Advapi32.dll\MD5Init", "Ptr", &MD5_CTX)
   While (FileSize > MaxSize) {
      File.RawRead(Buffer, MaxSize)
      DllCall("Advapi32.dll\MD5Update", "Ptr", &MD5_CTX, "Ptr", &Buffer, "UInt", MaxSize)
      FileSize -= MaxSize
   }
   File.RawRead(Buffer, FileSize)
   DllCall("Advapi32.dll\MD5Update", "Ptr", &MD5_CTX, "Ptr", &Buffer, "UInt", FileSize)
   DllCall("Advapi32.dll\MD5Final", "Ptr", &MD5_CTX)
   File.CLose()
   Loop, 16
      MD5 .= Format("{:02X}", NumGet(MD5_CTX, 87 + A_Index, "UChar"))
   Return MD5
}
p.s hab auch noch irgendein bug in der bcrypt funktion drin
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
effel
Posts: 544
Joined: 16 Jan 2018, 13:34

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 08:53

meinst du damit, das die zahlen ein zeitfaktor sind?
File_MD5: 8409.989678
bcrypt_md5_file: 3802.942053
sorry wenn meine frage evt kopfschütteln erzeugt, aber ich verstehe hier zwar einiges, aber alles was langsamer :-)

und, was meinst du mit

Code: Select all

p.s hab auch noch irgendein bug in der bcrypt funktion drin
ist deine funktion nicht sicher?

Code: Select all

---------------------------
Ergebnis
---------------------------
*
---------------------------
File_MD5:	8409.989678
B64993820DBC529527A600496F8C2E7B

bcrypt_md5_file:	3802.942053
b64993820dbc529527a600496f8c2e7b
---------------------------
OK   
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 09:19

effel wrote: meinst du damit, das die zahlen ein zeitfaktor sind?
File_MD5: 8409.989678
bcrypt_md5_file: 3802.942053
Ja

effel wrote:und, was meinst du mit

Code: Select all

p.s hab auch noch irgendein bug in der bcrypt funktion drin
In der Win10 Funktion
https://www.autohotkey.com/boards/viewtopic.php?p=240620#p240620
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 11:28

Moin jNizM,

schön, Dich mal wieder hier zu sehen.

Dein Beispiel ist recht interessant. Wenn ich MaxSize in File_MD5() auf den Wert von bcrypt_md5_file() setze (262144), bekomme ich folgende Meldung:

Code: Select all

---------------------------
MD5.ahk
---------------------------
File_MD5:	2789.062458
049F665C88F636253DFFB65B58B531CD

bcrypt_md5_file:	2946.022412
049f665c88f636253dffb65b58b531cd
---------------------------
OK   
---------------------------
Manchmal ist weniger eben doch mehr! ;)
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: MD5 wert ist gleich bei verschiedenen files?

08 Feb 2019, 11:49

Noch etwas zum Win 10 Bug:

Code: Select all

    VarSetCapacity(pbHash, cbHash, 0)
    if !(f := FileOpen(filename, "r", "UTF-8"))
        throw Exception("Failed to open file: " filename, -1)
    f.Seek(0)
    while (dataread := f.RawRead(data, 262144))
        if (NT_STATUS := DllCall("bcrypt\BCryptHash", "ptr", hAlgo, "ptr", 0, "uint", 0, "ptr", &data, "uint", dataread, "ptr", &pbHash, "uint", cbHash) != 0)
            throw Exception("BCryptHash: " NT_STATUS, -1)
    f.Close()
BCryptHash wrote:Performs a single hash computation. This is a convenience function that wraps calls to BCryptCreateHash, BCryptHashData, BCryptFinishHash, and BCryptDestroyHash.

Source

Ich glaube nicht, dass Du BCryptHash() scheibchenweise aufrufen kannst. Diese Funktion führt die Berechnung anscheinend immer komplett durch.

Grüße, just me
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 03:36

Code: Select all

    VarSetCapacity(pbHash, cbHash, 0)
    if !(f := FileOpen(filename, "r", "UTF-8"))
        throw Exception("Failed to open file: " filename, -1)
	f.Seek(0), dataread := f.RawRead(data, f.Length)
	if (NT_STATUS := DllCall("bcrypt\BCryptHash", "ptr", hAlgo, "ptr", 0, "uint", 0, "ptr", &data, "uint", dataread, "ptr", &pbHash, "uint", cbHash) != 0)
		throw Exception("BCryptHash: " NT_STATUS, -1)
    f.Close()
Hoffe das ist nicht zu negativ mit riesigen Dateien.. muss ich mal testen.


Edit:
Diese Funktion ist nicht für große Dateien geeignet.
Hab es mit einer Windows iso probiert (3.8 GB). Er haut das dann natürlich komplett in den RAM und AHK hatte zwischendurch knapp 4 GB im Taskmanager.

Werde diese Funktion dann aus der Lib in meinem Github entfernen, da sie Probleme verursachen kann, wenn nicht genügend Arbeitsspeicher vorhanden ist.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
effel
Posts: 544
Joined: 16 Jan 2018, 13:34

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 12:05

ich bin mit dem code nun auf einen win10 (4gb ram) rechner umgezogen
dort läuft es mit beiden versionen einwandfrei

Code: Select all

RTLNITRO_11_23_2016_20_20_22.mpg - 12,6 GB 
---------------------------
bcrypt_md5_file
1 Dateien wurden kopiert!
Startzeit: 13:29, jetzige Zeit: 13:36. Es ist vergangen: 00:07
4694c6ee0b33f563875dfc378d29b94d
---------------------------
File_MD5 MaxSize 32 MB
1 Dateien wurden kopiert!
Startzeit: 13:40, jetzige Zeit: 13:46. Es ist vergangen: 00:06
4694C6EE0B33F563875DFC378D29B94D
---------------------------

File_MD5 MaxSize 262144
1 Dateien wurden kopiert!
Startzeit: 13:54, jetzige Zeit: 14:00. Es ist vergangen: 00:06
4694C6EE0B33F563875DFC378D29B94D
---------------------------

File_MD5 MaxSize 1024
1 Dateien wurden kopiert!
Startzeit: 15:25, jetzige Zeit: 15:31. Es ist vergangen: 00:06
4694C6EE0B33F563875DFC378D29B94D
---------------------------
bei wenigen fotos stimmt jedoch das datum nicht mit dem id3tag überein, gibt es eine möglichkeit mit ahk die metadaten des files auszulesen?, wenn dort ein anderes datum steht als in A_LoopFileTimeModified, habe ich die wahl
gregster
Posts: 9002
Joined: 30 Sep 2013, 06:48

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 12:31

Ist ein id3tag nicht eher in mp3s zu finden? In Fotos würd ich eher exif-Daten erwarten... aber vielleicht bin ich nicht up-to-date :think:
Im Falle von exif-Daten könntest du mal das hier probieren: https://autohotkey.com/board/topic/61855-exif-data-natively-and-com-ahk-l/ (Habe ich selber noch nicht probiert)

Edit: Etwas neueres zu Exif: https://www.autohotkey.com/boards/viewtopic.php?t=59650&p=251466
effel
Posts: 544
Joined: 16 Jan 2018, 13:34

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 13:27

gregster wrote:
12 Feb 2019, 12:31
Ist ein id3tag nicht eher in mp3s zu finden? In Fotos würd ich eher exif-Daten erwarten... a
danke für deine antwort ;)

stimmt, damit hast du natürlich recht, ich habe ich meine frage falsch gestellt und trotzdem die richtige antwort bekommen :-)

ich habe in dem "grossen" ordner nicht nur fotos sondern auch audio und film dateien.

somit stellt sich nochmal die frage nach den metataten für die audio und video dateien und sollte der "tag" hierfür anders heissen, dann meine ich den...
gregster
Posts: 9002
Joined: 30 Sep 2013, 06:48

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 13:45

Für mp3-tags gab es, soweit ich mich erinnere, auch windows-native Verfahren. Vielleicht funktioniert das auch heutzutage noch: https://autohotkey.com/board/topic/83376-ahk-l-read-id3-tags-function/ Ansonsten gibt es auch dlls von Drittanbietern, die sowas können (audiogenie gab es mal und wurde auch im Forum behandelt).

Bei anderen Formaten muss man ggf. mal gucken, ob man das auch mit Windowsbordmitteln hinkriegt - die beiden verlinkten Verfahren für exif und mp3 verwenden ja offenbar beide ComObjCreate("Shell.Application") und NameSpace... vielleicht geht das auch mit anderen Dateiformaten. Aber man muss dann in den entspechenden Tag-Standard reingucken, denk ich, um die richtigen Einträge zu finden (die mp3-Lösung listet ja schon eine ganze Reihe).

Edit: die mp3-Lösung scheint schon mal zu funktionieren auf meinem Win10.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MD5 wert ist gleich bei verschiedenen files?

12 Feb 2019, 14:50

Es würde eventuell auch sinn machen nur die rohdaten zu extrahieren. Also nur die Daten der Pixel im Bild.
Recommends AHK Studio

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 51 guests