Что нового

Ошибка при кодировке строк

MockeR

Знающий
Сообщения
101
Репутация
14
Всем привет!
При использовании кодировки _Encoding_Base64Decode, SciTE выдает ошибку:
!>22:14:09 AutoIT3.exe ended.rc:-1073741819
>Exit code: -1073741819 Time: 39.011
Из за чего это может быть?

Код:
$body = FileRead("base64.txt")
$en = _Encoding_Base64Decode($body)
MsgBox(0, "Result", $en)


Func _Encoding_Base64Decode($sData)
	Local $Opcode = "0xC81000005356578365F800E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFF00FFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132338F45F08B7D0C8B5D0831D2E9910000008365FC00837DFC047D548A034384C0750383EA033C3D75094A803B3D75014AB00084C0751A837DFC047D0D8B75FCC64435F400FF45FCEBED6A018F45F8EB1F3C2B72193C7A77150FB6F083EE2B0375F08A068B75FC884435F4FF45FCEBA68D75F4668B06C0E002C0EC0408E08807668B4601C0E004C0EC0208E08847018A4602C0E00624C00A46038847028D7F038D5203837DF8000F8465FFFFFF89D05F5E5BC9C21000"

	Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($Opcode) & "]")
	DllStructSetData($CodeBuffer, 1, $Opcode)

	Local $Ouput = DllStructCreate("byte[" & BinaryLen($sData) & "]")
	Local $Ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), _
			"str", $sData, _
			"ptr", DllStructGetPtr($Ouput), _
			"int", 0, _
			"int", 0)

	Return BinaryToString(BinaryMid(DllStructGetData($Ouput, 1), 1, $Ret[0]))
EndFunc   ;==>_Encoding_Base64Decode

Вот файл base64.txt
UEsDBBQAAgAIAKmyOT4dkE/syQEAAOICAAAKAAAAQXV0b0l0LnR4dG1SzW4TMRC+V+o7zBGkKhee
IHDqgRMHHgBUqRci0SAehffhDcoTzDrremJ7Jra3m220qy6zm6SqEDdLnvl+Z/ljvbpewy/IRiqp
WSBh3iXJJSGPNvZbGF3voQ4joCkSsZDDPRGYfieBLdMIDmvswMDH2y/fV3ermzV8vv32dfXzbgG/
FY+ZWjA2ZRpbUOxNwhhRX5Zic7C5GMtKTFkBBycGA+ZhZsziapwYsk+0K2L+0fCGWDY1AqPrDara
FiJ6VY+R3s4IZ7r/afuDnuwJugclt477eeuVtw5zEf1U3jQ+H6jNJ79XUHS/BY8eiHPBEMa9LlBt
uVDHqoWxkqSiX0QwQqUen8SCl0Dd5F30GXfDc7E6OgWmE9Yqo6tf57Y8FtWEpnuioCJqzWDLczsI
Woc49R0QpDrgCI8N+z0JYxhYyxyuoJtsJKoCOQpyxvNHgDit2Y1MSTJ2k/PF5cXlxb1G0Uot8Tz/
DjKxGs+UT9RVHyCpkdT40iRSE8iq54VKpXrINtqtmm3g/fLT9YcF3M+pQ5QHWxSiDNqDxkDhBGCA
rUNDmaYTlAKNJsxiwnQqqtOojlwUVbPX5PSWCmpDeLyi0+U+4jYs/gJQSwECFAAUAAIACACpsjk+
HZBP7MkBAADiAgAACgAAAAAAAAAAACAAAAAAAAAAQXV0b0l0LnR4dFBLBQYAAAAAAQABADgAAADx
AQAAAAA=
Помогите :(
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Эту ошибку можно получить, например, так:

Код:
$tCrash = DllStructCreate("byte[80]", 12234)
ConsoleWrite(DllStructGetData($tCrash, 1) & @CR) ; Crash


-1073741819

Access Violation.

Лучше спроси там, где ты ее взял. И что это за странный вызов:

Код:
DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), "str", $sData, "ptr", DllStructGetPtr($Ouput), "int", 0, "int", 0)


Для наглядности, сравни с описанием этой функции в MSDN. Обрати внимание на типы передаваемых параметров. И что должен делать код в $Opcode? Это выдрано из какого-нибудь .exe файла?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
А вообще, разобрался. Это очередной бред от trancexx'а. Но если проверить твой base64.txt, например, здесь, то получается, что файл битый.

:smile:

P.S

У меня тоже нет никаких ошибок. Какая система? x64?
 
Автор
M

MockeR

Знающий
Сообщения
101
Репутация
14

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Тогда нужно править $Opcode, а что там, кроме автора, думаю, тебе никто не ответит. Попробуй запусти скрипт в x32, добавив в начало следующую строчку:

Код:
#AutoIt3Wrapper_UseX64= N
 
Автор
M

MockeR

Знающий
Сообщения
101
Репутация
14
Тогда нужно править $Opcode
Извините, я пока в этом 0 :'(

Функцию взял из Encoding UDF CreatoR'a

может он что-нибудь подскажет?




Добавлено:
Сообщение автоматически объединено:

Попробуй запусти скрипт в x32

Пробовал - безрезультатно(
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
MockeR сказал(а):
Пробовал - безрезультатно.

Эта директива работает только, если скрипт компилируется в AutoIt3Wrapper'е (полная версия SciTE). У тебя стоит именно она?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Попробуй увеличить буфер, больше я ничего не могу здесь посоветовать.

Код:
Local $Ouput = DllStructCreate("byte[" & (2 * BinaryLen($sData)) & "]")
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
$Data = FileRead('base64.txt')

ConsoleWrite($Data & @CR & @CR)
ConsoleWrite(_Base64_Decode($Data) & @CR)

Func _Base64_Decode($sData)

	Local $Ret, $tData

	$Ret = DllCall('crypt32.dll', 'int', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', 0, 'dword*', 0, 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	$tData = DllStructCreate('byte[' & $Ret[5] & ']')
	$Ret = DllCall('crypt32.dll', 'int', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', DllStructGetPtr($tData), 'dword*', $Ret[5], 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	Return BinaryToString(DllStructGetData($tData, 1))
EndFunc   ;==>_Base64_Decode
 
Автор
M

MockeR

Знающий
Сообщения
101
Репутация
14
Yashied сказал(а):
Попробуй увеличить буфер, больше я ничего не могу здесь посоветовать.

это ничего не изменило :'(

А вот это работает отлично :ok:
Код:
$Data = FileRead('base64.txt')

ConsoleWrite($Data & @CR & @CR)
ConsoleWrite(_Base64_Decode($Data) & @CR)

Func _Base64_Decode($sData)

    Local $Ret, $tData

    $Ret = DllCall('crypt32.dll', 'int', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', 0, 'dword*', 0, 'ptr', 0, 'ptr', 0)
    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, '')
    EndIf
    $tData = DllStructCreate('byte[' & $Ret[5] & ']')
    $Ret = DllCall('crypt32.dll', 'int', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', DllStructGetPtr($tData), 'dword*', $Ret[5], 'ptr', 0, 'ptr', 0)
    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, '')
    EndIf
    Return BinaryToString(DllStructGetData($tData, 1))
EndFunc   ;==>_Base64_Decode

Спасибо!!!
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied
А такую же для Encode можно?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR сказал(а):
А такую же для Encode можно?

Код:
$Data = 'Hello World!'
ConsoleWrite($Data & @CR)
$Data = _Base64_Encode($Data)
ConsoleWrite($Data & @CR)
$Data = _Base64_Decode($Data)
ConsoleWrite($Data & @CR)

Func _Base64_Decode($sData)

	Local $Ret, $tData

	$Ret = DllCall('crypt32.dll', 'bool', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', 0, 'dword*', 0, 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	$tData = DllStructCreate('byte[' & $Ret[5] & ']')
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', DllStructGetPtr($tData), 'dword*', $Ret[5], 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	Return BinaryToString(DllStructGetData($tData, 1))
EndFunc   ;==>_Base64_Decode

Func _Base64_Encode($sData)

	Local $Ret, $bData, $tData, $tText

	$bData = StringToBinary($sData)
	$tData = DllStructCreate('byte[' & BinaryLen($bData) & ']')
	DllStructSetData($tData, 1, $bData)
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptBinaryToStringW', 'ptr', DllStructGetPtr($tData), 'dword', DllStructGetSize($tData), 'dword', 1, 'ptr', 0, 'dword*', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	$tText = DllStructCreate('wchar[' & $Ret[5] & ']')
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptBinaryToStringW', 'ptr', DllStructGetPtr($tData), 'dword', DllStructGetSize($tData), 'dword', 1, 'ptr', DllStructGetPtr($tText), 'dword*', $Ret[5])
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	Return DllStructGetData($tText, 1)
EndFunc   ;==>_Base64_Encode
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied,
Ваши формулы в связке _Base64_Encode() - _Base64_Decode() прекрасно кодируют в обе стороны и англ. и рус. строки.
Я попробовал закодировать в Base64 строку с помощью online-сервиса Base64. (не знаю, насколько правильно он кодирует). _Base64_Decode() раскодирует англ. строку без проблем, а рус. текст корректно отображается только после обработки _Encoding_UTF8ToANSI() из Encoding.au3. В чем может быть проблема?
Код:
#include <Encoding.au3>

;$Data = 'Здравствуй Вася!'
$Data = '0JfQtNGA0LDQstGB0YLQstGD0Lkg0JLQsNGB0Y8h'
ConsoleWrite($Data & @CR)
$Data = _Base64_Decode($Data)
ConsoleWrite($Data & @CR)
ConsoleWrite(_Encoding_UTF8ToANSI($Data) & @CR)
ConsoleWrite(_Encoding_UTF8ToANSI_API($Data) & @CR)
;...
Выдает:
Код:
0JfQtNGA0LDQstGB0YLQstGD0Lkg0JLQsNGB0Y8h
Здравствуй Вася!
Здравствуй Вася!
PS
А _Encoding_UTF8ToANSI_API() в этом случае не работает. :wacko:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
В какой кодировке строка была закодирована, в такой и нужно ее декодировать, точнее, полученный результат после DllCall(). Можно ввести опциональный параметр, по аналогии с BinaryToString().

Код:
$Data = 'Здравствуй Вася!'
ConsoleWrite($Data & @CR)
$Data = _Base64_Encode($Data, 4) ; UTF8
ConsoleWrite($Data & @CR)
$Data = _Base64_Decode($Data, 4) ; UTF8
ConsoleWrite($Data & @CR)

Func _Base64_Decode($sData, $iFlag = 1)

	Local $Ret, $tData

	$Ret = DllCall('crypt32.dll', 'bool', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', 0, 'dword*', 0, 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	$tData = DllStructCreate('byte[' & $Ret[5] & ']')
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptStringToBinaryW', 'wstr', $sData, 'dword', 0, 'dword', 1, 'ptr', DllStructGetPtr($tData), 'dword*', $Ret[5], 'ptr', 0, 'ptr', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	Return BinaryToString(DllStructGetData($tData, 1), $iFlag)
EndFunc   ;==>_Base64_Decode

Func _Base64_Encode($sData, $iFlag = 1)

	Local $Ret, $bData, $tData, $tText

	$bData = StringToBinary($sData, $iFlag)
	$tData = DllStructCreate('byte[' & BinaryLen($bData) & ']')
	DllStructSetData($tData, 1, $bData)
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptBinaryToStringW', 'ptr', DllStructGetPtr($tData), 'dword', DllStructGetSize($tData), 'dword', 1, 'ptr', 0, 'dword*', 0)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	$tText = DllStructCreate('wchar[' & $Ret[5] & ']')
	$Ret = DllCall('crypt32.dll', 'bool', 'CryptBinaryToStringW', 'ptr', DllStructGetPtr($tData), 'dword', DllStructGetSize($tData), 'dword', 1, 'ptr', DllStructGetPtr($tText), 'dword*', $Ret[5])
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, '')
	EndIf
	Return DllStructGetData($tText, 1)
EndFunc   ;==>_Base64_Encode
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied
Понял, спасибо.
 
Верх