diff --git a/DynamicPassword.ahk b/DynamicPassword.ahk index 4128ef7..fa4b452 100755 --- a/DynamicPassword.ahk +++ b/DynamicPassword.ahk @@ -1,45 +1,91 @@ +; ============================================================================== +; DynamicPassword.ahk +; Deterministic Password Generator +; ============================================================================== +; This script generates a unique, complex password based on a service name +; and a personal salt. The password is never stored and is generated on-the-fly. +; ============================================================================== + #NoEnv #SingleInstance force -#Persistent +#Persistent +; --- Hotkeys --- + +; WIN + F1: Generate a 32-character password #F1:: -Password(32) + Password(32) return +; WIN + F2: Generate a 16-character password #F2:: -Password(16) + Password(16) return +; --- Core Logic --- + Password(Length) { -InputBox, Service, Website/Service, Enter the name of the site:, , 200, 130 -InputBox, Salt, Password Salt, Enter a salt password:, hide , 200, 130 -Hash := MD5(MD5(Service)Salt)MD5(MD5(Salt)Service) -Loop, %Length% { -Char := SubStr(Hash, A_Index*2-1, 2) -Char2Hex = 0x%Char% -Hex := Chr(Round((Char2Hex + 0)/2.74)+33) -Pwd := Pwd Hex -} -Clipboard:=Pwd -MouseGetPos x1, y1 -ToolTip, Password copied to clipboard, %x1%, %y1% -SetTimer, RemoveToolTip, 1000 -Sleep, 1000 -Reload + ; Prompt for the website or service name (e.g., "gmail") + InputBox, Service, Website/Service, Enter the name of the site:, , 200, 130 + if (ErrorLevel) ; User cancelled + return + + ; Prompt for the personal salt (a simple password only you know) + InputBox, Salt, Password Salt, Enter a salt password:, hide , 200, 130 + if (ErrorLevel) ; User cancelled + return + + ; Generate a complex hash by combining MD5 of Service and Salt in a cross-pattern + ; This creates a unique signature for the site/salt combination. + Hash := MD5(MD5(Service) . Salt) . MD5(MD5(Salt) . Service) + + ; Map the hash characters to a wider range of ASCII symbols + ; to create a complex password. + Pwd := "" + Loop, %Length% { + ; Extract 2 characters from the hash + Char := SubStr(Hash, A_Index * 2 - 1, 2) + Char2Hex := "0x" . Char + + ; Transform the hex value into a printable ASCII character (Range: 33-126) + ; Logic: (HexValue / 2.74) + 33 maps 0-255 to roughly 33-126 range. + Hex := Chr(Round((Char2Hex + 0) / 2.74) + 33) + Pwd .= Hex + } + + ; Copy to clipboard and notify the user + Clipboard := Pwd + MouseGetPos, x1, y1 + ToolTip, Password copied to clipboard, %x1%, %y1% + + ; Auto-hide the tooltip after 1 second + SetTimer, RemoveToolTip, 1000 + Sleep, 1000 + + ; Reload the script to clear variables from memory for extra security + Reload } -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 +; MD5 Hashing Function using Windows Crypto API (advapi32) +MD5(ByRef V, L = 0) { + VarSetCapacity(MD5_CTX, 104, 0) + DllCall("advapi32\MD5Init", "Ptr", &MD5_CTX) + DllCall("advapi32\MD5Update", "Ptr", &MD5_CTX, "Str", V, "UInt", L ? L : VarSetCapacity(V)) + DllCall("advapi32\MD5Final", "Ptr", &MD5_CTX) + + Hex := "123456789ABCDEF0" + Loop 16 { + N := NumGet(MD5_CTX, 87 + A_Index, "UChar") + MD5 .= SubStr(Hex, N >> 4, 1) . SubStr(Hex, N & 15, 1) + } + Return MD5 } +; ToolTip Cleanup RemoveToolTip: -SetTimer, RemoveToolTip, Off -ToolTip + SetTimer, RemoveToolTip, Off + ToolTip return +