LC_Version := "0.0.24.04" #Requires Autohotkey v2.0 LC_ASCII2Bin(s, pretty := 0) { r := "" l := StrLen(s) for i, ch in StrSplit(s) { byte := Ord(ch) bits := "" Loop 8 { bit := (byte & (1 << (A_Index - 1))) ? "1" : "0" bits := bit bits } r .= bits if (pretty && i < l) r .= " " } return r } LC_Ascii2Bin2(Ascii) { Out := "" for Char in StrSplit(Ascii) Loop 8 Out .= !!(Ord(Char) & (1 << (8 - A_Index))) return Out } LC_Bin2Ascii(Bin) { Bin := RegExReplace(Bin, "[^10]") Loop StrLen(Bin) / 8 { Asc := 0 for Bit in StrSplit(SubStr(Bin, (A_Index - 1) * 8 + 1, 8)) Asc += Asc + Bit Out .= Chr(Asc) } return Out } LC_BinStr_EncodeText(Text, Pretty := False, Encoding := "UTF-8") { Len := StrPut(Text, Encoding) Buf := Buffer(Len) StrPut(Text, Buf, Encoding) BinStr := "" LC_BinStr_Encode(&BinStr, &Buf, Len, Pretty) return BinStr } LC_BinStr_DecodeText(Text, Encoding := "UTF-8") { Len := LC_BinStr_Decode(&Buf, Text) ; Buf wird als Buffer gefüllt, Len = Bytes return StrGet(Buf, Len, Encoding) } LC_BinStr_Encode(&Out, &InBuf, InLen, Pretty := False) { Out := "" Loop InLen { Byte := NumGet(InBuf, A_Index - 1, "UChar") Loop 8 Out .= (Byte >> (8 - A_Index)) & 1 if Pretty Out .= " " } } LC_BinStr_Decode(&Out, InTxt) { ; Optional: nur 0/1 behalten, falls In Leerzeichen o.ä. enthalten kann ; In := RegExReplace(In, "[^01]") ByteCount := StrLen(InTxt) // 8 Out := Buffer(ByteCount, 0) BitIndex := 1 Loop ByteCount { Byte := 0 Loop 8 { Byte := (Byte << 1) | SubStr(InTxt, BitIndex, 1) BitIndex += 1 } NumPut("UChar", Byte, Out, A_Index - 1) } return ByteCount } ; implemented in ahk by joedf ; based on https://github.com/cryptii/cryptii/blob/4a0a58318d093c4c6e3333b3f296ad7c96309629/src/Encoder/Ascii85.js /** * Performs encode on given content. * @param {String} content * @param {String} variant * @return {String} Encoded content */ LC_ASCII85_Encode(content, variant := "") { content := StrReplace(content, "<~") content := StrReplace(content, "~>") bytes := [] for ch in StrSplit(content) bytes.Push(Ord(ch)) variant := __LC_ASCII85_getVariant(variant) n := bytes.Length string := "" i := 1 while (i <= n) { if (i - 1 + 4 > n) bytes.Push(0, 0, 0) tuple := ((bytes[i] << 24) + (bytes[i + 1] << 16) + (bytes[i + 2] << 8) + bytes[i + 3]) >> 0 if (variant["zeroTupleChar"] = "null") || (tuple > 0) { digits := [] Loop 5 { digits.Push(Mod(tuple, 85)) tuple := tuple // 85 } newarr := [] for t_idx, t_val in digits newarr.InsertAt(1, t_val) digits := newarr if (n < (i - 1 + 4)) digits := __LC_ASCII85_splice(digits, n - (i - 1 + 4), 4) for t_k, t_v in digits string .= (variant["alphabet"] = "null") ? Chr(t_v + 33) : SubStr(variant["alphabet"], t_v + 1, 1) } else { string .= variant["zeroTupleChar"] } i += 4 } return string } LC_ASCII85_Decode(content, variant := "") { string := Trim(content) variant := __LC_ASCII85_getVariant(variant) n := StrLen(string) bytes := [] i := 1 while (i <= n) { if (SubStr(string, i, 1) = variant.zeroTupleChar) { bytes.Push(0, 0, 0, 0) i++ } else { digits := [] for character in StrSplit(SubStr(string, i, 5)) { digit := (variant["alphabet"] = "null") ? Ord(character) - 33 : InStr(variant["alphabet"], character) - 1 if (digit < 0 || digit > 84) throw Error(Format("Invalid character '{1}' at index {2}", character, i + A_Index - 1)) digits.Push(digit) } tuple := 0 + digits[1] * 52200625 + digits[2] * 614125 + ((i - 1 + 2 < n) ? digits[3] : 84) * 7225 + ((i - 1 + 3 < n) ? digits[4] : 84) * 85 + ((i - 1 + 4 < n) ? digits[5] : 84) tupleBytes := [ (tuple >> 24) & 0xFF, (tuple >> 16) & 0xFF, (tuple >> 8) & 0xFF, tuple & 0xFF ] if (n < i - 1 + 5) tupleBytes := __LC_ASCII85_splice(tupleBytes, n - (i - 1 + 5), 5) for t_v in tupleBytes bytes.Push(t_v) i += 5 } } decoded := "" for v in bytes decoded .= Chr(v) return decoded } __LC_ASCII85_getVariant(variant := "") { if InStr(variant, "z") return { name: "Z85" , label: "Z85 (ZeroMQ)" , alphabet: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#" , zeroTupleChar: "null" } return { name: "original" , label: "Original" , alphabet: "null" , zeroTupleChar: "z" } } __LC_ASCII85_splice(arr, start, deleteCount := "") { len := arr.Length newarr := [] startIndex := start if (start > len) startIndex := len else if (start < 0) startIndex := len + start if (len + start < 0) startIndex := 0 Loop startIndex newarr.Push(arr[A_Index]) if (deleteCount != "") { if (deleteCount < 0) deleteCount := 0 j := 1 + startIndex + deleteCount while (j <= len) { newarr.Push(arr[j]) j++ } } return newarr } LC_Base64_EncodeText(Text, Encoding := "UTF-8") { Len := StrPut(Text, Encoding) Bin := Buffer(Len) StrPut(Text, Bin, Encoding) Base64 := "" LC_Base64_Encode(&Base64, &Bin, Len) return Base64 } LC_Base64_DecodeText(Text, Encoding := "UTF-8") { Len := LC_Base64_Decode(&Bin, Text) return StrGet(Bin, Len, Encoding) } LC_Base64_Encode(&Out, &InBin, InLen) { return LC_Bin2Str(&Out, &InBin, InLen, 0x40000001) } LC_Base64_Decode(&Out, InTxt) { ; In ist hier ein String (Base64), Out soll ein Buffer werden return LC_Str2Bin(&Out, InTxt, 0x1) } LC_Bin2Hex(&Out, &InBin, InLen, Pretty := False) { return LC_Bin2Str(&Out, &InBin, InLen, Pretty ? 0xb : 0x4000000c) } LC_Hex2Bin(&Out, InHex) { return LC_Str2Bin(&Out, InHex, 0x8) } LC_Bin2Str(&Out, &InBin, InLen, Flags) { DllCall("Crypt32.dll\CryptBinaryToString", "ptr", InBin, "uint", InLen, "uint", Flags, "ptr", 0, "uint*", &OutLen) Out := Buffer(OutLen * 2) DllCall("Crypt32.dll\CryptBinaryToString", "ptr", InBin, "uint", InLen, "uint", Flags, "ptr", Out, "uint*", &OutLen) return OutLen } LC_Str2Bin(&Out, InSt, Flags) { DllCall("Crypt32.dll\CryptStringToBinary", "ptr", InSt, "uint", StrLen(InSt), "uint", Flags, "ptr", 0, "uint*", &OutLen, "ptr", 0, "ptr", 0) Out := Buffer(OutLen) DllCall("Crypt32.dll\CryptStringToBinary", "ptr", InSt, "uint", StrLen(InSt), "uint", Flags, "ptr", Out, "uint*", &OutLen, "ptr", 0, "ptr", 0) return OutLen } ; ; Version: 2014.03.06-1518, jNizM ; see https://en.wikipedia.org/wiki/Caesar_cipher ; =================================================================================== LC_Caesar(string, num := 2) { ret := "" loop parse string { c := Ord(A_LoopField) if (c > 64) && (c < 91) ret .= Chr(Mod(c - 65 + num, 26) + 65) else if (c > 96) && (c < 123) ret .= Chr(Mod(c - 97 + num, 26) + 97) else ret .= A_LoopField } return ret } LC_CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0) { static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"] static b := h.minIndex() hProv := hHash := o := "" if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000)) { if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash)) { if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0)) { if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0)) { VarSetCapacity(hash, hashlength, 0) if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0)) { loop % hashlength { v := NumGet(hash, A_Index - 1, "UChar") o .= h[(v >> 4) + b] h[(v & 0xf) + b] } } } } DllCall("advapi32\CryptDestroyHash", "Ptr", hHash) } DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0) } return o } LC_CalcStringHash(string, algid, encoding = "UTF-8", byref hash = 0, byref hashlength = 0) { chrlength := (encoding = "CP1200" || encoding = "UTF-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength VarSetCapacity(data, length, 0) StrPut(string, &data, floor(length / chrlength), encoding) return LC_CalcAddrHash(&data, length, algid, hash, hashlength) } LC_CalcHexHash(hexstring, algid) { length := StrLen(hexstring) // 2 VarSetCapacity(data, length, 0) loop % length { NumPut("0x" SubStr(hexstring, 2 * A_Index - 1, 2), data, A_Index - 1, "Char") } return LC_CalcAddrHash(&data, length, algid) } LC_CalcFileHash(filename, algid, continue = 0, byref hash = 0, byref hashlength = 0) { fpos := "" if (!(f := FileOpen(filename, "r"))) { return } f.pos := 0 if (!continue && f.length > 0x7fffffff) { return } if (!continue) { VarSetCapacity(data, f.length, 0) f.rawRead(&data, f.length) f.pos := oldpos return LC_CalcAddrHash(&data, f.length, algid, hash, hashlength) } hashlength := 0 while (f.pos < f.length) { readlength := (f.length - fpos > continue) ? continue : f.length - f.pos VarSetCapacity(data, hashlength + readlength, 0) DllCall("RtlMoveMemory", "Ptr", &data, "Ptr", &hash, "Ptr", hashlength) f.rawRead(&data + hashlength, readlength) h := LC_CalcAddrHash(&data, hashlength + readlength, algid, hash, hashlength) } return h } LC_CRC32(string, encoding = "UTF-8") { chrlength := (encoding = "CP1200" || encoding = "UTF-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength VarSetCapacity(data, length, 0) StrPut(string, &data, floor(length / chrlength), encoding) hMod := DllCall("Kernel32.dll\LoadLibrary", "Str", "Ntdll.dll") SetFormat, Integer, % SubStr((A_FI := A_FormatInteger) "H", 0) CRC32 := DllCall("Ntdll.dll\RtlComputeCrc32", "UInt", 0, "UInt", &data, "UInt", length, "UInt") CRC := SubStr(CRC32 | 0x1000000000, -7) DllCall("User32.dll\CharLower", "Str", CRC) SetFormat, Integer, %A_FI% return CRC, DllCall("Kernel32.dll\FreeLibrary", "Ptr", hMod) } LC_HexCRC32(hexstring) { length := StrLen(hexstring) // 2 VarSetCapacity(data, length, 0) loop % length { NumPut("0x" SubStr(hexstring, 2 * A_Index -1, 2), data, A_Index - 1, "Char") } hMod := DllCall("Kernel32.dll\LoadLibrary", "Str", "Ntdll.dll") SetFormat, Integer, % SubStr((A_FI := A_FormatInteger) "H", 0) CRC32 := DllCall("Ntdll.dll\RtlComputeCrc32", "UInt", 0, "UInt", &data, "UInt", length, "UInt") CRC := SubStr(CRC32 | 0x1000000000, -7) DllCall("User32.dll\CharLower", "Str", CRC) SetFormat, Integer, %A_FI% return CRC, DllCall("Kernel32.dll\FreeLibrary", "Ptr", hMod) } LC_FileCRC32(sFile := "", cSz := 4) { Bytes := "" cSz := (cSz < 0 || cSz > 8) ? 2**22 : 2**(18 + cSz) VarSetCapacity(Buffer, cSz, 0) hFil := DllCall("Kernel32.dll\CreateFile", "Str", sFile, "UInt", 0x80000000, "UInt", 3, "Int", 0, "UInt", 3, "UInt", 0, "Int", 0, "UInt") if (hFil < 1) { return hFil } hMod := DllCall("Kernel32.dll\LoadLibrary", "Str", "Ntdll.dll") CRC32 := 0 DllCall("Kernel32.dll\GetFileSizeEx", "UInt", hFil, "Int64", &Buffer), fSz := NumGet(Buffer, 0, "Int64") loop % (fSz // cSz + !!Mod(fSz, cSz)) { DllCall("Kernel32.dll\ReadFile", "UInt", hFil, "Ptr", &Buffer, "UInt", cSz, "UInt*", Bytes, "UInt", 0) CRC32 := DllCall("Ntdll.dll\RtlComputeCrc32", "UInt", CRC32, "UInt", &Buffer, "UInt", Bytes, "UInt") } DllCall("Kernel32.dll\CloseHandle", "Ptr", hFil) SetFormat, Integer, % SubStr((A_FI := A_FormatInteger) "H", 0) CRC32 := SubStr(CRC32 + 0x1000000000, -7) DllCall("User32.dll\CharLower", "Str", CRC32) SetFormat, Integer, %A_FI% return CRC32, DllCall("Kernel32.dll\FreeLibrary", "Ptr", hMod) } ;from joedf : fork-fusion of jNizM+Laszlo's functions [to_decimal()+ToBase()] LC_To_Dec(b, n) { ; 1 < b <= 36, n >= 0 d:=0 StringUpper,n,n loop % StrLen(n) { d *= b, k:=SubStr(n,A_Index,1) if k is not Integer k:=Asc(k)-55 d += k } return d } ;from Laszlo : http://www.autohotkey.com/board/topic/15951-base-10-to-base-36-conversion/#entry103624 LC_From_Dec(b,n) { ; 1 < b <= 36, n >= 0 Loop { d := mod(n,b), n //= b m := (d < 10 ? d : Chr(d+55)) . m IfLess n,1, Break } Return m } LC_Dec2Hex(x) { return LC_From_Dec(16,x) } LC_Hex2Dec(x) { return LC_To_Dec(16,x) } LC_Numvert(num,from,to) { ; from joedf : http://ahkscript.org/boards/viewtopic.php?f=6&t=6363 return LC_From_Dec(to,LC_To_Dec(from,num)) } ; ; Date Updated: ; Friday, November 23rd, 2012 - Tuesday, February 10th, 2015 ; ; Script Function: ; Function Library to Encrypt / Decrypt in Div2 (by Joe DF) ; Div2 was invented with a friend for fun, back in ~2010. ; The string is "divided" in 2 during encryption. It is a ; simple reordering of the characters in a string. The was ; to have a human-readable/decryptable message. ; ; Notes: ; AutoTrim should turned off, for the encryption to work properly ; because, in Div2, and count as a character. ; LC_Div2_encode(input, WithAutoTrim:=1, numproc:=1) { if (WithAutoTrim) StringReplace,input,input,%A_Space%,_,A loop, %numproc% { final:="", inputlen := StrLen(input) divmax := ceil((0.5 * inputlen) + 1) loop, %inputlen% { temp := SubStr(input,A_Index,1) q := inputlen + 1 - A_Index temp2 := SubStr(input,q,1) if (A_Index < divmax) { final .= temp if (A_Index != q) final .= temp2 } if (A_Index >= divmax) Break } input := final } return final } LC_Div2_decode(input, WithAutoTrim:=1, numproc:=1) { if (WithAutoTrim) StringReplace,input,input,%A_Space%,_,A loop, %numproc% { i := 1, final:="", inputlen := StrLen(input) loop, % loopc := ceil(inputlen * (1/2)) { if (i <= inputlen) final .= SubStr(input,i,1) i += 2 } i := inputlen loop, %loopc% { if (i <= inputlen) { if (mod(SubStr(i,0,1)+0,2)==1) { if (i != 1) final .= SubStr(input,i-1,1) } else { final .= SubStr(input,i,1) } } i -= 2 } input := final } return final } LC_HMAC(Key, Message, Algo := "MD5") { static Algorithms := {MD2: {ID: 0x8001, Size: 64} , MD4: {ID: 0x8002, Size: 64} , MD5: {ID: 0x8003, Size: 64} , SHA: {ID: 0x8004, Size: 64} , SHA256: {ID: 0x800C, Size: 64} , SHA384: {ID: 0x800D, Size: 128} , SHA512: {ID: 0x800E, Size: 128}} static iconst := 0x36 static oconst := 0x5C if (!(Algorithms.HasKey(Algo))) { return "" } Hash := KeyHashLen := InnerHashLen := "" HashLen := 0 AlgID := Algorithms[Algo].ID BlockSize := Algorithms[Algo].Size MsgLen := StrPut(Message, "UTF-8") - 1 KeyLen := StrPut(Key, "UTF-8") - 1 VarSetCapacity(K, KeyLen + 1, 0) StrPut(Key, &K, KeyLen, "UTF-8") if (KeyLen > BlockSize) { LC_CalcAddrHash(&K, KeyLen, AlgID, KeyHash, KeyHashLen) } VarSetCapacity(ipad, BlockSize + MsgLen, iconst) Addr := KeyLen > BlockSize ? &KeyHash : &K Length := KeyLen > BlockSize ? KeyHashLen : KeyLen i := 0 while (i < Length) { NumPut(NumGet(Addr + 0, i, "UChar") ^ iconst, ipad, i, "UChar") i++ } if (MsgLen) { StrPut(Message, &ipad + BlockSize, MsgLen, "UTF-8") } LC_CalcAddrHash(&ipad, BlockSize + MsgLen, AlgID, InnerHash, InnerHashLen) VarSetCapacity(opad, BlockSize + InnerHashLen, oconst) Addr := KeyLen > BlockSize ? &KeyHash : &K Length := KeyLen > BlockSize ? KeyHashLen : KeyLen i := 0 while (i < Length) { NumPut(NumGet(Addr + 0, i, "UChar") ^ oconst, opad, i, "UChar") i++ } Addr := &opad + BlockSize i := 0 while (i < InnerHashLen) { NumPut(NumGet(InnerHash, i, "UChar"), Addr + i, 0, "UChar") i++ } return LC_CalcAddrHash(&opad, BlockSize + InnerHashLen, AlgID) } /* from AHK forums Fast 64- and 128-bit hash functions Originally created by Laszlo , Jan 01 2007 06:59 PM https://autohotkey.com/board/topic/14040-fast-64-and-128-bit-hash-functions/ Here are two of hash functions, which - are programmed fully in AHK - are much faster than cryptographic hash functions - provide long enough hash values (64 or 128 bits), so a collision is very unlikely They are modeled after Linear Feedback Shift Register (LFSR) based hash functions, like CRC-32. joedf: modified/updated for inclusion in libcrypt.ahk The dynamic __LC_LHashTable global array variable is kept global in the interest of speed for successive calls. */ LC_L64Hash(x) { ; 64-bit generalized LFSR hash of string x Local i, R = 0 __LC_LHash_LHashInit() ; 1st time set LHASH0..LHAS256 global table Loop Parse, x { i := (R >> 56) & 255 ; dynamic vars are global R := (R << 8) + Asc(A_LoopField) ^ __LC_LHashTable%i% } Return __LC_LHash_Hex8(R>>32) . __LC_LHash_Hex8(R) } LC_L128Hash(x) { ; 128-bit generalized LFSR hash of string x Local i, S = 0, R = -1 __LC_LHash_LHashInit() ; 1st time set LHASH0..LHAS256 global table Loop Parse, x { i := (R >> 56) & 255 ; dynamic vars are global R := (R << 8) + Asc(A_LoopField) ^ __LC_LHashTable%i% i := (S >> 56) & 255 S := (S << 8) + Asc(A_LoopField) - __LC_LHashTable%i% } Return __LC_LHash_Hex8(R>>32) . __LC_LHash_Hex8(R) . __LC_LHash_Hex8(S>>32) . __LC_LHash_Hex8(S) } __LC_LHash_Hex8(i) { ; integer -> LS 8 hex digits SetFormat Integer, Hex i:= 0x100000000 | i & 0xFFFFFFFF ; mask LS word, set bit32 for leading 0's --> hex SetFormat Integer, D Return SubStr(i,-7) ; 8 LS digits = 32 unsigned bits } __LC_LHash_LHashInit() { ; build pseudorandom substitution table Local i, u = 0, v = 0 If __LC_LHashTable0= Loop 256 { i := A_Index - 1 __LC_LHASH_TEA(u,v, 1,22,333,4444, 8) ; <- to be portable, no Random() __LC_LHashTable%i% := (u<<32) | v } } ; ; [y,z] = 64-bit I/0 block, [k0,k1,k2,k3] = 128-bit key __LC_LHASH_TEA(ByRef y,ByRef z, k0,k1,k2,k3, n = 32) { ; n = #Rounds s := 0, d := 0x9E3779B9 Loop %n% { ; standard = 32, 8 for speed k := "k" . s & 3 ; indexing the key y := 0xFFFFFFFF & (y + ((z << 4 ^ z >> 5) + z ^ s + %k%)) s := 0xFFFFFFFF & (s + d) ; simulate 32 bit operations k := "k" . s >> 11 & 3 z := 0xFFFFFFFF & (z + ((y << 4 ^ y >> 5) + y ^ s + %k%)) } } LC_MD2(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x8001, encoding) } LC_HexMD2(hexstring) { return LC_CalcHexHash(hexstring, 0x8001) } LC_FileMD2(filename) { return LC_CalcFileHash(filename, 0x8001, 64 * 1024) } LC_AddrMD2(addr, length) { return LC_CalcAddrHash(addr, length, 0x8001) } LC_MD4(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x8002, encoding) } LC_HexMD4(hexstring) { return LC_CalcHexHash(hexstring, 0x8002) } LC_FileMD4(filename) { return LC_CalcFileHash(filename, 0x8002, 64 * 1024) } LC_AddrMD4(addr, length) { return LC_CalcAddrHash(addr, length, 0x8002) } LC_MD5(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x8003, encoding) } LC_HexMD5(hexstring) { return LC_CalcHexHash(hexstring, 0x8003) } LC_FileMD5(filename) { return LC_CalcFileHash(filename, 0x8003, 64 * 1024) } LC_AddrMD5(addr, length) { return LC_CalcAddrHash(addr, length, 0x8003) } ;nnnik's custom encryption algorithm ;Version 2.1 of the encryption/decryption functions LC_nnnik21_encryptStr(str="",pass="") { If !(enclen:=(strput(str,"utf-16")*2)) return "Error: Nothing to Encrypt" If !(passlen:=strput(pass,"utf-8")-1) return "Error: No Pass" enclen:=Mod(enclen,4) ? (enclen) : (enclen-2) Varsetcapacity(encbin,enclen,0) StrPut(str,&encbin,enclen/2,"utf-16") Varsetcapacity(passbin,passlen+=mod((4-mod(passlen,4)),4),0) StrPut(pass,&passbin,strlen(pass),"utf-8") LC_nnnik21_encryptbin(&encbin,enclen,&passbin,passlen) LC_Base64_Encode(Text, encbin, enclen) return Text } LC_nnnik21_decryptStr(str="",pass="") { If !((strput(str,"utf-16")*2)) return "Error: Nothing to Decrypt" If !((passlen:=strput(pass,"utf-8")-1)) return "Error: No Pass" Varsetcapacity(passbin,passlen+=mod((4-mod(passlen,4)),4),0) StrPut(pass,&passbin,strlen(pass),"utf-8") enclen:=LC_Base64_Decode(encbin, str) LC_nnnik21__decryptbin(&encbin,enclen,&passbin,passlen) return StrGet(&encbin,"utf-16") } LC_nnnik21_encryptbin(pBin1,sBin1,pBin2,sBin2) { b:=0 Loop % sBin1/4 { a:=numget(pBin1+0,sBin1-A_Index*4,"uint") numput(a+b,pBin1+0,sBin1-A_Index*4,"uint") b:=(a+b)*a } Loop % sBin2/4 { c:=numget(pBin2+0,(A_Index-1)*4,"uint") b:=0 Loop % sBin1/4 { a:=numget(pBin1+0,(A_Index-1)*4,"uint") numput((a+b)^c,pBin1+0,(A_Index-1)*4,"uint") b:=(a+b)*a } } } LC_nnnik21__decryptbin(pBin1,sBin1,pBin2,sBin2){ Loop % sBin2/4 { c:=numget(pBin2+0,sBin2-A_Index*4,"uint") b:=0 Loop % sBin1/4 { a:=numget(pBin1+0,(A_Index-1)*4,"uint") numput(a:=(a^c)-b,pBin1+0,(A_Index-1)*4,"uint") b:=(a+b)*a } } b:=0 Loop % sBin1/4 { a:=numget(pBin1+0,sBin1-A_Index*4,"uint") numput(a:=a-b,pBin1+0,sBin1-A_Index*4,"uint") b:=(a+b)*a } } LC_RC4_Encrypt(Data,Pass) { b:=0,j:=0,Key:=Object(),sBox:=Object() VarSetCapacity(Result,StrLen(Data)*2) Loop 256 a:=(A_Index-1),Key[a]:=Asc(SubStr(Pass,Mod(a,StrLen(Pass))+1,1)),sBox[a]:=a Loop 256 a:=(A_Index-1),b:=(b+sBox[a]+Key[a])&255,sBox[a]:=(sBox[b]+0,sBox[b]:=sBox[a]) ; SWAP(a,b) Loop Parse, Data i:=(A_Index&255),j:=(sBox[i]+j)&255,k:=(sBox[i]+sBox[j])&255,sBox[i]:=(sBox[j]+0,sBox[j]:=sBox[i]) ; SWAP(i,j) ,Result.=format("{:02x}", Asc(A_LoopField)^sBox[k]) Return Result } LC_RC4_Decrypt(Data,Pass) { b:=0,j:=0,x:="0x",Key:=Object(),sBox:=Object() VarSetCapacity(Result,StrLen(Data)//2) Loop 256 a:=(A_Index-1),Key[a]:=Asc(SubStr(Pass,Mod(a,StrLen(Pass))+1,1)),sBox[a]:=a Loop 256 a:=(A_Index-1),b:=(b+sBox[a]+Key[a])&255,sBox[a]:=(sBox[b]+0,sBox[b]:=sBox[a]) ; SWAP(a,b) Loop % StrLen(Data)//2 i:=(A_Index&255),j:=(sBox[i]+j)&255,k:=(sBox[i]+sBox[j])&255,sBox[i]:=(sBox[j]+0,sBox[j]:=sBox[i]) ; SWAP(i,j) ,Result.=Chr((x . SubStr(Data,(2*A_Index)-1,2))^sBox[k]) Return Result } LC_RC4(RC4Data,RC4Pass) { ; Thanks Rajat for original, Updated Libcrypt version ; http://www.autohotkey.com/board/topic/570-rc4-encryption/page-2#entry25712 ATrim:=A_AutoTrim,BLines:=A_BatchLines,RC4PassLen:=StrLen(RC4Pass),Key:=Object(),sBox:=Object(),b:=0,RC4Result:="",i:=0,j:=0 AutoTrim,Off SetBatchlines,-1 Loop, 256 a:=(A_Index-1),ModVal:=Mod(a,RC4PassLen),c:=SubStr(RC4Pass,ModVal+=1,1),Key[a]:=Asc(c),sBox[a]:=a Loop, 256 a:=(A_Index-1),b:=Mod(b+sBox[a]+Key[a],256),T:=sBox[a],sBox[a]:=sBox[b],sBox[b]:=T Loop, Parse, RC4Data i:=Mod(i+1,256),j:=Mod(sBox[i]+j,256),k:=sBox[Mod(sBox[i]+sBox[j],256)],c:=Asc(A_LoopField)^k,c:=((c==0)?k:c),RC4Result.=Chr(c) AutoTrim, %ATrim% SetBatchlines, %BLines% Return RC4Result } /* - ROT5 covers the numbers 0-9. - ROT13 covers the 26 upper and lower case letters of the Latin alphabet (A-Z, a-z). - ROT18 is a combination of ROT5 and ROT13. - ROT47 covers all printable ASCII characters, except empty spaces. Besides numbers and the letters of the Latin alphabet, the following characters are included: !"#$%&'()*+,-./:;<=>?[\]^_`{|}~ */ LC_Rot5(string) { Loop, Parse, string s .= (strlen((c:=A_LoopField)+0)?((c<5)?c+5:c-5):(c)) Return s } ; by Raccoon July-2009 ; http://rosettacode.org/wiki/Rot-13#AutoHotkey LC_Rot13(string) { Loop, Parse, string { c := asc(A_LoopField) if (c >= 97) && (c <= 109) || (c >= 65) && (c <= 77) c += 13 else if (c >= 110) && (c <= 122) || (c >= 78) && (c <= 90) c -= 13 s .= Chr(c) } Return s } LC_Rot18(string) { return LC_Rot13(LC_Rot5(string)) } ; adapted from http://langref.org/fantom+java+scala/strings/reversing-a-string/simple-substitution-cipher ; from decimal 33 '!' through 126 '~', 94 LC_Rot47(string) { Loop Parse, string { c := Asc(A_LoopField) c += (c >= Asc("!") && c <= Asc("O") ? 47 : (c >= Asc("P") && c <= Asc("~") ? -47 : 0)) s .= Chr(c) } Return s } ; RSHash (Robert Sedgewick's string hashing algorithm) ; from jNizM ; https://autohotkey.com/boards/viewtopic.php?p=87929#p87929 LC_RSHash(str) { a := 0xF8C9, b := 0x5C6B7, h := 0 loop, parse, str h := h * a + Asc(A_LoopField), a *= b return (h & 0x7FFFFFFF) } LC_SecureSalted(salt, message, algo := "md5") { hash := "" saltedHash := LC_%algo%(message . salt) saltedHashR := LC_%algo%(salt . message) len := StrLen(saltedHash) loop % len / 2 { byte1 := "0x" . SubStr(saltedHash, 2 * A_index - 1, 2) byte2 := "0x" . SubStr(saltedHashR, 2 * A_index - 1, 2) SetFormat, integer, hex hash .= StrLen(ns := SubStr(byte1 ^ byte2, 3)) < 2 ? "0" ns : ns } SetFormat, integer, dez return hash } LC_SHA(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x8004, encoding) } LC_HexSHA(hexstring) { return LC_CalcHexHash(hexstring, 0x8004) } LC_FileSHA(filename) { return LC_CalcFileHash(filename, 0x8004, 64 * 1024) } LC_AddrSHA(addr, length) { return LC_CalcAddrHash(addr, length, 0x8004) } LC_SHA256(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x800c, encoding) } LC_HexSHA256(hexstring) { return LC_CalcHexHash(hexstring, 0x800c) } LC_FileSHA256(filename) { return LC_CalcFileHash(filename, 0x800c, 64 * 1024) } LC_AddrSHA256(addr, length) { return LC_CalcAddrHash(addr, length, 0x800c) } LC_SHA384(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x800d, encoding) } LC_HexSHA384(hexstring) { return LC_CalcHexHash(hexstring, 0x800d) } LC_FileSHA384(filename) { return LC_CalcFileHash(filename, 0x800d, 64 * 1024) } LC_AddrSHA384(addr, length) { return LC_CalcAddrHash(addr, length, 0x800d) } LC_SHA512(string, encoding = "UTF-8") { return LC_CalcStringHash(string, 0x800e, encoding) } LC_HexSHA512(hexstring) { return LC_CalcHexHash(hexstring, 0x800e) } LC_FileSHA512(filename) { return LC_CalcFileHash(filename, 0x800e, 64 * 1024) } LC_AddrSHA512(addr, length) { return LC_CalcAddrHash(addr, length, 0x800e) } /* Written by Masonjar13 A static-class for a length-based rotational cipher. Works for any unicode string by first encoding the string to base64. Decodes back to UTF-8 (could be altered to support binary data). Methods & Parameters: --------------- LC_soupRot.enc() - encode string str - string to encode mult - rotation iteration count junk - random character count to be added (default: 0) LC_soupRot.dec() - decode string str - string to decode mult - rotation iteration count used to encode junk - random character count used to encode (default: 0) dependencies (can be found at https://github.com/Masonjar13/AHK-Library) _randStr() _rand() _ifContains() _isDigit() --------------- Example: ------------ iterationCnt:=a_tickCount junk:=0 str:="Hello° µWorld" encStr:=LC_soupRot.enc(str,iterationCnt,junk) decStr:=LC_soupRot.dec(encStr,iterationCnt,junk) msgbox,,SoupRot,% "Original String: " str "`n`nEncrypted String: " encStr "`n`nDecrypted String: " decStr ------------ */ class LC_soupRot { enc(str,mult,junk:=0){ str:=LC_Base64_EncodeText(str) rotBase:=strLen(str) * mult for i,a in strSplit(str) { rot:=mod(rotBase*i,94) nC:=asc(a)+rot while (nC > 126 || nC < 32) { if (nC > 126) { nC-=94 } else if (nC < 32) { nC+=94 } } nStr.=chr(nC) if (junk) { nStr.=soupRot.randStr(junk,junk,1234) } } return nStr } dec(str,mult,junk:=0){ i:=0 rotBase:=strLen(str) * mult // (junk+1) for _,a in strSplit(str) { if (skip) { skip-- continue } rot:=mod(rotBase*++i,94) nC:=asc(a)-rot while (nC > 126 || nC < 32) { if (nC > 126) { nC-=94 } else if (nC < 32) { nC+=94 } } nStr.=chr(nC) if (junk) { skip:=junk } } return rTrim(LC_Base64_DecodeText(nStr),chr(65533)) ;"�" } ; Dependencies _randStr(lowerBound,upperBound,mode:=1){ if (!this._isDigit(lowerBound)||!this._isDigit(upperBound)||!this._isDigit(mode)) return -1 loop % this._rand(lowerBound,upperBound) { t:="" if (strLen(mode)=1) { t:=mode } else { while (!this._ifContains(mode,t)) t:=this._rand(1,4) } if (t=1) { str.=chr(this._rand(97,122)) } else if (t=2) { str.=chr(this._rand(65,90)) } else if (t=3) { str.=this._rand(0,9) } else if (t=4) { i:=this._rand(1,4) str.=i=1?chr(this._rand(33,47)):i=2?chr(this._rand(58,64)):i=3?chr(this._rand(91,96)):chr(this._rand(123,126)) } } return str } _rand(lowerBound,upperBound){ random,rand,% lowerBound,% upperBound return rand } _ifContains(haystack,needle){ if haystack contains %needle% return 1 } _isDigit(in){ if in is digit return 1 } } ; analogous to encodeURIComponent() / decodeURIComponent() in javascript ; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent ; Modified by GeekDude from http://goo.gl/0a0iJq LC_UriEncode(Uri, RE="[0-9A-Za-z]") { VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0), StrPut(Uri, &Var, "UTF-8") While Code := NumGet(Var, A_Index - 1, "UChar") Res .= (Chr:=Chr(Code)) ~= RE ? Chr : Format("%{:02X}", Code) Return, Res } LC_UriDecode(Uri, Encoding:="UTF-8") { Pos := 1 While Pos := RegExMatch(Uri, "i)(%[\da-f]{2})+", Code, Pos) { VarSetCapacity(Var, StrLen(Code) // 3, 0), Code := SubStr(Code,2) Loop, Parse, Code, `% NumPut("0x" A_LoopField, Var, A_Index-1, "UChar") Decoded := StrGet(&Var, Encoding) Uri := SubStr(Uri, 1, Pos-1) . Decoded . SubStr(Uri, Pos+StrLen(Code)+1) Pos += StrLen(Decoded)+1 } Return, Uri } ;---------------------------------- ; analogous to encodeURI() / decodeURI() in javascript ; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI LC_UrlEncode(Url) { ; keep certain symbols like ":/;?@,&=+$#.", as per the standard js implementation ; see https://github.com/ahkscript/libcrypt.ahk/issues/30 return LC_UriEncode(Url, "[!#$&-;=?-Z_a-z~]") } LC_UrlDecode(url) { return LC_UriDecode(url) } ; ; Version: 2014.03.06-1518, jNizM ; see https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher ; =================================================================================== LC_VigenereCipher(string, key, enc := 1) { enc := "", DllCall("user32.dll\CharUpper", "Ptr", &string, "Ptr") , string := RegExReplace(StrGet(&string), "[^A-Z]") loop, parse, string { a := Asc(A_LoopField) - 65 , b := Asc(SubStr(key, 1 + Mod(A_Index - 1, StrLen(key)), 1)) - 65 , enc .= Chr(Mod(a + b, 26) + 65) } return enc } LC_VigenereDecipher(string, key) { dec := "" loop, parse, key dec .= Chr(26 - (Asc(A_LoopField) - 65) + 65) return LC_VigenereCipher(string, dec) } ; FUnctions and algorithm by VxE ; intergrated into libcrypt.ahk with "LC_" prefixes /* #################################################################################################### #################################################################################################### ###### ###### ###### [VxE]-251 Encryption ###### ###### & ###### ###### [VxE]-89 Encryption ###### ###### ###### #################################################################################################### #################################################################################################### [VxE] 251 encryption is a rotation-based encryption algorithm using a dynamic key and a dynamic map. The '251' indicates the size of the map, which omits the following byte-values: 0x00 ( null byte: string terminator ) 0x09 ( tab character: common text formatting character ) 0x0A ( newline character: common text formatting character ) 0x0D ( carriage return character: common text formatting character ) 0x7F ( wierd character: ascii 'del' ) This encryption function also supports an 89-character map, which incorporates the byte values between 0x20 and 0x7e, omitting 0x22, 0x27, 0x2C, 0x2F, 0x5C, and 0x60. This mode allows text value input to be encrypted as text without high-ascii characters or non-printable characters. */ ; ################################################################################################## ; ## Function shortcuts LC_VxE_Encrypt89( key, byref message ) { ; ---------------------------------------------------------- Return LC_VxE_Crypt( key, message, 1, "vxe89 len" StrLen( message ) << !!A_IsUnicode ) } ; VxE_Encrypt89( key, byref message ) ---------------------------------------------------------- LC_VxE_Decrypt89( key, byref message ) { ; ---------------------------------------------------------- Return LC_VxE_Crypt( key, message, 0, "vxe89 len" StrLen( message ) << !!A_IsUnicode ) } ; VxE_Decrypt89( key, byref message ) ---------------------------------------------------------- LC_VxE_Encrypt251( key, byref message, len ) { ; ---------------------------------------------------- Return LC_VxE_Crypt( key, message, 1, "len" len ) } ; VxE_Encrypt251( key, byref message, len ) ---------------------------------------------------- LC_VxE_Decrypt251( key, byref message, len ) { ; ---------------------------------------------------- Return LC_VxE_Crypt( key, message, 0, "len" len ) } ; VxE_Decrypt251( key, byref message, len ) ---------------------------------------------------- ; ################################################################################################## ; ## The core function LC_VxE_Crypt( key, byref message, direction = 1, options="" ) { ; ----------------------------------- ; Transorms the message. 'direction' indicates whether or not to decrypt or encrypt the message. ; However, since this algorithm is symmetrical, distinguishing between 'encrypt' and 'decrypt' is ; merely for the benefit of human understanding. ; This agorithm was developed by [VxE] in July 2010. When a key/message are passed to this function, ; it generates the rotation map using the key. Then, it traverses the bytes in the message, rotating ; their values along the map according to the key. Once the character's encoded value is determined, ; the key is augmented by a value based on the byte value. If !RegexMatch( options, "i)(?:len|l)\K(?:0x[\da-fA-F]+|\d+)", length ) ; check explicit length length := StrLen( message ) << !!A_IsUnicode ; otherwise, find length. UseVxE89 := InStr( options, "vxe89" ) ; check 'options' for text-friendly mode. direction := 2 * ( direction = 1 ) - 1 ; coerce the 'direction' to either +1 or -1. w := StrLen( key ) << !!A_IsUnicode ; 'w' holds the derived key, which is a 32-bit integer based on the key. ; Although this doesn't seem very entropic, remember that the map is also derived from the key. If (UseVxE89) ; using the smaller map allows text-friendly encrypting since the small map is Loop 126 ; composed only of low-ascii printable characters If ( A_Index >= 32 && A_Index != 34 && A_Index != 39 && A_Index != 44 && A_Index != 47 && A_Index != 92 && A_Index != 96 ) map .= Chr( A_Index ) If !UseVxE89 ; the 251 map is more suitable for non-text data Loop 255 If ( A_Index != 9 && A_Index != 10 && A_Index != 13 && A_Index != 127 ) map .= Chr( A_Index ) k := StrLen( map ) ; keep the length of the map Loop 9 ; pad the key up to 509 characters, mixing in digit-characters If StrLen( key ) < 509 key := SubStr( key Chr( 48 + A_Index ) key, 1, 509 ) Loop 509 ; rearrange the map, using the padded key as the selector. { ; This is how the map becomes dynamic. 509 times, a char is selected from the map and ; is extracted from the map string, then appended to it. At the same time, the derived key is ; augmented by XORing it with a value based on each byte in the key. q := *( &key + A_Index - 1 ) pos := 1 + Mod( q * A_Index * 3, k ) StringMid, e, map, %pos%, 1 StringLeft, i, map, pos - 1 StringTrimLeft, c, map, %pos% map := i c e w ^= q * A_Index * 1657 } x := 0 Loop %length% { c := NumGet( message, A_Index - 1, "UChar" ) ; for each byte in the message If !c || !( i := InStr( map, Chr( c ), 1 ) ) Continue ; if the character isn't in the map, just skip it. i-- ; the map index should be zero based for easier use with Mod() function x++ ; this tracks the actual index, not the char position. e := Mod( 223390000 + i + w * direction, k ) ; rotate the index along the map c := Asc( SubStr( map, e + 1, 1 ) ) ; lookup the character at the rotated index NumPut( c, message, A_Index - 1, "UChar" ) ; append the newly-mapped char to the result ; Finally, depending on the direction of rotation, use either the original index or ; the rotated index to augment the derived key If ( direction = 1 ) c := Mod( e + x, 251 ) Else c := Mod( i + x, 251 ) w ^= c | c << 8 | c << 16 | c << 24 } return length } ; VxE_Crypt( key, byref message, direction = 1, options="" ) ----------------------------------- LC_XOR_Encrypt(str,key) { EncLen:=StrPut(Str,"UTF-16")*2 VarSetCapacity(EncData,EncLen) StrPut(Str,&EncData,"UTF-16") PassLen:=StrPut(key,"UTF-8") VarSetCapacity(PassData,PassLen) StrPut(key,&PassData,"UTF-8") LC_XOR(OutData,EncData,EncLen,PassData,PassLen) LC_Base64_Encode(OutBase64, OutData, EncLen) return OutBase64 } LC_XOR_Decrypt(OutBase64,key) { EncLen:=LC_Base64_Decode(OutData, OutBase64) PassLen:=StrPut(key,"UTF-8") VarSetCapacity(PassData,PassLen) StrPut(key,&PassData,"UTF-8") LC_XOR(EncData,OutData,EncLen,PassData,PassLen) return StrGet(&EncData,"UTF-16") } LC_XOR(byref OutData,byref EncData,EncLen,byref PassData,PassLen) { VarSetCapacity(OutData,EncLen) Loop % EncLen NumPut(NumGet(EncData,A_Index-1,"UChar")^NumGet(PassData,Mod(A_Index-1,PassLen),"UChar"),OutData,A_Index-1,"UChar") }