Пример преобразования двоичных данных в строку

Доброго всем времени суток. Хочу поделиться маленьким решением маленькой проблемы. Думаю, будет интересно новичкам. Я не раз встречал на форумах вопрос: как преобразовать двоичные данные в строку? В частности, к примеру, частенько нужно получить хэш файла MD5 в текстовом виде, но как мы знаем 1С возвращает его в виде двоичных данных.

Самый простой пример, который я видел, это просто выполнить приведение типа двоичных данных к строке и удалить пробел:

СтрЗаменить(Строка(ДвоичныеДанные), " ", "");

Но проблема, на мой взгляд, в том, что если строковое представление двоичных данных в 1С изменится, то все может пойти не по плану, да и как-то не по христиански это…

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

Функция ДвоичныеДанныеВСтроку(ДвоичныеДанные) Экспорт
Результат = "";
ЧтениеДанных = Новый ЧтениеДанных(ДвоичныеДанные);
Байт = ЧтениеДанных.ПрочитатьБайт();
Пока Не Байт = Неопределено Цикл
Результат = Результат + ЧислоDECtoHEX(Байт, 2);
Байт = ЧтениеДанных.ПрочитатьБайт();
КонецЦикла;

Возврат Результат;
КонецФункции

Функция ЧислоDECtoHEX(ИсходноеЧисло, ДлинаВыравнивания = 0) Экспорт
Результат = "";
Значение = ИсходноеЧисло;
Пока Значение > 0 Цикл
Результат = Сред("0123456789ABCDEF", (Значение % 16) + 1, 1) + Результат;
Значение = Цел(Значение / 16);
КонецЦикла;

Результат = ?(Результат = "", "0", Результат);
Возврат ?(ДлинаВыравнивания > 0, СтрДопЛ(Результат, ДлинаВыравнивания, "0"), Результат);
КонецФункции

Функция СтрДопЛ(ДополняемаяСтрока, ДлинаСтроки, СимволДополнения) Экспорт
Результат = ДополняемаяСтрока;

Пока СтрДлина(Результат) < ДлинаСтроки Цикл
Результат = СимволДополнения + Результат;
КонецЦикла;

Возврат Результат;
КонецФункции

Собственно пример использования:

Хэш = Новый ХешированиеДанных(ХешФункция.MD5);
Хэш.ДобавитьФайл("C:File.bin");
ДвоичныеДанные = Хэш.ХешСумма;

Результат = ДвоичныеДанныеВСтроку(ДвоичныеДанные);
Сообщить(Результат, СтатусСообщения.Информация);

Эх, если бы разработчики платформы еще сделали функцию преобразования десятичного числа в шестнадцатеричное, то программного кода было бы в несколько раз меньше. Вообще странный подход у разработчиков платформы к расширению функционала, они добавили новую функцию ЧислоИзШестнадцатеричнойСтроки, но, что их остановило сделать функцию обратного преобразования, к примеру ЧислоВШестнадцатеричнуюСтроку, непонятно…

Всем добра, спасибо за внимание!

19 Comments

  1. apic

    Спасибо, теперь знаю как читать байты

    Reply
  2. Armando

    Наверняка Вы пользовались СП, но не дочитали до методов ПолучитьДвоичныеДанныеИзСтроки и ПолучитьСтрокуИзДвоичныхДанных.

    Reply
  3. Поручик

    А ещё меня удивляет на.. зачем возвращать хэш MD5 в виде двоичных данных. Это же касается серийного номера сертификата в соответствующей функции и некоторых других.

    Reply
  4. frkbvfnjh

    Можете написать как решить данную задачу с помощью этих функций (ПолучитьДвоичныеДанныеИзСтроки и ПолучитьСтрокуИзДвоичныхДанных)? У меня что-то «думки» не хватает, буду благодарен.

    Reply
  5. bulpi

    (2)

    Не нашел таких методов в СП. (8.3.9)

    Reply
  6. bulpi

    Есть еще вариант :

    ТипДвоичныеДанные = ФабрикаXDTO.Тип(«http://www.w3.org/2001/XMLSchema», «hexBinary»);

    ДвоичныеДанные = ФабрикаXDTO.Создать(ТипДвоичныеДанные,ХешSHA1.ХешСумма);

    Возврат ДвоичныеДанные.ЛексическоеЗначение;

    Reply
  7. johnnyshut23

    Спасибо большое, полезно!

    Reply
  8. Armando

    (4) В данном случае подойдет метод ПолучитьHexСтрокуИзДвоичныхДанных

    Хэш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хэш.ДобавитьФайл(«C:File.bin»);
    ДвоичныеДанные = Хэш.ХешСумма;
    
    Результат = ПолучитьHexСтрокуИзДвоичныхДанных(ДвоичныеДанные);
    Сообщить(Результат, СтатусСообщения.Информация);
    Reply
  9. Armando
  10. frkbvfnjh

    (8) АААААААААААААААААА, Спасибо Бро!!! Не знал о таком! Не жалею, что сделал публикацию, 5 минут позора, зато узнал то, что давно мучило и не узнал бы никогда этих элементарных вещей.

    Reply
  11. frkbvfnjh

    (6) Это ваще бомба! От куда вы все это берете? С этим XDTO что только не делают, я видел даже регулярные выражения обрабатывают. Спасибо!

    Reply
  12. frkbvfnjh

    Всем огромное спасибо!

    Reply
  13. cool.vlad4

    (3) чтобы можно было с этими двоичными данными делать все что хочешь, если посмотришь как делают апи у всяких криптобиблиотек в частности, там все построено по принципу пайпа, ты можешь эти двоичные данные еще куда-нибудь запихнуть и не париться, принимает ли у тебя метод текстовое представление(скорее даже hex представление, о текстовом вообще молчу, поскольку это не комильфо по определению из-за кодировок), я именно поэтому в своей ВК делал возврат двоичных данных

    Reply
  14. Поручик

    (9) 8.3.10 не везде есть. Некоторые наши заказчики счастливо работают на 8.3.8 и большего не надо.

    Reply
  15. Поручик

    (6) А я вот подумал и сделал в нашей конфе так же, на всякий случай. До того двоичные данные преобразовывал тупо строкой.

    Reply
  16. kuzyara

    Строка(ДвоичныеДанные) — так делать нельзя, т.к. съедаются #13#10

        // прочитаем двоичные данные в строку
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.Прочитать(ФайлДанных, «ISO-8859-1», «»);
    ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
    
    Reply
  17. Synoecium

    (16) а почему они будут съедаться, двоичные данные представляются строкой в base16 виде и все символы там печатные.

    Например,

    тест64 = «DQkIExA=»;
    Сообщить(Строка(Base64Значение(тест64 )));

    выдаст

    0D 09 08 13 10

    что соответствует исходной строке

    Reply
  18. nacsa

    (17) да, я тоже не понял этого.

    Reply
  19. andr2510

    21 век на дворе, а статья как никогда полезна оказалась.

    В одночасье у людей по всей сети перестала запускаться буха. Причем именно падать. Вылетала на строке:

    ОтпечатокHex = ПолучитьHexСтрокуИзДвоичныхДанных(Сертификат.Отпечаток); в общем модуле ПерсонализированныеПредложенияСервисовКлиент.

    Причем в отладчике Отпечаток был обычными двоичными данными. В итоге заменил на ваш модуль.

    Других путей решения найти не смог. Можно было удалить личные сертификаты пользователя, но это не вариант.

    Спасибо 1С-у. Шикарные функции в платформу встраивает.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *