#Requires AutoHotkey v2.0 #Warn LocalSameAsGlobal, Off LC_Version := "0.0.24.04" ; ============================================================================== ; ASCII / Binary ; ============================================================================== LC_ASCII2Bin(s, pretty := false) { r := "" for i, ch in StrSplit(s) { byte := Ord(ch), bits := "" Loop 8 bits := ((byte >> (A_Index - 1)) & 1) bits r .= bits if pretty && i < StrLen(s) 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]") Out := "" Loop StrLen(Bin) // 8 { val := 0 for Bit in StrSplit(SubStr(Bin, (A_Index - 1) * 8 + 1, 8)) val += val + Bit Out .= Chr(val) } return Out } ; ============================================================================== ; Binary String Encode/Decode (text <-> binary string) ; ============================================================================== LC_BinStr_EncodeText(Text, Pretty := false, Encoding := "UTF-8") { Len := StrPut(Text, Encoding) - 1 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) 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) { InTxt := RegExReplace(InTxt, "[^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 } ; ============================================================================== ; ASCII85 (Original + Z85) ; ============================================================================== LC_ASCII85_Encode(content, variant := "") { content := StrReplace(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 } ; ============================================================================== ; Base64 / Hex via Windows CryptoAPI ; ============================================================================== LC_Base64_EncodeText(Text, Encoding := "UTF-8") { Len := StrPut(Text, Encoding) - 1 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(&OutVar, &InVar, InLen) { return LC_Bin2Str(&OutVar, &InVar, InLen, 0x40000001) } LC_Base64_Decode(&OutVar, InVar) { return LC_Str2Bin(&OutVar, InVar, 0x1) } LC_Bin2Hex(&OutVar, &InVar, InLen, Pretty := false) { return LC_Bin2Str(&OutVar, &InVar, InLen, Pretty ? 0xb : 0x4000000c) } LC_Hex2Bin(&OutVar, &InVar) { return LC_Str2Bin(&OutVar, &InVar, 0x8) } LC_Bin2Str(&OutVar, &InVar, InLen, Flags) { OutLen := 0 DllCall("Crypt32\CryptBinaryToString", "ptr", InVar, "uint", InLen, "uint", Flags, "ptr", 0, "uint*", &OutLen) OutVar := Buffer(OutLen * 2) DllCall("Crypt32\CryptBinaryToString", "ptr", InVar, "uint", InLen, "uint", Flags, "ptr", OutVar, "uint*", &OutLen) return OutLen } LC_Str2Bin(&OutVar, InVar, Flags) { OutLen := 0 DllCall("Crypt32\CryptStringToBinary", "ptr", InVar, "uint", StrLen(InVar), "uint", Flags, "ptr", 0, "uint*", &OutLen, "ptr", 0, "ptr", 0) OutVar := Buffer(OutLen) DllCall("Crypt32\CryptStringToBinary", "ptr", InVar, "uint", StrLen(InVar), "uint", Flags, "ptr", OutVar, "uint*", &OutLen, "ptr", 0, "ptr", 0) return OutLen } ; ============================================================================== ; Caesar / ROT ; ============================================================================== LC_Caesar(string, num := 2) { ret := "" for ch in StrSplit(string) { c := Ord(ch) 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 .= ch } return ret } LC_Rot5(string) { s := "" for ch in StrSplit(string) { c := Ord(ch) s .= (c >= 48 && c <= 57) ? ((c < 53) ? c + 5 : c - 5) : c } return s } LC_Rot13(string) { s := "" for ch in StrSplit(string) { c := Ord(ch) 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)) } LC_Rot47(string) { s := "" for ch in StrSplit(string) { c := Ord(ch) c += (c >= 33 && c <= 79 ? 47 : (c >= 80 && c <= 126 ? -47 : 0)) s .= Chr(c) } return s } ; ============================================================================== ; Base conversion ; ============================================================================== LC_To_Dec(b, n) { d := 0, n := StrUpper(n) for i, ch in StrSplit(n) { d *= b, k := ch if (k < "0" || k > "9") k := Ord(k) - 55 else k := Integer(k) d += k } return d } LC_From_Dec(b, n) { m := "" Loop { d := Mod(n, b), n //= b m := (d < 10 ? d : Chr(d + 55)) m if 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) { return LC_From_Dec(to, LC_To_Dec(from, num)) } ; ============================================================================== ; Div2 ; ============================================================================== LC_Div2_encode(input, WithAutoTrim := true, numproc := 1) { if WithAutoTrim input := StrReplace(input, A_Space, "_") 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 } else Break } input := final } return final } LC_Div2_decode(input, WithAutoTrim := true, numproc := 1) { if WithAutoTrim input := StrReplace(input, A_Space, "_") Loop numproc { i := 1, final := "", inputlen := StrLen(input) loopc := Ceil(inputlen * (1/2)) Loop loopc { 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 } ; ============================================================================== ; URI / URL ; ============================================================================== LC_UriEncode(Uri, RE := "[0-9A-Za-z]") { Var := Buffer(StrPut(Uri, "UTF-8") - 1), StrPut(Uri, Var, "UTF-8"), Res := "" Loop Var.Size { Code := NumGet(Var, A_Index - 1, "UChar") Res .= (Chr(Code) ~= RE) ? Chr(Code) : Format("%{:02X}", Code) } return Res } LC_UriDecode(Uri, Encoding := "UTF-8") { Pos := 1 while Pos := RegExMatch(Uri, "i)(%[\da-f]{2})+", &Code, Pos) { Var := Buffer(StrLen(Code[0]) // 3, 0), CodeTxt := SubStr(Code[0], 2) Loop Var.Size NumPut("UChar", Integer("0x" SubStr(CodeTxt, (A_Index - 1) * 2 + 1, 2)), Var, A_Index - 1) Decoded := StrGet(Var, Var.Size, Encoding) Uri := SubStr(Uri, 1, Pos - 1) Decoded SubStr(Uri, Pos + StrLen(Code[0])) Pos += StrLen(Decoded) + 1 } return Uri } LC_UrlEncode(Url) { return LC_UriEncode(Url, "[!#$&-;=?-Z_a-z~]") } LC_UrlDecode(url) { return LC_UriDecode(url) } ; ============================================================================== ; Vigenere ; ============================================================================== LC_VigenereCipher(string, key, enc := 1) { enc := "" DllCall("user32\CharUpperW", "ptr", StrPtr(string)) string := RegExReplace(string, "[^A-Z]") for ch in StrSplit(string) { a := Ord(ch) - 65 b := Ord(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 := "" for ch in StrSplit(key) dec .= Chr(26 - (Ord(ch) - 65) + 65) return LC_VigenereCipher(string, dec) } ; ============================================================================== ; CryptoAPI Hash Core (CalcAddrHash etc.) ; ============================================================================== LC_CalcAddrHash(addr, length, algid, &hash := 0, &hashlength := 0) { static h := [0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f"] hProv := hHash := o := "" if DllCall("advapi32\CryptAcquireContext", "ptr*", &hProv, "ptr", 0, "ptr", 0, "uint", 24, "uint", 0xF0000000) = 0 { if DllCall("advapi32\CryptCreateHash", "ptr", hProv, "uint", algid, "uint", 0, "uint", 0, "ptr*", &hHash) = 0 { if DllCall("advapi32\CryptHashData", "ptr", hHash, "ptr", addr, "uint", length, "uint", 0) = 0 { if DllCall("advapi32\CryptGetHashParam", "ptr", hHash, "uint", 2, "ptr", 0, "uint*", &hashlength, "uint", 0) = 0 { hash := Buffer(hashlength, 0) if DllCall("advapi32\CryptGetHashParam", "ptr", hHash, "uint", 2, "ptr", hash, "uint*", &hashlength, "uint", 0) = 0 { Loop hashlength { v := NumGet(hash, A_Index - 1, "UChar") o .= h[(v >> 4) + 1] h[(v & 0xF) + 1] } } } } DllCall("advapi32\CryptDestroyHash", "ptr", hHash) } DllCall("advapi32\CryptReleaseContext", "ptr", hProv, "uint", 0) } return o } LC_CalcStringHash(string, algid, encoding := "UTF-8", &hash := 0, &hashlength := 0) { chrlength := (encoding = "CP1200" || encoding = "UTF-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength data := Buffer(length, 0) StrPut(string, data, length // chrlength, encoding) return LC_CalcAddrHash(data, length, algid, &hash, &hashlength) } LC_CalcHexHash(hexstring, algid) { length := StrLen(hexstring) // 2 data := Buffer(length, 0) Loop length NumPut("UChar", Integer("0x" SubStr(hexstring, 2 * A_Index - 1, 2)), data, A_Index - 1) return LC_CalcAddrHash(data, length, algid) } LC_CalcFileHash(filename, algid, chunkSize := 0, &hash := 0, &hashlength := 0) { fpos := "" f := FileOpen(filename, "r") if !f return "" f.Pos := 0 if (!chunkSize && f.Length > 0x7FFFFFFF) return "" if (!chunkSize) { data := Buffer(f.Length, 0) f.RawRead(data, f.Length) return LC_CalcAddrHash(data, f.Length, algid, &hash, &hashlength) } hashlength := 0 while (f.Pos < f.Length) { readlength := (f.Length - fpos > chunkSize) ? chunkSize : f.Length - f.Pos data := Buffer(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 } ; ============================================================================== ; MD2 / MD4 / MD5 / SHA / SHA256 / SHA384 / SHA512 wrappers ; ============================================================================== LC_MD2(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x8001, encoding) LC_HexMD2(hexstring) => LC_CalcHexHash(hexstring, 0x8001) LC_FileMD2(filename) => LC_CalcFileHash(filename, 0x8001, 64*1024) LC_AddrMD2(addr, length) => LC_CalcAddrHash(addr, length, 0x8001) LC_MD4(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x8002, encoding) LC_HexMD4(hexstring) => LC_CalcHexHash(hexstring, 0x8002) LC_FileMD4(filename) => LC_CalcFileHash(filename, 0x8002, 64*1024) LC_AddrMD4(addr, length) => LC_CalcAddrHash(addr, length, 0x8002) LC_MD5(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x8003, encoding) LC_HexMD5(hexstring) => LC_CalcHexHash(hexstring, 0x8003) LC_FileMD5(filename) => LC_CalcFileHash(filename, 0x8003, 64*1024) LC_AddrMD5(addr, length) => LC_CalcAddrHash(addr, length, 0x8003) LC_SHA(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x8004, encoding) LC_HexSHA(hexstring) => LC_CalcHexHash(hexstring, 0x8004) LC_FileSHA(filename) => LC_CalcFileHash(filename, 0x8004, 64*1024) LC_AddrSHA(addr, length) => LC_CalcAddrHash(addr, length, 0x8004) LC_SHA256(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x800C, encoding) LC_HexSHA256(hexstring) => LC_CalcHexHash(hexstring, 0x800C) LC_FileSHA256(filename) => LC_CalcFileHash(filename, 0x800C, 64*1024) LC_AddrSHA256(addr, length) => LC_CalcAddrHash(addr, length, 0x800C) LC_SHA384(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x800D, encoding) LC_HexSHA384(hexstring) => LC_CalcHexHash(hexstring, 0x800D) LC_FileSHA384(filename) => LC_CalcFileHash(filename, 0x800D, 64*1024) LC_AddrSHA384(addr, length) => LC_CalcAddrHash(addr, length, 0x800D) LC_SHA512(string, encoding := "UTF-8") => LC_CalcStringHash(string, 0x800E, encoding) LC_HexSHA512(hexstring) => LC_CalcHexHash(hexstring, 0x800E) LC_FileSHA512(filename) => LC_CalcFileHash(filename, 0x800E, 64*1024) LC_AddrSHA512(addr, length) => LC_CalcAddrHash(addr, length, 0x800E) ; ============================================================================== ; CRC32 ; ============================================================================== LC_CRC32(string, encoding := "UTF-8") { chrlength := (encoding = "CP1200" || encoding = "UTF-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength data := Buffer(length, 0) StrPut(string, data, length // chrlength, encoding) hMod := DllCall("Kernel32\LoadLibraryW", "str", "Ntdll.dll") CRC32 := DllCall("Ntdll\RtlComputeCrc32", "uint", 0, "ptr", data, "uint", length, "uint") CRC := Format("{:08X}", CRC32) DllCall("User32\CharLowerW", "str", CRC) DllCall("Kernel32\FreeLibrary", "ptr", hMod) return CRC } LC_HexCRC32(hexstring) { length := StrLen(hexstring) // 2 data := Buffer(length, 0) Loop length NumPut("UChar", Integer("0x" SubStr(hexstring, 2 * A_Index - 1, 2)), data, A_Index - 1) hMod := DllCall("Kernel32\LoadLibraryW", "str", "Ntdll.dll") CRC32 := DllCall("Ntdll\RtlComputeCrc32", "uint", 0, "ptr", data, "uint", length, "uint") CRC := Format("{:08X}", CRC32) DllCall("User32\CharLowerW", "str", CRC) DllCall("Kernel32\FreeLibrary", "ptr", hMod) return CRC } LC_FileCRC32(sFile := "", cSz := 4) { Bytes := "" cSz := (cSz < 0 || cSz > 8) ? 2**22 : 2**(18 + cSz) BufferObj := Buffer(cSz, 0) hFil := DllCall("Kernel32\CreateFileW", "str", sFile, "uint", 0x80000000, "uint", 3, "int", 0, "uint", 3, "uint", 0, "int", 0, "ptr") if (hFil < 1) return hFil hMod := DllCall("Kernel32\LoadLibraryW", "str", "Ntdll.dll") CRC32 := 0 fSz := NumGet(BufferObj, 0, "int64") Loop (fSz // cSz + !!Mod(fSz, cSz)) { DllCall("Kernel32\ReadFile", "ptr", hFil, "ptr", BufferObj, "uint", cSz, "uint*", &Bytes, "uint", 0) CRC32 := DllCall("Ntdll\RtlComputeCrc32", "uint", CRC32, "ptr", BufferObj, "uint", Bytes, "uint") } DllCall("Kernel32\CloseHandle", "ptr", hFil) CRC32 := Format("{:08X}", CRC32) DllCall("User32\CharLowerW", "str", CRC32) DllCall("Kernel32\FreeLibrary", "ptr", hMod) return CRC32 } ; ============================================================================== ; HMAC ; ============================================================================== 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, oconst := 0x5C if !Algorithms.Has(Algo) return "" AlgID := Algorithms[Algo].ID, BlockSize := Algorithms[Algo].Size MsgLen := StrPut(Message, "UTF-8") - 1 KeyLen := StrPut(Key, "UTF-8") - 1 K := Buffer(KeyLen + 1, 0) StrPut(Key, K, KeyLen, "UTF-8") KeyHash := KeyHashLen := "" if (KeyLen > BlockSize) LC_CalcAddrHash(K, KeyLen, AlgID, &KeyHash, &KeyHashLen) ipad := Buffer(BlockSize + MsgLen, iconst) Addr := KeyLen > BlockSize ? KeyHash : K Length := KeyLen > BlockSize ? KeyHashLen : KeyLen i := 0 while (i < Length) { NumPut(NumGet(Addr, i, "UChar") ^ iconst, ipad, i, "UChar") i++ } if (MsgLen) StrPut(Message, Buffer(ipad.Ptr + BlockSize, MsgLen), MsgLen, "UTF-8") InnerHash := InnerHashLen := "" LC_CalcAddrHash(ipad, BlockSize + MsgLen, AlgID, &InnerHash, &InnerHashLen) opad := Buffer(BlockSize + InnerHashLen, oconst) Addr := KeyLen > BlockSize ? KeyHash : K Length := KeyLen > BlockSize ? KeyHashLen : KeyLen i := 0 while (i < Length) { NumPut(NumGet(Addr, i, "UChar") ^ oconst, opad, i, "UChar") i++ } i := 0 while (i < InnerHashLen) { NumPut(NumGet(InnerHash, i, "UChar"), Buffer(opad.Ptr + BlockSize + i, 1), 0, "UChar") i++ } return LC_CalcAddrHash(opad, BlockSize + InnerHashLen, AlgID) } ; ============================================================================== ; L64 / L128 Hash (Laszlo) ; ============================================================================== __LC_LHashTable := [] LC_L64Hash(x) { global __LC_LHashTable if __LC_LHashTable.Length = 0 __LC_LHash_LHashInit() R := 0 for ch in StrSplit(x) { i := (R >> 56) & 255 R := ((R << 8) + Ord(ch)) ^ __LC_LHashTable[i + 1] } return __LC_LHash_Hex8(R >> 32) . __LC_LHash_Hex8(R) } LC_L128Hash(x) { global __LC_LHashTable if __LC_LHashTable.Length = 0 __LC_LHash_LHashInit() S := 0, R := -1 for ch in StrSplit(x) { i := (R >> 56) & 255 R := ((R << 8) + Ord(ch)) ^ __LC_LHashTable[i + 1] i := (S >> 56) & 255 S := ((S << 8) + Ord(ch)) - __LC_LHashTable[i + 1] } return __LC_LHash_Hex8(R >> 32) . __LC_LHash_Hex8(R) . __LC_LHash_Hex8(S >> 32) . __LC_LHash_Hex8(S) } __LC_LHash_Hex8(i) { i := 0x100000000 | (i & 0xFFFFFFFF) return SubStr(i, -7) } __LC_LHash_LHashInit() { global __LC_LHashTable u := 0, v := 0 Loop 256 { i := A_Index - 1 __LC_LHASH_TEA(&u, &v, 1, 22, 333, 4444, 8) __LC_LHashTable.Push((u << 32) | v) } } __LC_LHASH_TEA(&y, &z, k0, k1, k2, k3, n := 32) { s := 0, d := 0x9E3779B9 Loop n { k := [k0,k1,k2,k3][Mod(s, 4) + 1] y := 0xFFFFFFFF & (y + (((z << 4) ^ (z >> 5)) + z ^ s + k)) s := 0xFFFFFFFF & (s + d) k := [k0,k1,k2,k3][Mod(s >> 11, 4) + 1] z := 0xFFFFFFFF & (z + (((y << 4) ^ (y >> 5)) + y ^ s + k)) } } ; ============================================================================== ; nnnik21 encryption ; ============================================================================== 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 encbin := Buffer(enclen, 0) StrPut(str, encbin, enclen // 2, "UTF-16") passlen += Mod((4 - Mod(passlen, 4)), 4) passbin := Buffer(passlen, 0) StrPut(pass, passbin, StrLen(pass), "UTF-8") LC_nnnik21_encryptbin(&encbin, encbin.Size, &passbin, passbin.Size) Text := "" LC_Base64_Encode(&Text, &encbin, encbin.Size) 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" passlen += Mod((4 - Mod(passlen, 4)), 4) passbin := Buffer(passlen, 0) StrPut(pass, passbin, StrLen(pass), "UTF-8") encbin := Buffer(0) enclen := LC_Base64_Decode(&encbin, str) LC_nnnik21__decryptbin(&encbin, encbin.Size, &passbin, passbin.Size) return StrGet(encbin, encbin.Size, "UTF-16") } LC_nnnik21_encryptbin(&pBin1, sBin1, &pBin2, sBin2) { b := 0 Loop sBin1 // 4 { a := NumGet(pBin1, sBin1 - A_Index * 4, "UInt") NumPut(a + b, pBin1, sBin1 - A_Index * 4, "UInt") b := (a + b) * a } Loop sBin2 // 4 { c := NumGet(pBin2, (A_Index - 1) * 4, "UInt") b := 0 Loop sBin1 // 4 { a := NumGet(pBin1, (A_Index - 1) * 4, "UInt") NumPut((a + b) ^ c, pBin1, (A_Index - 1) * 4, "UInt") b := (a + b) * a } } } LC_nnnik21__decryptbin(&pBin1, sBin1, &pBin2, sBin2) { Loop sBin2 // 4 { c := NumGet(pBin2, sBin2 - A_Index * 4, "UInt") b := 0 Loop sBin1 // 4 { a := NumGet(pBin1, (A_Index - 1) * 4, "UInt") a := (a ^ c) - b NumPut(a, pBin1, (A_Index - 1) * 4, "UInt") b := (a + b) * a } } b := 0 Loop sBin1 // 4 { a := NumGet(pBin1, sBin1 - A_Index * 4, "UInt") a := a - b NumPut(a, pBin1, sBin1 - A_Index * 4, "UInt") b := (a + b) * a } } ; ============================================================================== ; RC4 ; ============================================================================== LC_RC4_Encrypt(Data, Pass) { b := 0, j := 0, Key := [], sBox := [], Result := "" Loop 256 { a := A_Index - 1 Key[a] := Ord(SubStr(Pass, Mod(a, StrLen(Pass)) + 1, 1)) sBox[a] := a } Loop 256 { a := A_Index - 1 b := (b + sBox[a] + Key[a]) & 255 t := sBox[a], sBox[a] := sBox[b], sBox[b] := t } for ch in StrSplit(Data) { i := A_Index & 255 j := (sBox[i] + j) & 255 k := sBox[(sBox[i] + sBox[j]) & 255] t := sBox[i], sBox[i] := sBox[j], sBox[j] := t Result .= Format("{:02x}", Ord(ch) ^ sBox[k]) } return Result } LC_RC4_Decrypt(Data, Pass) { b := 0, j := 0, Key := [], sBox := [], Result := "" Loop 256 { a := A_Index - 1 Key[a] := Ord(SubStr(Pass, Mod(a, StrLen(Pass)) + 1, 1)) sBox[a] := a } Loop 256 { a := A_Index - 1 b := (b + sBox[a] + Key[a]) & 255 t := sBox[a], sBox[a] := sBox[b], sBox[b] := t } Loop StrLen(Data) // 2 { i := A_Index & 255 j := (sBox[i] + j) & 255 k := sBox[(sBox[i] + sBox[j]) & 255] t := sBox[i], sBox[i] := sBox[j], sBox[j] := t Result .= Chr((Integer("0x" SubStr(Data, (2 * A_Index) - 1, 2))) ^ sBox[k]) } return Result } LC_RC4(RC4Data, RC4Pass) { RC4PassLen := StrLen(RC4Pass), Key := [], sBox := [], b := 0, RC4Result := "", i := 0, j := 0 Loop 256 { a := A_Index - 1 ModVal := Mod(a, RC4PassLen) + 1 c := SubStr(RC4Pass, ModVal, 1) Key[a] := Ord(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 } for ch in StrSplit(RC4Data) { i := Mod(i + 1, 256) j := Mod(sBox[i] + j, 256) k := sBox[Mod(sBox[i] + sBox[j], 256)] c := Ord(ch) ^ k c := (c = 0) ? k : c RC4Result .= Chr(c) } return RC4Result } ; ============================================================================== ; RSHash / SecureSalted ; ============================================================================== LC_RSHash(str) { a := 0xF8C9, b := 0x5C6B7, h := 0 for ch in StrSplit(str) { h := h * a + Ord(ch) a *= b } return h & 0x7FFFFFFF } LC_SecureSalted(salt, message, algo := "md5") { hash := "" funcName := "LC_" algo saltedHash := %funcName%(message . salt) saltedHashR := %funcName%(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) ns := SubStr(byte1 ^ byte2, 3) hash .= (StrLen(ns) < 2 ? "0" ns : ns) } return hash } ; ============================================================================== ; VxE 89 / 251 ; ============================================================================== LC_VxE_Encrypt89(key, &message) { return LC_VxE_Crypt(key, &message, 1, "vxe89 len " StrLen(message)) } LC_VxE_Decrypt89(key, &message) { return LC_VxE_Crypt(key, &message, 0, "vxe89 len " StrLen(message)) } LC_VxE_Encrypt251(key, &message, len) { return LC_VxE_Crypt(key, &message, 1, "len " len) } LC_VxE_Decrypt251(key, &message, len) { return LC_VxE_Crypt(key, &message, 0, "len " len) } LC_VxE_Crypt(key, &message, direction := 1, options := "") { length := "" if RegExMatch(options, "i)(?:len|l)\K(?:0x[\da-fA-F]+|\d+)", &m) length := Integer(m[0]) if length = "" length := StrLen(message) UseVxE89 := InStr(options, "vxe89") direction := 2 * (direction = 1) - 1 w := StrLen(key) map := "" if UseVxE89 { Loop 126 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) } else { Loop 255 if (A_Index != 9 && A_Index != 10 && A_Index != 13 && A_Index != 127) map .= Chr(A_Index) } k := StrLen(map) Loop 9 if StrLen(key) < 509 key := SubStr(key Chr(48 + A_Index) key, 1, 509) Loop 509 { q := NumGet(StrPtr(key) + A_Index - 1, "UChar") pos := 1 + Mod(q * A_Index * 3, k) e := SubStr(map, pos, 1) i := SubStr(map, 1, pos - 1) c := SubStr(map, pos + 1) map := i c e w ^= q * A_Index * 1657 } x := 0 Loop length { c := NumGet(message, A_Index - 1, "UChar") if !c || !(i := InStr(map, Chr(c), 1)) Continue i-- x++ e := Mod(223390000 + i + w * direction, k) c := Ord(SubStr(map, e + 1, 1)) NumPut(c, message, A_Index - 1, "UChar") if (direction = 1) c := Mod(e + x, 251) else c := Mod(i + x, 251) w ^= c | c << 8 | c << 16 | c << 24 } return length } ; ============================================================================== ; XOR ; ============================================================================== LC_XOR_Encrypt(str, key) { EncLen := StrPut(str, "UTF-16") * 2 EncData := Buffer(EncLen, 0) StrPut(str, EncData, EncLen // 2, "UTF-16") PassLen := StrPut(key, "UTF-8") - 1 PassData := Buffer(PassLen, 0) StrPut(key, PassData, StrLen(key), "UTF-8") OutData := Buffer(0) LC_XOR(&OutData, &EncData, EncLen, &PassData, PassLen) OutBase64 := "" LC_Base64_Encode(&OutBase64, &OutData, OutData.Size) return OutBase64 } LC_XOR_Decrypt(OutBase64, key) { OutData := Buffer(0) EncLen := LC_Base64_Decode(&OutData, OutBase64) PassLen := StrPut(key, "UTF-8") - 1 PassData := Buffer(PassLen, 0) StrPut(key, PassData, StrLen(key), "UTF-8") EncData := Buffer(0) LC_XOR(&EncData, &OutData, EncLen, &PassData, PassLen) return StrGet(EncData, EncData.Size, "UTF-16") } LC_XOR(&OutData, &EncData, EncLen, &PassData, PassLen) { OutData := Buffer(EncLen, 0) Loop EncLen NumPut(NumGet(EncData, A_Index - 1, "UChar") ^ NumGet(PassData, Mod(A_Index - 1, PassLen), "UChar"), OutData, A_Index - 1, "UChar") } ; ============================================================================== ; soupRot class ; ============================================================================== class LC_soupRot { enc(str, mult, junk := 0) { str := LC_Base64_EncodeText(str) rotBase := StrLen(str) * mult nStr := "" i := 0 for a in StrSplit(str) { i++ rot := Mod(rotBase * i, 94) nC := Ord(a) + rot while (nC > 126 || nC < 32) { if (nC > 126) nC -= 94 else if (nC < 32) nC += 94 } nStr .= Chr(nC) if (junk) nStr .= this._randStr(junk, junk, 1234) } return nStr } dec(str, mult, junk := 0) { i := 0, rotBase := StrLen(str) * mult // (junk + 1), nStr := "", skip := 0 for a in StrSplit(str) { if (skip) { skip-- continue } i++ rot := Mod(rotBase * i, 94) nC := Ord(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)) } _randStr(lowerBound, upperBound, mode := 1) { if (!this._isDigit(lowerBound) || !this._isDigit(upperBound) || !this._isDigit(mode)) return -1 str := "" 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) { return Random(lowerBound, upperBound) } _ifContains(haystack, needle) { return InStr(haystack, needle) != 0 } _isDigit(innum) { return InStr("0123456789", innum) != 0 } }