bdd2

Контрольная сумма CRC8

Опубликовал Александр Лукин (i_lo) в раздел Программирование - Теория программирования

Алгоритм вычисления CRC8 на языке 1Сv8 без использования внешних компонент

Иногда возникает необходимость посчитать какую-нибудь контрольную сумму... В зависимости от исходных требований можно использовать различные алгоритмы: CRC8, CRC16, CRC32, MD5, SHA-1 и т.д. Сложность их программной реализации в том, что они требуют оперирования с битами, что в языке 1С не очень удобно... Для простых случаев можно использовать CRC8. Его легко реализовать на языке 1С. Ниже приводится один из вариантов решения. Про оптимальность дискутировать не буду, но на расчет около пяти миллионов кодов с записью их в базу потребовалось не более 10 минут. Что вполне устроило...

// Вычисляет контрольную сумму по алгоритму crc8 для нормального полинома x**8+x**5+x**4+1
// Аргумент и результат - число
Функция CRC8(Числ) Экспорт
   
ДвСтр = ДвоичнаяСимвольнаяСтрока(Числ); // Переведем в двоичную строку
   
ДвСтрЛев = ЗаполнитьДо8Знаков(ДвСтр);   // Дополним слева до 8 знаков
   
Длина = СтрДлина(ДвСтрЛев);
   
ДвСтрЛевПрав = ДвСтрЛев + "00000000";   // Дополним справа, чтобы могли делать XOR

   
Полином = "00110001";                   // Полином в нормальной форме 31h
   
Результат = "";

    Для
Позиция = 1 по Длина цикл           // цикл по исходной двоичной строке
       
Если Сред(ДвСтрЛевПрав,Позиция,1) = "1" тогда   // Если разряд "1", то XOR с полиномом
           
а = XOR(Сред(ДвСтрЛевПрав,Позиция+1,8),Полином);
           
ДвСтрЛевПрав = Лев(ДвСтрЛевПрав,Позиция) + а + Сред(ДвСтрЛевПрав,Позиция+9);
        КонецЕсли;
    КонецЦикла;

   
Результат = Прав(ДвСтрЛевПрав,8);       // Последние 8 символов - остаток

   
КонтрЧисл = ЧислоИзДвоичнойСимвольнойСтроки(Результат); // Вернем в число

   
Возврат(КонтрЧисл);
КонецФункции

// Выполняет операцию "исключающего или" над двумя аргументами в двоичном строковом представлении
// Аргументы и результат - строки длиной 8 символов из "0" и "1"
Функция XOR(А,Б)
   
Рез = "";

    Для
с=1 по 8 цикл
       
Рез = Рез + ?(Сред(А,с,1)=Сред(Б,с,1),"0","1");
    КонецЦикла;

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

// Преобразовывает двоичную строку в число
Функция ЧислоИзДвоичнойСимвольнойСтроки(Знач Стр)
   
Числ = 0;
   
Длин = СтрДлина(Стр);
    Для
А=1 по Длин цикл
       
Числ = Числ + Pow(2,Длин-А)*Число(Сред(Стр,А,1));
    КонецЦикла;
    Возврат(
Числ);
КонецФункции

// Дополняет символьную строку "0" слева до 8 знаков
Функция ЗаполнитьДо8Знаков(Знач Исх)
    Пока
СтрДлина(Исх) < 8 цикл
       
Исх = "0" + Исх;
    КонецЦикла;
    Возврат(
Исх);
КонецФункции

// Преобразовывает число в двоичную символьную строку
Функция ДвоичнаяСимвольнаяСтрока(Знач Исх)
   
Стр = "";
    Пока
Исх > 0 цикл
       
Стр = ?((Исх%2)=1,"1","0") + Стр;
       
Исх = Цел(Исх/2);
    КонецЦикла;
    Возврат(
Стр);
КонецФункции

Для сложных расчетов, например CRC32, MD-5, замечательно подходит вызов MSScriptControl.ScriptControl и передача ему кода на javascript или vbscript. Примеры: http://www.forum.mista.ru/topic.php?id=378975, http://www.forum.mista.ru/topic.php?id=259586, http://infostart.ru/public/82506/. Но есть нюансы... Например на MS Server 2008, 64-bit, 8.1 на сервере в режиме внешнего соединения у меня почему-то MSScriptControl.ScriptControl не запускался...

С благодарностью: http://pajhome.org.uk/crypt/md5/index.html

См. также

Добавить вознаграждение
Комментарии
1. xs19 (Oleg_nsk) 28.03.11 08:02 Сейчас в теме
Ещебы функцию добавить у которой на входе не число а путь к файлу, для которого надо crc8 вычислить, потому что для простого числа считать мало кому надо. И в чем сложность чтобы также crc16 реализовать?
2. xs19 (Oleg_nsk) 28.03.11 08:07 Сейчас в теме
А еще лучше сделать обработку, где можно получать контрольные суммы разными алгоритмами для выбранного файла. Вот тогда бы полноценная публикация была.
3. Александр Рытов (Арчибальд) 2652 28.03.11 09:43 Сейчас в теме
Спасибо за выполнение социального заказа из http://infostart.ru/public/82506/
Самому выполнять доводилось, но вот чтобы мой выполнили... :oops:
4. Al Alware (alware) 20 28.03.11 11:48 Сейчас в теме
Сюда бы еще МД5 SHA1 и т.д.. с интерфейсом для сравнения
5. Ийон Тихий (cool.vlad4) 41 28.03.11 14:46 Сейчас в теме
(0) а там же javascript-ы, в полеhtmlдокумента их и через eval ...и наверное тогда не нужен msscriptcontrol
По приведенной ссылке даже пример есть - по которому можно сделать
Сообщить(ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval("hex_md5(document.getElementById('input').value)"));
Хотя наверное для пакетной обработки без msscriptcontrol не обойтись...
6. Ийон Тихий (cool.vlad4) 41 28.03.11 16:41 Сейчас в теме
В принципе скорость меня удовлетворила...для пакетной обработки, я как самый простой извращенец формиромал строки eval(hex_md5(Строка)...отсутствие ВК это плюс в данном случае.
7. Александр Лукин (i_lo) 168 28.03.11 16:54 Сейчас в теме
(5) C HTML не слишком знаком... Посмотрел ещё раз всё по ссылкам, но примера с eval() так не нашел. Буду признателен за указание :)...
8. Александр Лукин (i_lo) 168 28.03.11 17:04 Сейчас в теме
(1),(2),(4) Использовать CRC8 для файлов считаю неадекватным. Слишком короткая контрольная сумма. Высокая вероятность ошибки. Лучше для файлов брать MD5. По ним, например, сравниваются файлы в ОС. Ну, или CRC32, или SHA-1. Алгоритмы есть по ссылкам. Сделать не сложно :). Если, конечно, это нужно в 1С. В Инете можно найти автономные программки, которые контрольные суммы легко считают... Эта публикация просто пример алгоритма...

CRC8 хорошо использовать, когда нужно добавить контрольные разряды для какого-нибудь "номера накладной", "кода платежа" или "кода карты", который пользователю нужно будет вводить руками. Тогда можно отловить все одиночные и даже больше ошибок ручного ввода...
9. Ийон Тихий (cool.vlad4) 41 28.03.11 17:06 Сейчас в теме
(7) хотелось быстро проверить скрипты по ссылке, там в html коде демонстрация

<h2>Demonstration</h2>

<script src="scripts/md5-min0.js" type="text/javascript"></script>
<script src="scripts/sha1-min.js" type="text/javascript"></script>

<div class="indented">
<table>
<tr><th>Input</th><td><input type="text" id="input" size="40"></td></tr>
<tr><th>Calculate</th>
<td style="text-align:center">
<input type="button" onclick="document.getElementById('hash').value = hex_md5(document.getElementById('input').value)" value="MD5">
<input type="button" onclick="document.getElementById('hash').value = hex_sha1(document.getElementById('input').value)" value="SHA-1"></td></tr>
<tr><th>Result</th><td><input type="text" id="hash" size="40"></td></tr>
</table>

Ну и скрипты в папке scripts/ (это я оперой сохранял)

А дальше в полеhtmlдокумента и как обычно через ЭлементыФормы.ПолеHTMLДокумента1.Документ.parentWindow.eval получаю, что надо. Ведь ПолеHTMLДокумента использует DOM модель html
10. Ийон Тихий (cool.vlad4) 41 28.03.11 17:09 Сейчас в теме
(8) тоже так считаю, кстати повторюсь для контрольной суммы файла можно использовать api-ную ф-цию MapFileAndCheckSum, см. комментарии http://infostart.ru/public/82506/
11. Трактор Трактор (Трактор) 1107 29.03.11 10:28 Сейчас в теме
(4)(5)(7)
alware пишет:
Сюда бы еще МД5 SHA1 и т.д.. с интерфейсом для сравнения
Обработка для расчёта МД5 без внешних компонент в прикреплении. Разработка не моя. Полезна тем что может быть переложена на язык 8.х и исполняться под линуксом, где яваскрипт недоступен.
Прикрепленные файлы:
MD5_ХЭШ.ert
i_lo; cool.vlad4; +2 Ответить 2
12. Ийон Тихий (cool.vlad4) 41 29.03.11 10:35 Сейчас в теме
(11) А я уже собрался сам писать...спс
13. Александр Лукин (i_lo) 168 29.03.11 12:20 Сейчас в теме
(11) :) Это вещь известная http://1c.proclub.ru/modules/mydownloads/personal.php?cid=5&lid=5287
После вопроса об ошибке с запуском msscriptcontrol на партнерском форуме, мне именно её коллеги из Раруса и порекомендовали...
14. Павел (d0dger) 75 29.03.11 15:20 Сейчас в теме
(2) помнится были проблемы в 1С с бинарными файлами при чтении, не все символы читались и результирующий ХЕШ не совпадал с тем, что считалось всякими сторонними утилитами...
15. mozz mozz (mozz) 144 04.04.11 16:28 Сейчас в теме
17. Ийон Тихий (cool.vlad4) 41 04.04.11 16:55 Сейчас в теме
(16) спс за ссылку, но у мня все руки не дойдут (ибо пока не нужно) сделать через api, через cryptoapi ( http://www.rsdn.ru/article/crypto/usingcryptoapi.xml ) благо dynwrapx есть
18. mozz mozz (mozz) 144 05.04.11 09:20 Сейчас в теме
Вот функция которая хэш SHA1 получает (использован vbscript и методы .NET)
Функция SHA1Шифровать(СтрИсх) Экспорт
ScrptCtrl=Новый COMОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language="vbscript";
ТекстСкрипта="
|Function Hash()
|Dim asc, enc, bytes, instr, outstr, pos
|instr = """
+СтрИсх+"""
|Set asc = CreateObject(""System.Text.UTF8Encoding"")
|Set enc = CreateObject(""System.Security.Cryptography.SHA1CryptoServiceProvider"")
|bytes = asc.GetBytes_4(instr)
|bytes = enc.ComputeHash_2((bytes))
|outstr = """"
|For pos = 1 To Lenb(bytes)
| outstr = outstr & LCase(Right(""0"" & Hex(Ascb(Midb(bytes, pos, 1))), 2))
|Next
|Hash = outstr
|End Function
|"
;

ScrptCtrl.AddCode(ТекстСкрипта);
результат = ScrptCtrl.Run("Hash");
Возврат
результат;
КонецФункции
amon_ra; teflon; +2 Ответить 1
19. Ийон Тихий (cool.vlad4) 41 05.04.11 10:39 Сейчас в теме
(18) А зачем Net, когда по ссылке в статье javascript-ы и Sha1, и много чего...http://pajhome.org.uk/crypt/md5/scripts.html...даже wsc там есть...
20. Валентин Елфимов (ratinc) 19.02.12 23:06 Сейчас в теме
Com объектом MSScriptControl.ScriptControl на сервере 2008R2 воспользоватся не удастся в случае если имеем дело с клиентсерверным 1С и сервер 1С 64 бит
21. Александр Лукин (i_lo) 168 20.02.12 00:39 Сейчас в теме
(20) ratinc, Об этом в конце статьи и говорится. И на партнерском форуме http://partners.v8.1c.ru/forum/thread.jsp?id=834807#834807 все обсуждение осталось без четкого решения...
Дело было давно, но насколько я помню, у меня не заработал вызов именно в варианте обработчика для web-сервиса. А в случае интерактивной работы он выполнялся. Тогда там ещё 8.1 была...
22. Валентин Елфимов (ratinc) 20.02.12 01:39 Сейчас в теме
(21) i_lo, решение есть. Пока оно четко не оформилось но работать будет однозначно. С подачи этой статьи http://wiki.kint.ru/index.php/Использование_средств_шифрования_.Net_из_1С и вытекающей из неё http://msdn.microsoft.com/ru-ru/library/system.security.cryptography.aspx попробовал использовать ком объект "System.Security.Cryptography.MD5CryptoServiceProvider". Осталось адаптировать код VBS под себя и будут у меня хеши.
23. Александр Лукин (i_lo) 168 20.02.12 02:22 Сейчас в теме
(22) ratinc, согласен, можно пробовать. Хотя шанс нарваться на server core ненулевой. Там не поддерживается .net...
24. Валентин Елфимов (ratinc) 20.02.12 02:45 Сейчас в теме
(23) i_lo, будем решать проблемы по мере поступления. Сам люблю вариант с CORE. Правда у меня на них не 1С. Есть ещё вариант у MSSQL хеш запросить.