Files
ArteKaffee/libcrypt/libcrypt_v2.ahk2
T
2026-08-20 15:54:24 +02:00

1063 lines
34 KiB
Plaintext

#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
}
}