1

Тема: VBS: Простой способ декодирования base64

Придумал очень простой способ декодирования base64:

Set oMSXML = CreateObject("Msxml2.DOMDocument")
Set node = oMSXML.createElement("tmp")
node.dataType = "bin.base64"
node.text = "PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4="
oMSXML.load(node.nodeTypedValue)
WScript.Echo oMSXML.xml

"VBS:" написал в заголовке, исключительно для привлечения читателей (переписать на JS - элементарно).
Более того, если код использовать в HTA приложении, то можно обойтись и без объявления "Msxml2.DOMDocument". Достаточно добавить в код тег:

<XML id="oMSXML"></XML>

Т.е. все преобразование осуществляется с помощью средств XML без привлечения каких бы то ни было сторонних объектов (как то "ADODB.Stream" и пр.).
К тому же преобразование строк более универсально, поскольку чтение/запись кодированного/декодированного текста в файлы организовать просто элементарно.
И все бы хорошо. Берем и добавляем в Коллекцию. Ан - нет:
Проблема в том, что закодированный в base64 текст должен быть обязательно заключен в теги (в любые). Иначе преобразование не сработает
Всю башку сломал. Как заставить работать преобразование с обычным текстом???
Может светлая голова предложит решение проблемы?

2 (изменено: Flasher, 2012-03-18 16:39:32)

Re: VBS: Простой способ декодирования base64

А где тут сам момент сохранения без использования ADODB.Stream?
И почему просто не отрезать эти теги с пом. Mid?

3

Re: VBS: Простой способ декодирования base64

2Flasher
В данном коде нет ни загрузки текстовой строки из файла, ни сохранения раскодированного текста в файл.
Как я уже говорил, дописать, при необходимости, подобные процедуры сможет даже ребенок.

В уже преобразованном тексте отрезать теги - элементарно - можно Mid, а можно еще проще - брать не oMSXML.xml а oMSXML.text.
Проблема в том что исходный текст должен обязательно быть в тегах.
Т.е. в данном примере "PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4=" - это текст в тегах!

4 (изменено: Flasher, 2012-03-18 22:23:13)

Re: VBS: Простой способ декодирования base64

mozers пишет:

В данном коде нет ни загрузки текстовой строки из файла, ни сохранения раскодированного текста в файл.
Как я уже говорил, дописать, при необходимости, подобные процедуры сможет даже ребенок.

Не вижу, где это написано. Но утрировать так сильно неоязательно.
Было написано

без привлечения каких бы то ни было сторонних объектов (как то "ADODB.Stream" и пр.).

Так вот этот "сторонний" объект и используется в коде первого поста указанной ветки для сохранения преобразованного кода в файл. Пытаюсь увидеть реальность упрощения в подходе, но всё никак не могу. Фактически кусок аналогии, только слегка под себя подрихтованный.

mozers пишет:

Проблема в том что исходный текст должен обязательно быть в тегах.
Т.е. в данном примере "PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4=" - это текст в тегах!

Я судил по тексту сообщения. С бинарниками так не попляшешь, это да. Но пока сам метод себя никак не превознёс над имеющимся в коллекции, поэтому и не вижу особого смысла убиваться над этой задачей.

5

Re: VBS: Простой способ декодирования base64

Доброго времени суток господа. Я видимо что то не уловил. Не могу понять какие тэги требуются при декодированиии текста ?


Option Explicit

MsgBox decode("//4/BEAEPgQyBDUEQAQ6BDAEIAA0BDUEOgQ+BDQEOARABD4EMgQwBD0EOARPBCAAQgQ1BDoEQQRCBDAE","bin.base64")

'Функция декодирования
Function decode(data,encoder)
    With CreateObject("Msxml2.DOMDocument").CreateElement("tmp")
		.dataType = encoder
		.text = data
		decode = .nodeTypedValue
	End With
End Function

Опробовал свой старый пример... Работает без всяких посторонних тегов. Что я упустил ?

UPD.

Я так понимаю для HTA, Вы хотели использовать нечто подобное.


<html>
	<head>
		<meta charset="windows-1251">
	</head>
	<body>
		<xml id="oXML"></xml>
		<script language=VBScript>
		With oXML.createElement("tmp")
			.dataType = "bin.base64"
			.text = "PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4="
			MsgBox .nodeTypedValue
		End With
		</script>
	</body>
</html>

К сожалению при декодировании получаю китайскую азбуку. ) Могу только догадываться, что там в тексте.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

6

Re: VBS: Простой способ декодирования base64

2Xameleon
Вот теперь не уловил я.
Откуда взялась такая строка "//4/BEAEPgQyBDUEQAQ6BDAEIAA0BDUEOgQ+BDQEOARABD4EMgQwBD0EOARPBCAAQgQ1BDoEQQRCBDAE" ?
Ведь строка "проверка декодирования текста" закодированная в base64 выглядит совсем иначе: "0L/RgNC+0LLQtdGA0LrQsCDQtNC10LrQvtC00LjRgNC+0LLQsNC90LjRjyDRgtC10LrRgdGC0LA=".
Если ее вставить в твои скрипты то на выходе получим лишь иероглифы, поскольку в предложенных вариантах на выходе получается бинарное содержимое, а не текст.
А вот в моем варианте на выходе получаем нормальный текст.
Проблема лишь в том, что исходная строка должна быть закодирована вместе с обрамляющими тегами.
Т.е. строка "проверка декодирования текста" должна быть заключена в теги "<q>проверка декодирования текста</q>" до ее кодирования в base64. Итого получаем "PHE+0L/RgNC+0LLQtdGA0LrQsCDQtNC10LrQvtC00LjRgNC+0LLQsNC90LjRjyDRgtC10LrRgdGC0LA8L3E+". Вот такая строка уже нормально раскодируется моим скриптом.
Кстати для тестов можно использовать Online base64 декодер. Впрочем, подобных ресурсов в инете - тьма.

7 (изменено: Xameleon, 2021-02-17 13:17:34)

Re: VBS: Простой способ декодирования base64

Насколько я понимаю, тут дело просто в кодировке. ) У меня строка декодируется без проблем. И обрамляющие тэги я опять же не использую.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8

Re: VBS: Простой способ декодирования base64

Аналогичная проблема

function DecodeBase64(S)
{
    var HTMLFile = new ActiveXObject("HTMLFile");
    HTMLFile.write('<XML id=o123><tmp xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64" encoding="UTF-8">'+S+'</tmp></XML>');
    return HTMLFile.parentWindow.o123.firstChild.nodeTypedValue;
}

var S="PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4=";
WScript.Echo(DecodeBase64(S));
var S="//4/BEAEPgQyBDUEQAQ6BDAEIAA0BDUEOgQ+BDQEOARABD4EMgQwBD0EOARPBCAAQgQ1BDoEQQRCBDAE";
WScript.Echo(DecodeBase64(S));

Проверено под ХР.

9

Re: VBS: Простой способ декодирования base64

Под Win7 результат такой же.
Тот способ декодирования что предложил я, требует чтобы текст в base64 включал в себя обрамляющие теги.
Те варианты одного и того же способа что привели вы, требует чтобы текст в base64 тоже что то включал.
Почему я так подумал? А потому что ваша успешно декодируемая строка не является валидным текстом в base64!
В нее что то еще добавлено. Что???
Увы, и у моего и у вашего вариантов - один и тот же дефект - нет возможности декодировать "чистый" текст (без дополнительных добавок к нему).
Для своего я пока нашел единственное полезное применение - декодирование документов УФЭБС (в них как раз текст сообщения закодирован вместе с обрамляющими тегами).

10

Re: VBS: Простой способ декодирования base64

mozers, я бы и рад ответить вам, что нибудь в стиле "О да смертный ! Для достижения максимальной силы зелья, я добавляю измельчённый зуб дракона, пять капель слёз василиска и щепотку тёртых корней мандрагоры !!!", но нет. Ничего я к тексту не добавляю. И как я уже говорил, весь секрет в кодировке. В какой закодировали, в такой обратно и получили. Не поленился - собрал что то наподобии утилитки кодировщика. Над условиями и проверками особо не трудился. Но суть она показывает. Варианты кодировок (windows-1251/utf-8/utf-16) можете добавить сами, при желании. )


<html>
    <head>
        <title>encode / decode</title>
        <meta charset="windows-1251">
        <style>
        *{font-family:Tahoma;font-size:13px;}
        </style>
    </head>
    <body scroll=no>
        <table width=100% height=100%>
            <tr>
                <td colspan=2>
                    <button id="btnEncode">Кодировать</button>
                    &nbsp;
                    <button id="btnDecode">Декодировать</button>
                    <hr>
                    Кодировщик
                    <select id="selEncoder">
                        <option value="bin.base64">bin.base64</option>
                        <option value="bin.hex">bin.hex</option>
                    </select>
                    Кодировка
                    <select id="selCharset">
                        <option value="windows-1251">windows-1251</option>
                        <option value="utf-8">utf-8</option>
                        <option value="utf-16">utf-16</option>
                    </select>
                    <hr>
                </td>
            </tr>
            <tr>
                <td>Исходные данные</td>
                <td>Закодированные данные</td>
            </tr>
            <tr>
                <td width=50% height=100%><textarea id="txtDecoded" style="width:100%;height:100%;"></textarea></td>
                <td><textarea id="txtEncoded" style="width:100%;height:100%;"></textarea></td>
            </tr>
        </table>
        <script language=vbscript>
        Option Explicit
        
        Sub btnEncode_onclick()
            if txtDecoded.value <> "" Then txtEncoded.value = encode(strToBin(txtDecoded.value,selCharset.value),selEncoder.value)
        End Sub

        Sub btnDecode_onclick()
            if txtEncoded.value <> "" Then txtDecoded.value = binToStr(decode(txtEncoded.value,selEncoder.value),selCharset.value)
        End Sub
        
        Function binToStr(Data, Charset)
            With CreateObject("ADODB.Stream")
                .Type = 1
                .Open
                .Write Data
                .position = 0
                .Type = 2
                .Charset = Charset
                binToStr = .readText
            End With
        End Function

        Function strToBin(Text, Charset)
            With CreateObject("ADODB.Stream")
                .Type = 2
                .Charset = Charset
                .Open
                .WriteText Text
                .position = 0
                .Type = 1
                strToBin = .read
            End With
        End Function

        Function encode(Data, encoder)
            With CreateObject("Msxml2.DOMDocument").createElement("tmp")
                .dataType = encoder
                .nodeTypedValue = Data
                encode = .Text
            End With
        End Function

        Function decode(Data, encoder)
            With CreateObject("Msxml2.DOMDocument").createElement("tmp")
                .dataType = encoder
                .Text = Data
                decode = .nodeTypedValue
            End With
        End Function
        </script>
    </body>
</html>

Результат декодирования вашего текста у меня

В случае неправильного указания кодировки
http://zalil.ru/32904605/406d5bcf.4f6ad818/1.gif

В случае правильного указания кодировки
http://zalil.ru/32904613/406d5bcf.4f6ad818/2.gif

Результат декодирования моего текста

Методом эксперимента выяснил, что у меня кодируется в utf-16

http://zalil.ru/32904650/406d5bcf.4f6ad818/3.gif

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

11

Re: VBS: Простой способ декодирования base64

2Xameleon
Спасибо за утилитку!
Вот потыкал ее и все понял:
1. Ваш метод: (запихнуть в ноду кодированный текст, а потом прочитать из её же с помощью nodeTypedValue) работает только если в base64 был закодирован текст в кодировке UTF-16. Пытаться принудительно задать кодировку в ноде 'encoding="UTF-8"' (как в примере JSman) не приводит ни к какому эффекту. Т.е. только UTF-16, что, к сожалению, сильно сужает область применения.
Значит - надо искать способ работы с другими кодировками...

2. Мой метод: (запихнуть в ноду кодированный текст, прочитать из её же с помощью nodeTypedValue, загрузить результат в XML Parser, а затем читать уже из него) четко работает с любыми кодировками. Проблема только в том, что кодированный текст должен включать обрамляющие теги.
Значит - надо искать способ обойтись без тегов...

12

Re: VBS: Простой способ декодирования base64

mozers, рад что утилитка вам пригодилась, но я так и не могу понять в каком месте кода у вас возникает необходимость обрамления тегами. Можно посмотреть на код с которым вы работаете ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

13

Re: VBS: Простой способ декодирования base64

2Xameleon
Самый первый пост.

14

Re: VBS: Простой способ декодирования base64

Провёл эксперимент. Теперь наконец то понял о чём речь. Думаю над решением. )

UPD.

Присмотрелся к вашему коду. Хм. Логично, что требуется обрамление в теги. Вы же грузите в документ байтовое представление документа


oMSXML.load(node.nodeTypedValue)

Логично, что ему нужен корневой элемент.

Собственно что и подтверждает


oMSXML.parseError.reason

Если обрамляющих тегов нет, то получаем ошибку - "Ошибка в элементе верхнего уровня документа."

Собственно поэтому свойство ".xml" не возвращает нам данных. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

15

Re: VBS: Простой способ декодирования base64

mozers, интересно, а такой код у вас срабатывает нормально ?


<html>
    <head>
        <meta charset="windows-1251">
    </head>
    <body>
        <script language=VBScript>
            
            MsgBox base64decode("PHQ+0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NDwvdD4=")

            MsgBox base64decode("77u/0J/RgNC40LzQtdGAINC00LXQutC+0LTQuNGA0L7QstCw0L3QuNGPIGJhc2U2NA==")
            
            Function base64decode(Text)
                Dim oMSXML
                Set oMSXML = document.createElement("xml")
                With oMSXML.createElement("tmp")
                    .dataType = "bin.base64"
                    .Text = Text
                    if oMSXML.Load(.nodeTypedValue) Then
                        base64decode = oMSXML.xml
                    Else
                        base64decode = oMSXML.parseError.srcText
                    End if
                End With
            End Function
        </script>
    </body>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

16 (изменено: mozers, 2012-03-19 21:47:45)

Re: VBS: Простой способ декодирования base64

2Xameleon
КЛАСС! Работает
Но... возьмем для примера строку "русский текст".
Закодируем ее с помощью Вашей утилиты.
Для кодировки windows-1251 получим: "8PPx8ero6SDy5erx8g==".
Для кодировки utf-8 получим: "77u/0YDRg9GB0YHQutC40Lkg0YLQtdC60YHRgg==".
Для кодировки utf-16 получим: "//5ABEMEQQRBBDoEOAQ5BCAAQgQ1BDoEQQRCBA==".
Для непонятной кодировки (utf-8???) с сайта base64.ru получим: "0YDRg9GB0YHQutC40Lkg0YLQtdC60YHRgg=="
Попробуем декодировать текст с помощью последнего скрипта и убедимся, что несмотря на совершенно разные строки, результат будет один и тот же.
Скрипт не смог раскодировать только строку в кодировке windows-1251

Добавлено:
Если верить что Ваша утилита кодирует правильно, то строка "8PPx8ero6SDy5erx8g==" не раскодируется и моим первоначальным скриптом тоже.

17

Re: VBS: Простой способ декодирования base64

Именно так. ) т.к кодировка явно не указана, то декодер читает её так, как считаем нужным.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

18 (изменено: mozers, 2012-03-20 11:44:58)

Re: VBS: Простой способ декодирования base64

2Xameleon
Так и есть. Но если base64 текст будет включать в себя строку с явным указанием кодировки, то и мой и твой вариант сработают
Попробуйте, к примеру, такую строку: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV0lORE9XUy0xMjUxIj8+PHA+8PPx8ero6SDy5erx8jwvcD4=".
Осталось придумать как к обычному base64-тексту динамически добавить base64-заголовок с указанием кодировки и обрамить в base64-теги...

19

Re: VBS: Простой способ декодирования base64

если base64 текст будет включать в себя строку с явным указанием кодировки, то и мой и твой вариант сработают

Не понял с чего такой вывод. ) В вашей строке "PD94bWwgdmVyc2lvbj0iMS4wIj8+PHA+8PPx8ero6SDy5erx8jwvcD4=" я не нашёл указанной кодировки. ) И код, представленный мной, декодирует её как

<?xml version="1.0"?><p>

Логично, т.к декодировщик читает строку как UTF-16 но именно русские символы тут кодируются неверно. Но это можно обойти...

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

20

Re: VBS: Простой способ декодирования base64

2Xameleon
Не понимаю. Дома эта строка - декодировалась в "<?xml version="1.0" encoding="WINDOWS-1251"?><p>русский текст</p>".
То ли другая версия MSXML иначе отрабатывает, то ли я тупо ошибся, эксперементируя с одной строкой, а в форум запостив другую.
Пока на работе разобраться не могу. Будем считать что ошибся. Строку, постом выше, заменил на правильную.

21

Re: VBS: Простой способ декодирования base64

При раскодировании base64 необходимо учитывать версию MSXML2.DOMDocument
без ошибок работает 4.0 на сайте Microsoft есть об этой ошибке
У Файлов  из Центробанка распаковывались (снималось КА) на ура
а из внутреней программы Oracle+Java+Unix+Ftp были проблемы
Перебор версий пришлось отключить

LIB.xml_base64=function(xFile)
{
//var dom =XMLDOC() // bag c версиями старше 4
var dom= new ActiveXObject("MSXML2.DOMDocument.4.0")
dom.load(xFile)
dom.setProperty("SelectionLanguage","XPath")
dom.setProperty("SelectionNamespaces",'xmlns:sen="urn:cbr-ru:dsig:env:v1.1" ')

var File1 = new ActiveXObject("ADODB.Stream")
File1.Mode = 3
File1.Type = 1
File1.Open()
debugger 
var ss=dom.selectSingleNode("//sen:Object")
if (ss!=null)
{
ss.dataType = "bin.base64"
ss=ss.nodeTypedValue  
File1.Write(ss) 
File1.SaveToFile(xFile,2)
}
File1.Close()

function XMLDOC() {
var dom
var vers = ['.6.0', '.5.0', '.4.0', ''];
vers=['']
for (var i = 0; i < vers.length; i++) {
try {
    dom = new ActiveXObject('Msxml2.DOMDocument'+vers[i]);
    dom.async = false;
    dom.validateOnParse = false;
    dom.resolveExternals = false;
    return dom;
    } 	catch (e) {}
}
return null
}
}

22

Re: VBS: Простой способ декодирования base64

Пришел домой. Все перепроверил и убедился что имела место быть банальная ошибка.
Строка для декодирования должна выглядеть так: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV0lORE9XUy0xMjUxIj8+PHA+8PPx8ero6SDy5erx8jwvcD4=".
Вот в этой строке действительно содержится указание о кодировке.
И хотя после раскодировки из тега XML исчезает 'encoding="WINDOWS-1251"' (так и задумано Microsoft) содержимое в тегах раскодируется без ошибок в указанную кодировку.

2badik
Проблемы могут возникнуть с MSXML младше версии 3.0.
То, что возможны глюки с версиями старше 4.0 - впервые слышу. Стало очень интересно где "на сайте Microsoft есть об этой ошибке"???
И, кстати, приведенный Вами код работает только потому что в тегах <sen:Object> заключено не просто закодированный в base64 текст, а специально оформленный текст: '<?xml version="1.0" encoding="WINDOWS-1251"?><PacketESID>тут уже может быть все что угодно</PacketESID>'.

23

Re: VBS: Простой способ декодирования base64

По предложению mozers-а, решил попробовать свои силы в создании прямой и обратной функции кодирования. Идею основы взял у JSman-а, за что спасибо ему огромное ).

Создал функции:

Кодирование строки в HEX строку и обратно.

strToHex - String -> Hex String
hexToStr - Hex String -> String

Преобразование строки в массив байт и обратно.

strToBin - String -> Byte()
binToStr - Byte() -> String

Кодирование строки в base64 и обратно.

strToBase64 - String -> base64
base64ToStr - base64 -> String

Зачем всё это делал ? Было приятно отказаться напрочь от CreateObject

К сожалению пришлось пожертвовать указанием кодировки при кодировании.


<html>
    <head>
		<title>encoder / decoder</title>
        <meta charset="windows-1251">
        <style>
        *{font-family:Tahoma;font-size:14px;}
        </style>
    </head>
    <body>
		<table width=100% height=100%>
			<tr>
				<td colspan=4>
					Кодировщик
					<select id="selEncoder">
						<option value="0">base64</option>
						<option value="1">hex</option>
					</select>
					<hr>
				</td>
			</tr>
			<tr>
				<td align=left>Исходные данные</td>
				<td align=right><button id="btnEncode">Encode ></button></td>
				<td align=left><button id="btnDecode">< Decode</button></td>
				<td align=right>Закодированные данные</td>
			</tr>
			<tr>
				<td colspan=2 height=100% ><textarea id="txtDecoded" style="width:100%;height:100%;"></textarea></td>
				<td colspan=2><textarea id="txtEncoded" style="width:100%;height:100%;"></textarea></td>
			</tr>
		</table>
        <script language=VBScript>
			Option Explicit

			Sub btnEncode_onclick()
				On Error Resume Next
				Select Case selEncoder.value
				Case "0"
					txtEncoded.value = strToBase64(txtDecoded.value)
				Case "1"
					txtEncoded.value = strToHex(txtDecoded.value)
				End Select
				if Err.Number <> 0 Then MsgBox Err.Description, vbCritical, document.title
			End Sub

			Sub btnDecode_onclick()
				On Error Resume Next
				Select Case selEncoder.value
				Case "0"
					txtDecoded.value = Base64ToStr(txtEncoded.value)
				Case "1"
					txtDecoded.value = hexToStr(txtEncoded.value)
				End Select
				if Err.Number <> 0 Then MsgBox Err.Description, vbCritical, document.title
			End Sub
 
			'Кодирование String в base64
			Function strTobase64(data)
			    With document.createElement("xml").createElement("t")
			        .dataType = "bin.base64"
			        .nodeTypedValue = strToBin(data)
			        strTobase64 = .text
			    End With
			End Function

			'Декодирование base64 в String
			Function base64ToStr(data)
			    With document.createElement("xml").createElement("t")
			        .dataType = "bin.base64"
			        .text = data
			        base64ToStr = binToStr(.nodeTypedValue)
			    End With
			End Function

			'Конвертация String в Byte()
			Function strToBin(text)
			    With document.createElement("xml").createElement("t")
			        .dataType = "bin.hex"
			        .text = strTohex(text)
			        strToBin = .nodeTypedValue
			    End With
			End Function

			'Конвертация Byte() в String
			Function binToStr(data)
			    With document.createElement("xml").createElement("t")
			        .dataType = "bin.hex"
			        .nodeTypedValue = data
			        binToStr = hexToStr(.text)
			    End With
			End Function

			'Кодирование строки в HEX
			Function strTohex(text)
			    Dim tmp, i
			    For i = 1 To Len(text)
			        tmp = tmp & Right("0" & Hex(Asc(Mid(text, i, 1))), 2)
			    Next
			    strTohex = tmp
			End Function

			'Декодирование строки из HEX
			Function hexToStr(hexStr)
			    Dim tmp, i
			    For i = 1 To Len(hexStr) Step 2
			        tmp = tmp & Chr("&H" & Mid(hexStr, i, 2))
			    Next
			    hexToStr = tmp
			End Function
        </script>
    </body>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24

Re: VBS: Простой способ декодирования base64

2Xameleon
Развитие первоначальной идеи пошло совсем в другом направлении
И хотя предложенное решение "простым способом" не назовешь, однако это действительно - новинка!
Такого способа, без привлечения ADODB.Stream, или замудренных математических вычислений, с использованием только функционала XML, я (да и все присутствующие) еще не видели.
Класс!

25 (изменено: badik, 2012-03-22 09:11:42)

Re: VBS: Простой способ декодирования base64

Про версии парсеров:
Ошибку выдал парсер версии 6.0.
Разбор парсером версии  5.0 прошёл (раньше не проходил ?!).

msxml6.dll: Ошибка разбора ''PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iV0lORE9XUy0xMjUxIj8+CjxQYWNrZXRF
UEQgeG1sbnM9InVybjpjYnItcnU6ZWQ6djIuMCIgRURObz0iND...'' как типа данных bin.base64.
код ошибки -2147467259

FIX: MSXML Does Not Parse Slash Mark Character with Base64 Encoded Data
http://support.microsoft.com/kb/301356/en-us


P.S
msxml6.dll
версия: 6.20.1076.0
название продукта: Microsoft(R) MSXML 6.0 SP2
Из реестра

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{88d96a05-f192-11d4-a65f-0040963251e5}\InProcServer32]
@="C:\\WINDOWS\\system32\\msxml6.dll"
"ThreadingModel"="Both"
"Class"="Microsoft.SqlServer.MSXML6.DOMDocument60Class"
"Assembly"="Microsoft.SqlServer.msxml6_interop, Version=6.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"
"RunTimeVersion"="v2.0.50727"

26 (изменено: mozers, 2012-03-21 14:24:24)

Re: VBS: Простой способ декодирования base64

2badik

msxml6.dll: Ошибка разбора

А можно взглянуть на эту строку целиком?

27 (изменено: badik, 2012-03-22 09:20:27)

Re: VBS: Простой способ декодирования base64

mozers пишет:

2badik

msxml6.dll: Ошибка разбора

А можно взглянуть на эту строку целиком?

Выслал вам на mail.ru

28

Re: VBS: Простой способ декодирования base64

2badik
Спасибо. Получил. Проверил.
Действительно файлик прекрасно парсится с помощью MSXML 3.0, 4.0, 5.0.
C MSXML 6.0 выдает ошибку разбора.
Факт весьма печальный

29

Re: VBS: Простой способ декодирования base64

Опубликовал оба HTA приложения уважаемого Xameleon в Коллекции.
Позволил себе немного подправить код.
И если Base64EncoderDecoder.hta может пригодится искателям новых алгоритмов, то из XMLCodeTester.hta получился настоящий настольный инструмент для тестирования как кода так и установленных на машине версий MSXML.

30

Re: VBS: Простой способ декодирования base64

Переправил код. Неправильно работали функции hexToStr и strToHex. Собрал функции в класс модуль clsEncoder. Сделал класс совместимым с HTA / WSH / WSF и т.п.

Оставил функции
encode(data, enctype) - функция кодирования byte() массива в hex / base64. enctype (0 - base64, 1-hex)
decode(data, enctype) - функция декодирования hex / base64 строки в byte() массив. enctype (0 - base64, 1-hex)
strToBin(data) - конвертация String в byte()
binToStr(data) - конвертация byte() в String
strToHex(srcstr) - кодирование String в Hex строку
hexToStr(ByVal hexstr) - декодирование Hex строки в исходный текст.

<html>
    <head>
        <title>encoder / decoder</title>
        <meta charset="windows-1251">
        <style>
        *{font-family:Tahoma;font-size:14px;}
        </style>
    </head>
    <body>
        <table width=100% height=100%>
            <tr>
                <td colspan=4>
                    Кодировщик
                    <select id="selEncoder">
                        <option value="0">base64</option>
                        <option value="1">hex</option>
                    </select>
                    <hr>
                </td>
            </tr>
            <tr>
                <td align=left>Исходные данные</td>
                <td align=right><button id="btnEncode">Encode ></button></td>
                <td align=left><button id="btnDecode">< Decode</button></td>
                <td align=right>Закодированные данные</td>
            </tr>
            <tr>
                <td colspan=2 height=100% ><textarea id="txtDecoded" style="width:100%;height:100%;"></textarea></td>
                <td colspan=2><textarea id="txtEncoded" style="width:100%;height:100%;"></textarea></td>
            </tr>
        </table>
        <script language=VBScript>
            Option Explicit
            
            Dim encoder
            Set encoder = new clsEncoder

            Sub btnEncode_onclick()
                On Error Resume Next
                Select Case selEncoder.value
                Case 0
                    txtEncoded.value = encoder.encode(encoder.strToBin(txtDecoded.value),0)
                Case 1
                    txtEncoded.value = encoder.strToHex(txtDecoded.value)
                End Select
                if Err.Number <> 0 Then MsgBox Err.Description, vbCritical, document.title
            End Sub

            Sub btnDecode_onclick()
                On Error Resume Next
                Select Case selEncoder.value
                Case 0
                    txtDecoded.value = encoder.binToStr(encoder.decode(txtEncoded.value,0))
                Case 1
                    txtDecoded.value = encoder.hexToStr(txtEncoded.value)
                End Select
                if Err.Number <> 0 Then MsgBox Err.Description, vbCritical, document.title
            End Sub

            Class clsEncoder
                Private xmldoc, encTypes
                Private Sub Class_Initialize()
                    On Error Resume Next
                    encTypes = Array("bin.base64","bin.hex")
                    if isObject(document) then 
                        Set xmldoc = document.createElement("xml")
                    Else
                        Set xmldoc = CreateObject("htmlfile").createElement("xml")
                    End if
                End Sub
                 
                Function encode(data, enctype)
                    With xmldoc.createElement("enc")
                        .dataType = encTypes(enctype)
                        .nodeTypedValue = data
                        encode = Replace(.Text,vbLf,"")
                    End With
                End Function

                Function decode(data, enctype)
                    With xmldoc.createElement("enc")
                        .dataType = encTypes(enctype)
                        .Text = data
                        decode = .nodeTypedValue
                    End With
                End Function

                Function strToBin(data)
                    With xmldoc.createElement("enc")
                        .dataType = "bin.hex"
                        .Text = strToHex(data)
                        strToBin = .nodeTypedValue
                    End With
                End Function

                Function binToStr(data)
                    With xmldoc.createElement("enc")
                        .dataType = "bin.hex"
                        .nodeTypedValue = data
                        binToStr = hexToStr(.Text)
                    End With
                End Function

                Function strToHex(srcstr)
                    Dim i: For i = 1 To LenB(srcstr)
                        strToHex = strToHex & Right("0" & Hex(AscB(MidB(srcstr, i, 1))), 2)
                    Next
                End Function

                Function hexToStr(ByVal hexstr)
                    Dim i: For i = 1 To Len(hexstr) Step 2
                        hexToStr = hexToStr & ChrB("&H" & Mid(hexstr, i, 2))
                    Next
                End Function

            End Class

        </script>
    </body>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

31

Re: VBS: Простой способ декодирования base64

2Xameleon
Наверное стоит упомянуть о том в какой кодировке конвертируется текст.
И о том, что результат резко отличается от классического base64 кодирования.
И хотя закодированный утилитой текст все таки может быть декодирован в строку utf-16le, но можно ли его считать корректным base64 кодом?

32

Re: VBS: Простой способ декодирования base64

А стандарты корректности где то определены ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

33

Re: VBS: Простой способ декодирования base64

Вообще то - да.

34

Re: VBS: Простой способ декодирования base64

Посмотрел. Да, видел эту статью. ) И при чём тут корректность base64 ? И что такое классический base64 ? На сколько я понимаю, он всегда классический. base64 всегда кодируется байтовые массивы. ) Я спрашивал о корректности кодируемых данных. А т.к кодируется в этом случае именно байтовый массив, то о какой корректности может быть речь ? ) А сам метод кодирования заложен в объектную модель MSXML. Поэтому его я никак нарушить не могу. В моём случае он чёрный ящик. ) Поэтому кодирование, как бы я не изголялся, будет срабатывать всегда одинаково. ) Меняется лишь интерпретация данных, с которыми мы работаем.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

35

Re: VBS: Простой способ декодирования base64

set cdo=CreateObject("CDO.Message")
set bp=cdo.BodyPart
bp.ContentTransferEncoding = "base64"
Set s=bp.GetEncodedContentStream
bp.Fields.Item("urn:schemas:mailheader:content-type").Value="text/plain; charset=""windows-1251"""
bp.Fields.Update
s.WriteText "wuDx/yDP8+/q6O0="
s.Flush
Set s = bp.GetDecodedContentStream
s.charset = "windows-1251"
msgbox s.ReadText
Я конечно далек от мысли... (с)

36

Re: VBS: Простой способ декодирования base64

smaharbA, супер :-)

37

Re: VBS: Простой способ декодирования base64

Супер ! ) А я и забыл совсем что у CDO есть такая возможность !

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

38

Re: VBS: Простой способ декодирования base64

Не удержался, позволил себе немного оптимизировать код. ) Уж очень идея понравилась.


Function base64encode(data)
    With CreateObject("CDO.Message").BodyPart
        .Charset = "utf-8"
        .ContentTransferEncoding = "base64"
        With .GetDecodedContentStream
            .WriteText data
            .Flush
        End With
        With .GetEncodedContentStream
            base64encode = .ReadText(.Size - 2) 'Отрезаем перевод строки на хвосте
        End With
    End With
End Function

Function base64decode(data)
    With CreateObject("CDO.Message").BodyPart
        .ContentTransferEncoding = "base64"
        .Charset = "windows-1251"
        With .GetEncodedContentStream
            .WriteText data
            .Flush
        End With
        With .GetDecodedContentStream
            .Charset = "utf-8"
            base64decode = .ReadText
        End With
    End With
End Function
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !