Обсуждение:Конвертер из/в Base64
0 (0)
Обсуждение:Конвертер из/в Base64 ( Обсуждение примера 30.05.2006 15:36 )
3(1)Конвертирует текст в Base64 и наооборот. За тестовое сообщение взят пример из альбомов УФЭБС. Сходится, проверял.
С уважением,
Измайлов Ф.В.
Посмотреть пример
>> ОтветитьОшибка ( ken 30.05.2006 16:02 )
0(0)При выполнении макроса на строке
obj=ActiveX("MSScriptControl.ScriptControl");
выдается ошибка
───────────────────────┐
ActiveX Error: │
Invalid class string │
(800401F3) │
───────────────────────┘
В чем может быть дело?
>> ОтветитьСкорее всего ... ( Izmajlov 30.05.2006 16:27 )
0(0)Это значит на компьютере не установлен WSH. Либо уж ОС старая, или ОС не Windows..
Если не ошибаюсь, то уже на Win98 устанавливали WSH.
Попробуйте по этой ссылке скачать и установить http://www.microsoft.com/downloads/details.aspx?FamilyID=c717d943-7e4b-4622-86eb-95a22b832caa&DisplayLang=en
С уважением,
Измайлов Ф.В.
>> ОтветитьУстановил, но результат тот же ( ken 30.05.2006 16:44 )
0(0)┌───────────────────────────────────────────────────────────────┐
│ Ошибка base64.mac │
│ Строка 6 │
│ Ошибка выполнения Create object MSScriptControl.ScriptControl │
│ Будем отлаживать? │
│ │
│ Нет ▄ Да ▄ │
│ ▀▀▀▀▀ ▀▀▀▀▀ │
└───────────────────────────────────────────────────────────────┘
Система Win2k SP4, RS_Bank Версия: 5.00.086.22, трехзвенка
>> ОтветитьПервый раз с таким встречаюсь. ( Izmajlov 30.05.2006 17:14 )
0(0)Это уже из области фантастики..или политики прав на компе :)
Версии РСБанка и трехзвенки нипричем.
ScriptControl - это объект ОС, причем в стандартной поставке, встроенный, так сказать.
Если ПО не может создать объект, то вариантов два, либо этот объект не зарегистрирован в ОС (другими словами - не установлен), или нет прав на создание СОМ-объектов. Другого придумать ничего не могу.
Измайлов Ф.В.
>> ОтветитьНа счет прав... ( ken 30.05.2006 17:45 )
0(0)Работают под администратором, если можно, то подскажите, что нужно еще посмотреть?
Об объектах...Работа из макросов с WORD, Excel идет нормально или
это не корректное сравнение.
И еще - как проверить регистрацию, установку ScriptControl в OC, в реестре есть
HKEY_CLASSES_ROOT\MSScriptControl.ScriptControl
есть WINNT\system32\msscript.ocx
>> ОтветитьСовсем забыл про ... ( Izmajlov 30.05.2006 17:58 )
0(0)Макрос написан так, что все объекты создаются на ЛОКАЛЬНОЙ машине !!!!
Извиняюсь, если ввел в заблуждение. Смотрите локальный комп.
Или надо переписать макрос под серверное использование, но я стараюсь делать так, что бы все макросы, которые используют СОМ-объекты, выполняли действия с этими объектами на рабочих станциях.. Это и по безопастности вернее, и по устойчивости работы сервера.
С уважением,
Измайлов Ф.В.
>> ОтветитьЛокальный комп ( ken 30.05.2006 18:20 )
0(0)Все описанное мною выше и относится к локальной машине, а не к серверу.
Сегодня рабочий день закончен, может утро вечера мудренее...
>> ОтветитьФеликс, перепиши пример на два TArray - я и не надо ActiveX (+) ( григ 31.05.2006 07:44 )
0(0)Поиск в массиве можешь взять из hl_array.mac, который я тебе высылал.
Кроме того, если запускать пример в 3-х звенке, то объект будет создан на сервере. У меня все работает. Но все-таки, ради поиска соответствия в двух таблицах применять ActiveX - тяжеловатое решение.
>> ОтветитьТак оно так, но.. ( Izmajlov 31.05.2006 08:19 )
0(0)Гриш, ты прав, но есть и другая сторона вопроса. Эстетическая.. :). Конечно, переписав (скорее всего будет и такой вариант) под массивы, мы придем к необходимости при обработке каждой комбинации (сначала 6-значной, потом 8-значной) пробегать по соответствующему массиву. Как программиста, меня это "ломает", делать такой алгоритм, в старые времена так и было, бегали по массиву, а что делать, если другого инструментария не было?
У объекта Dictionary есть свойство поиск по ключу, в качестве ключа может выступать ЛЮБОЕ значение. Вернее, это не поиск, а получение Item по ключу. Если на сервере или на локальной машине установлен Windows, то есть и WSH, это практически 100%. Ограничений по размеру словаря нет, скорость получения информации приемлимая, почему мы должны не использовать эту функциональность? Это конечно не догма, а руководство к действия, как шутили в армии :).
ActiveX объекты - это реальность, и стандартная реальность. Если у ребят не получается на компе создать СОМ-объект, то это что-то непонятно. Повторюсь, я не догматик, поэтому в ближайшее время (часы) перепишу под использование массивов. Только, если будут длинные строки, насколько увеличится конверитирование??
С уважением,
Измайлов Ф.В.
>> ОтветитьМассивы маленькие - скорость не упадет (+) ( григ 31.05.2006 10:11 )
0(0)Зато экномим на общении с ActiveX-объектом - там цепочка достаточно наворочанная. Если WSH не юзает кэш для быстрого обращения к элементам словаря, то значит он тоже пробегает словарь сверху донизу.
Впрочем есть более эффективная реализация, как пишет Александр Иванов. Вот исходники из и-нета (надо только на РСЛ перерисовать):
BASE64 на VB & C++ Использовать класс можно так: Dim b64 as New BASE64 dstStr = b64.cBASE64(srcStr) Реализация класса: -------------------------------------------------------------------------------- Option Explicit Const Base64Table As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Private b64(63) As String Private b256(255) As Long Private Sub Class_Initialize() Dim i As Long For i = 0 To 63 Step 1 b64(i) = Mid$(Base64Table, i + 1, 1) b256(AscB(b64(i))) = i Next End Sub ' Кодирует данные в кодировку BASE64 Public Function cBASE64(s As String) As String Dim lenStr, endPos, lastChars, l, i As Long lenStr = Len(s) lastChars = lenStr Mod 3 endPos = lenStr - lastChars For i = 1 To endPos Step 3 l = CLng(AscB(Mid$(s, i, 1))) * 65536 + CLng(AscB(Mid$(s, i + 1, 1))) * 256 + CLng(AscB(Mid$(s, i + 2, 1))) cBASE64 = cBASE64 & b64(l \ 262144) & b64((l \ 4096) Mod 64) & _ b64((l \ 64) Mod 64) & b64(l Mod 64) Next Select Case lastChars Case 1 l = CLng(AscB(Right(s, 1))) * 16 cBASE64 = cBASE64 & b64((l \ 64) Mod 64) & b64(l Mod 64) & "==" Case 2 l = CLng(AscB(Mid$(s, lenStr - 1, 1))) * 1024 + CLng(AscB(Right$(s, 1))) * 4 cBASE64 = cBASE64 & b64((l \ 4096) Mod 64) & _ b64((l \ 64) Mod 64) & b64(l Mod 64) & "=" End Select End Function ' ДеКодирует данные из кодировки BASE64 Public Function eBASE64(s As String) As String Dim lenStr, endPos, lastChars, l, i As Long lenStr = Len(s) If Right(s, 2) = "==" Then lenStr = lenStr - 2 Else If Right(s, 1) = "=" Then lenStr = lenStr - 1 End If lastChars = lenStr Mod 4 endPos = lenStr - lastChars For i = 1 To endPos Step 4 l = b256(AscB(Mid$(s, i, 1))) * 262144 + b256(AscB(Mid$(s, i + 1, 1))) * 4096 + b256(AscB(Mid$(s, i + 2, 1))) * 64 + b256(AscB(Mid$(s, i + 3, 1))) eBASE64 = eBASE64 & Chr(l \ 65536) & Chr((l \ 256) Mod 256) & _ Chr(l Mod 256) Next Select Case lastChars Case 2 l = b256(AscB(Mid$(s, lenStr - 1, 1))) * 1024 + b256(AscB(Mid$(s, lenStr, 1))) * 16 eBASE64 = eBASE64 & Chr(l \ 256) Case 3 l = (b256(AscB(Mid$(s, lenStr - 2, 1))) * 4096 + b256(AscB(Mid$(s, lenStr - 1, 1))) * 64 + b256(AscB(Mid$(s, lenStr, 1)))) \ 4 eBASE64 = eBASE64 & Chr(l \ 256) & Chr(l Mod 256) End Select End Function -------------------------------------------------------------------------------- Описание алгоритма произвело на Сергея Кривулю неизгладимое впечатление, но исходник на VB не подходил по причине написания проекта на C/C++. Сергей прислал мне BASE64 кодирование, реализованное на C, за что ему большое спасибо :-) С удовольствием публикую его реализацию, однако, уведомляю, что я не проверял этот код на работоспособность :-P void Base64_code(IN const CHAR* strIn, OUT CString& strOut) { const static CHAR base64ABC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; strOut.Empty(); const size_t len = strlen(strIn); for(int i=0; i<len; i+=3) { LONG l = ( ((LONG)strIn[i ])<<16 ) | (((i+1) < len) ? (((LONG)strIn[i+1])<<8 ) : 0 ) | (((i+2) < len) ? ( (LONG)strIn[i+2] ) : 0 ); strOut += base64ABC[(l>>18) & 0x3F]; strOut += base64ABC[(l>>12) & 0x3F]; if (i+1 < len) strOut += base64ABC[(l>> 6) & 0x3F]; if (i+2 < len) strOut += base64ABC[(l ) & 0x3F]; } switch (len%3) { case 1: strOut += '='; case 2: strOut += '='; } } void Base64_decode( IN const CHAR* strIn, // на вход - зашифрованная строка OUT CString& strOut // на выход - расшифрованная строка ) { const static CHAR base64ABC[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; strOut.Empty(); const size_t len = strlen(strIn); for (int i=0; i<len; i+=4) { LONG l = (( (strIn[i ] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i ]) - base64ABC)) << 18) : 0) | ((((i+1) < len) && (strIn[i+1] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i+1]) - base64ABC)) << 12) : 0) | ((((i+2) < len) && (strIn[i+2] != '=')) ? (((LONG)(strchr(base64ABC, strIn[i+2]) - base64ABC)) << 6 ) : 0) | ((((i+3) < len) && (strIn[i+3] != '=')) ? ((LONG)(strchr(base64ABC, strIn[i+3]) - base64ABC)) : 0); BYTE ch1 = ((l>>16) & 0xFF); if (ch1) strOut += ch1; BYTE ch2 = ((l>>8 ) & 0xFF); if (ch2) strOut += ch2; BYTE ch3 = ( l & 0xFF); if (ch3) strOut += ch3; } } //Ну и как бонус :) функция для формировки заголовка авторизации по логину и паролю: void GetHeaderAuthorization( IN const CString& strLogin, // на вход - строка с логином IN const CString& strPassword, // на вход - строка с паролем OUT CString& strHeaderAuthorization // на выход - сторка, содержащая заголовок авторизации ){ CString strLoginPass(strLogin + ':' + strPassword); // формирую строку для шифрования CString strEncode; // сторка, где будет содержаться результат шифрования Base64_code(strLoginPass, strEncode); // шифрование strHeaderAuthorization = CString("Authorization: Basic " + strEncode + "\r\n"); // формирую заголовок авторизации }
>> Ответить
Я зачем в данном случае в массиве "искать" ? ( Иванов Александр 31.05.2006 08:56 )
0(0)Если можно просто по индексу взять? И конечно использовать жабаскрипт для получения строкового представления битов, это круто. Для демострации возможностей и умений... Вот только не для реальной работы. В частности для преобразования в base64 куда проще и быстрее брать по 3 байта из строки, переводить их в целое число и получать индекс в массиве кодов в цикле путем вычисления остатка от деления на 64 с последующим сдвигом. Ну и конечно небольшая обработка для завершающих байт, если длина строки не кратна 3...
>> ОтветитьЧем сейчас и занимаюсь. ( Izmajlov 31.05.2006 09:05 )
0(0)Отказываюсь (по просьбам трудящихся :) ) от жабаскриптов.
Но.. макрос работает с использованием WSH? Работает. Почему это нереальная работа?
Выдает результат? Почему это "нереальный" результат?
Если в РСЛ дали возможность использовать СОМ-объекты, то и давайте их использовать. Мне кажется, я к месту их использую, и кода меньше, и технологии вперед двигаем.
Измайлов Ф.В.
>> ОтветитьВозможно я неправильно выразился... ( Иванов Александр 31.05.2006 09:16 )
0(0)Прошу извинить. Я имел в виду неэффективность данной реализации, что на мой взгляд может препятствовать ее применению в нагруженных системах.
Что касается использования COM - объектов, то тогда уж лучше вообще вынести в этот объект всю реализацию...
Я конечно понимаю, что RSL не лучший инструмент для манипулирования битовыми массивами, но данная задача ему вполне по силам...
>> ОтветитьДа я и не в претензиях :)) ( Izmajlov 31.05.2006 14:38 )
0(0)В примерах (там же, "конвертеры и шлюзы") выложил архив, в котором макрос (на массивах), СОМ-объект и пример его использования.
Уж не стал в макросе применять хитрости по вычислению индексов, бинарных кодов и пр., просто нет времени на обстоятельную проработку алгоритма, пришлось "втупую" забить массивы.
С уважением,
Измайлов Ф.В.
>> Ответить