1 (изменено: Clannad5, 2022-08-21 23:18:59)

Тема: AHK: AHK_H V2 вызов класса из Base64.ahk

Здравствуйте!
Понимаю что возможно не каждый изучает AHK_H v2, но возможно кто-то сможет помочь с проблемой.

Нашел данный код для AHK_H v2: Base64.ahk.
Однако там не приведён пример того, как использовать это.

Пытался везде гуглить, но без результатно, а предоставленный chm(документация) файл я не понимаю.
Может ли кто помочь с этим?

Хотелось бы для примера закодировать строчку "Hello World".

UPD: Проблема решена примером ниже.

base64 and RC4 encode/decode.


; ====================
; https://autohotkey.com/boards/viewtopic.php?f=6&t=47895
; Base64 by user AlleyArtwork
;
; https://autohotkey.com/board/topic/6316-rc4-encryption-to-hex-stream/
; RC4 by user Laszlo
; =========================

; ========================================
; Usage:  b64Encode(InString,Encoding := "")
;         b64Decode(InString,Encoding := "")
;
;    Encoding is an optional parameter.  Use it to force "UTF-8", "UTF-16" or other encoding.
;    Otherwise encoding is automatically selected based on the current system.
; ========================================
; Examples
; ========================================
; myVar := b64Encode("a b c d", "UTF-16") ; 
; msgbox "output 1: " myVar
; myVar2 := b64Decode(myVar, "UTF-16") ; 
; msgbox "output 2: " myVar2
; ========================================

b64Encode(sInput,encoding:="UTF-8") {
    If (sInput != "") {
        funcName := (encoding = "UTF-8") ? "CryptBinaryToStringA" : "CryptBinaryToStringW"
        
        bin := Buffer(StrPut(sInput, encoding),0)
        StrPut(sInput, bin, encoding)
        
        if !(DllCall("crypt32\" funcName, "Ptr", bin.ptr, "UInt", bin.size, "uint", 0x1, "ptr", 0, "uint*", &chars:=0)) ; param 2 was len
            throw Error(funcName " failed to determine size.", -1)
        
        buf := Buffer(chars * ((encoding="UTF-16") ? 2 : 1), 0)
        
        if !(DllCall("crypt32\" funcName, "ptr", bin.ptr, "uint", bin.size, "uint", 0x1, "ptr", buf.ptr, "uint*", &chars))
            throw Error(funcName " failed to execute", -1)
		
        return StrGet(buf,encoding)
    } Else
        return ""
}

b64Decode(sInput,encoding:="UTF-8") {
    InvalidChars := RegexMatch(sInput,"[\#\(\)\$\^\{\}\[\]\.\*\?\+\|]+")
    If (InvalidChars > 0) {
        MsgBox "Invalid characters detected.  Halting.  (Char position: " InvalidChars ")"
        return ""
    }
    
    size := 0
    If (sInput != "") {
        funcName := (encoding = "UTF-8") ? "CryptStringToBinaryA" : "CryptStringToBinaryW"
        
        buf := Buffer(StrPut(sInput,encoding),0)
        StrPut(sInput,buf,encoding)
        
        if !(DllCall("crypt32\" funcName, "ptr", buf.ptr, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", &size:=0, "ptr", 0, "ptr", 0))
            throw Error(funcName " failed to determine size.", -1)
        
        buf2 := Buffer(size, 0)
        if !(DllCall("crypt32\" funcName, "ptr", buf.ptr, "uint", 0, "uint", 0x1, "ptr", buf2.ptr, "uint*", &size, "ptr", 0, "ptr", 0))
            throw Error(funcName " failed to execute.", -1)
        
        return StrGet(buf2, encoding)
    } Else
        return ""
}

; ========================================
; Usage:   RC4txt2hex(InString, password := "")  ; password optional
;          RC4hex2txt(InString, password := "")
; ========================================
; Examples
; ========================================
; myVar := RC4txt2hex("a b c d","poof")
; MsgBox myVar
; myVar2 := RC4hex2txt(myVar,"poof")
; msgbox myVar2
; ========================================

RC4txt2hex(Data,Pass:="") {
    If (Data != "") {
       Key := Map(), sBox := Map()
	   passLen := StrLen(Pass)
       b := Format("0x{:X}",0), j := Format("0x{:X}",0)
       Result := ""
       Loop 256 {
          a := Format("0x{:X}",A_Index - 1)
          ,Key[a] := Format("0x{:X}",passLen?Ord(SubStr(Pass, Mod(a,passLen)+1, 1)):0)
          ,sBox[a] := Format("0x{:X}",a)
	   }
       Loop 256 {
          a := Format("0x{:X}",A_Index - 1)
          b := b + sBox[a] + Key[a]  & 255, b := Format("0x{:X}",b)
		  temp := sBox[a], sBox[a] := sBox[b], sBox[b] := temp, temp := "" ; swap
	   }
	   Loop Parse, Data
	   {
          i := Format("0x{:X}",A_Index & 255)
          j := Format("0x{:X}",sBox[i] + j & 255)
          k := Format("0x{:X}",sBox[i] + sBox[j] & 255)
		  temp := sBox[i], sBox[i] := sBox[j], sBox[j] := temp, temp := "" ; swap
		  numConv := String(Format("0x{:02X}",Ord(A_LoopField)^sBox[k]))
          Result .= SubStr(numConv, -2, 2)
	   }
       Return Result
   }
}

RC4hex2txt(Data,Pass:="") {
    If (Data != "") {
       Key := Map(), sBox := Map()
	   passLen := StrLen(Pass)
       b := 0, j := 0, x := "0x"
       Result := ""
       Loop 256
          a := A_Index - 1
         ,Key[a] := passLen?Ord(SubStr(Pass, Mod(a,passLen)+1, 1)):0
         ,sBox[a] := a
       Loop 256 {
          a := A_Index - 1
          b := b + sBox[a] + Key[a]  & 255
		  temp := sBox[a], sBox[a] := sBox[b], sBox[b] := temp, temp := "" ; swap
	   }
       Loop StrLen(Data)//2 {
          i := A_Index  & 255
          j := sBox[i] + j  & 255
          k := sBox[i] + sBox[j]  & 255
		  temp := sBox[i], sBox[i] := sBox[j], sBox[j] := temp, temp := "" ; swap
          Result .= Chr((x SubStr(Data,2*A_Index-1,2)) ^ sBox[k])
	   }
       Return Result
   }
}

2

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Берете код на ahk_l, который переводит в base64.
Пытаетесь его понять.
Читаете справку об отличиях ahk_l первой и второй версии.
Переводите код.

3

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Malcev


Text := "Text"
Bytes := StrLen(Text)
Encoded := ""
Decoded := ""
	Msgbox Encoded := Base64.Encode(Text, Bytes)
	Msgbox Decoded := Base64.Decode(Encoded, Bytes)
ExitApp


Class Base64 {
	Static Encode(Buf, Codec := 0x40000001) {
		if Buf is String
			p := StrPtr(Buf), s := StrLen(Buf) * 2
		else p := Buf, s := Buf.Size
		if (DllCall("crypt32\CryptBinaryToString", "Ptr", p, "UInt", s, "UInt", Codec, "Ptr", 0, "Uint*", &nSize := 0) &&
			(VarSetStrCapacity(&VarOut, nSize << 1), DllCall("crypt32\CryptBinaryToString", "Ptr", p, "UInt", s, "UInt", Codec, "Str", VarOut, "Uint*", &nSize)))
			return (VarSetStrCapacity(&VarOut, -1), VarOut)
	}

	Static Decode(VarIn, Codec := 0x00000001) {
		if (DllCall("crypt32\CryptStringToBinary", "Str", VarIn, "UInt", 0, "UInt", Codec, "Ptr", 0, "Uint*", &SizeOut := 0, "Ptr", 0, "Ptr", 0) &&
			DllCall("Crypt32.dll\CryptStringToBinary", "Str", VarIn, "UInt", 0, "UInt", Codec, "Ptr", VarOut := Buffer(SizeOut), "Uint*", &SizeOut, "Ptr", 0, "Ptr", 0))
			return VarOut
	}
}

В Encoded я получаю это: 54 00 65 00 78 00 74 00.
В Decoded я получаю пустое значение.

При написание длинной строки в переменную "Text" я получаю пустое значение.
Я, видимо, делаю что-то не так.

4

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Ваш вопрос ahk_h не касается.
Лично я вторую версию автохотки не знаю.
Вам надо задать этот вопрос на оф.форуме в топике по ahk_l 2.

5 (изменено: Clannad5, 2022-08-21 17:44:17)

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Malcev

Я попробовал поиграться с функцией и понял, что ошибся.
Поправил и сделал так:


Text := "HelloWorld"
Bytes := StrLen(Text)
Encoded := ""
Decoded := ""

Msgbox Encoded := Base64.Encode(Text, Bytes)
Msgbox Base64.Decode(Encoded)
ExitApp


Class Base64 {
	Static Encode(Buf, Bytes, Codec := 0x00000001) {
		if Buf is String
			p := StrPtr(Buf), s := StrLen(Buf) * 2
		else p := Buf, s := Buf.Size
		if (DllCall("crypt32\CryptBinaryToString", "Ptr", p, "UInt", s, "UInt", Codec, "Ptr", 0, "Uint*", &nSize := 0) &&
			(VarSetStrCapacity(&VarOut, nSize << 1), DllCall("crypt32\CryptBinaryToString", "Ptr", p, "UInt", s, "UInt", Codec, "Str", VarOut, "Uint*", &nSize)))
			return (VarSetStrCapacity(&VarOut, -1), VarOut)
	}

	Static Decode(VarIn, Codec := 0x00000001) {
		if (DllCall("crypt32\CryptStringToBinary", "Str", VarIn, "UInt", 0, "UInt", Codec, "Ptr", 0, "Uint*", &SizeOut := 0, "Ptr", 0, "Ptr", 0) &&
			DllCall("Crypt32.dll\CryptStringToBinary", "Str", VarIn, "UInt", 0, "UInt", Codec, "Ptr", VarOut := Buffer(SizeOut), "Uint*", &SizeOut, "Ptr", 0, "Ptr", 0))
			return VarOut
	}
}

Теперь кодируется верно, а вот раскодировка почему-то отправляет пустое значение. Даже если поправить функцию как с первым вариантом( то есть добавить параметр Bytes в функцию).

6

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Зачем вы отправляете в функцию 2 параметра?
Чтобы понять почему у вас не работает, вам надо понять как эта функция работает, что принимает и что возвращает.

7 (изменено: Clannad5, 2022-08-21 17:57:33)

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Malcev
а я попробовал только что и без второго параметры и вы правы, результат не меняется, я просто уже запутался и как-то сам его добавил.
Однако убрав их, кодируется, но на онлайн сервисах по декодировке возвращает результат со странными невидимыми знаками в виде квадратов.

Видимо из-за этих квадратов, у меня не работает декод метод.

8

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Нужно понять, что в base64 кодируется не строка, а байты. Как строка представлена в байтах, зависит от её кодировки.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

teadrinker

Я попробовал поставить кодек "0x00000004" и он добавляет бессмысленные нули между байтами "48 00 65 00 6c 00 6c 00  6f 00".
Поэтому я понял, почему кодируется так странно(с невидимыми символами), но не понял как это исправить .

10

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Это не кодек, а формат.
https://docs.microsoft.com/en-us/window … ytostringw

11

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

Почему бессмысленные? Вполне осмысленные!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12 (изменено: Clannad5, 2022-08-21 23:06:35)

Re: AHK: AHK_H V2 вызов класса из Base64.ahk

В общем, долго мучаясь я нашел тему с нужным мне содержанием.
Отредактировал главный пост.