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

Доброго всем времени суток. Хочу поделиться маленьким решением маленькой проблемы. Думаю, будет интересно новичкам. Я не раз встречал на форумах вопрос: как преобразовать двоичные данные в строку? В частности, к примеру, частенько нужно получить хэш файла 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 не будет опубликован. Обязательные поля помечены *