如何在AHK Windows 10中生成字符串的MD5?

时间:2016-01-06 11:05:36

标签: md5 autohotkey

我尝试了https://github.com/acmeism/RosettaCodeData/blob/master/Task/MD5/AutoHotkey/md5-1.ahk中的代码,其中 与Windows 7一起使用:

data := "abc"
MsgBox % MD5(data,StrLen(data)) ; 900150983cd24fb0d6963f7d28e17f72

MD5( ByRef V, L=0 ) {
 VarSetCapacity( MD5_CTX,104,0 ), DllCall( "advapi32\MD5Init", Str,MD5_CTX )
 DllCall( "advapi32\MD5Update", Str,MD5_CTX, Str,V, UInt,L ? L : VarSetCapacity(V) )
 DllCall( "advapi32\MD5Final", Str,MD5_CTX )
 Loop % StrLen( Hex:="123456789ABCDEF0" )
  N := NumGet( MD5_CTX,87+A_Index,"Char"), MD5 .= SubStr(Hex,N>>4,1) . SubStr(Hex,N&15,1)
Return MD5
}

但是,某些dll调用现在必须不起作用,因为会使用Windows 10返回正确的值。例如,给定的代码段返回70350F6027BCE3713F6B76473084309B而不是{ {1}}。我也试过用管理员权限运行它。不知道这背后的原因是什么。由于某种原因,我无法直接访问advapi32 dll中的MD5函数。

我该怎么做才能获得正确的MD5哈希?

2 个答案:

答案 0 :(得分:0)

不确定它是否可以在Windows 10上运行,但在Rosetta代码上发布了一个Native版本:

http://rosettacode.org/wiki/MD5#Native_implementation

资料来源:Laszlo的AutoHotkey forum

; GLOBAL CONSTANTS r[64], k[64] 
r =  12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22 
, 5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20 
, 4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23 
, 6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21 
StringSplit r, r, `, 
r0 := 7 
Loop 64 
   i := A_Index-1, k%i% := floor(abs(sin(A_Index)) * 2**32) 

; TEST CASES 
MsgBox % MD5(x:="", 0) ; d41d8cd98f00b204e9800998ecf8427e 
MsgBox % MD5(x:="a", StrLen(x)) ; 0cc175b9c0f1b6a831c399e269772661 
MsgBox % MD5(x:="abc", StrLen(x)) ; 900150983cd24fb0d6963f7d28e17f72 
MsgBox % MD5(x:="message digest", StrLen(x)) ; f96b697d7cb7938d525a2f31aaf161d0 
MsgBox % MD5(x:="abcdefghijklmnopqrstuvwxyz", StrLen(x))
; c3fcd3d76192e4007dfb496cca67e13b 
MsgBox % MD5(x:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", StrLen(x))
; d174ab98d277d9f5a5611c2c9f419d9f 
MsgBox % MD5(x:="12345678901234567890123456789012345678901234567890123456789012345678901234567890", StrLen(x))
; 57edf4a22be3c955ac49da2e2107b67a 
MsgBox % MD5(x:="The quick brown fox jumps over the lazy dog", StrLen(x))
; 9e107d9d372bb6826bd81d3542a419d6 
MsgBox % MD5(x:="The quick brown fox jumps over the lazy cog", StrLen(x))
; 1055d3e698d289f2af8663725127bd4b 

MD5(ByRef Buf, L) { ; Binary buffer, Length in bytes 
   Static P, Q, N, i, a,b,c,d, t, h0,h1,h2,h3, y = 0xFFFFFFFF 

   h0 := 0x67452301, h1 := 0xEFCDAB89, h2 := 0x98BADCFE, h3 := 0x10325476 

   N := ceil((L+9)/64)*64 ; padded length (100..separator, 8B length) 
   VarSetCapacity(Q,N,0)  ; room for padded data 
   P := &Q ; pointer 
   DllCall("RtlMoveMemory", UInt,P, UInt,&Buf, UInt,L) ; copy data 
   DllCall("RtlFillMemory", UInt,P+L, UInt,1, UInt,0x80) ; pad separator 
   DllCall("ntdll.dll\RtlFillMemoryUlong",UInt,P+N-8,UInt,4,UInt,8*L) ; at end: length in bits < 512 MB 

   Loop % N//64 { 
      Loop 16 
         i := A_Index-1, w%i% := *P | *(P+1)<<8 | *(P+2)<<16 | *(P+3)<<24, P += 4 

      a := h0, b := h1, c := h2, d := h3 

      Loop 64 { 
         i := A_Index-1 
         If i < 16 
             f := (b & c) | (~b & d), g := i 
         Else If i < 32 
             f := (d & b) | (~d & c), g := 5*i+1 & 15 
         Else If i < 48 
             f := b ^ c ^ d,          g := 3*i+5 & 15 
         Else 
             f := c ^ (b | ~d),       g :=  7*i  & 15 

         t := d, d := c, c := b 
         b += rotate(a + f + k%i% + w%g%, r%i%) ; reduced to 32 bits later 
         a := t 
      } 

      h0 := h0+a & y, h1 := h1+b & y, h2 := h2+c & y, h3 := h3+d & y 
   } 
   Return hex(h0) . hex(h1) . hex(h2) . hex(h3) 
} 

rotate(a,b) { ; 32-bit rotate a to left by b bits, bit32..63 garbage 
   Return a << b | (a & 0xFFFFFFFF) >> (32-b) 
} 

hex(x) {      ; 32-bit little endian hex digits 
   SetFormat Integer, HEX 
   x += 0x100000000, x := SubStr(x,-1) . SubStr(x,8,2) . SubStr(x,6,2) . SubStr(x,4,2) 
   SetFormat Integer, DECIMAL 
   Return x 
}

答案 1 :(得分:0)

来自 jNizM 的这些哈希函数似乎有效:https://www.autohotkey.com/boards/viewtopic.php?f=6&t=21

对于 MD5:

md5(string)     ;   // by SKAN | rewritten by jNizM
{
    hModule := DllCall("LoadLibrary", "Str", "advapi32.dll", "Ptr")
    , VarSetCapacity(MD5_CTX, 104, 0), DllCall("advapi32\MD5Init", "Ptr", &MD5_CTX)
    , DllCall("advapi32\MD5Update", "Ptr", &MD5_CTX, "AStr", string, "UInt", StrLen(string))
    , DllCall("advapi32\MD5Final", "Ptr", &MD5_CTX)
    loop, 16
        o .= Format("{:02" (case ? "X" : "x") "}", NumGet(MD5_CTX, 87 + A_Index, "UChar"))
    DllCall("FreeLibrary", "Ptr", hModule)
    StringLower, o,o
    return o
}