Шифруйся сам! Alek Silverstone Xakep, номер #065, стр. 065-110-2 Хешируемся! Теперь рассмотрим хеш-функцию MD5. Разработана она все тем же Роном Ривестом. Ты не подумай, я не его фанат - просто в мире криптографии он один из самых авторитетных людей. Причины выбора этого алгоритма - простота (относительная, тут придется многое объяснять словами - но остальные еще сложнее :)), высокая скорость, малая вероятность коллизий. Кроме того, MD5 входит во многие стандарты и протоколы, например POP3 (RFC-1939,2095), SMTP (RFC-2554) и S/MIME (RFC2632-2634), так что можешь юзать этот код для написания почтового клиента. Здесь нам понадобятся 4 глобальные переменные md5a, md5b, md5c и md5d типа Longword. Также нужно объявить один тип: type TArr16xLongword=array [0..15] of Longword; Сначала текст дополняется так, чтобы его длина была на 64 бита короче числа, кратного 512 (если длина уже такая, то добавлять все равно нужно). Этим дополнением является бит 1, за которым следует нужное количество нулей. Затем к результату добавляется 64-битовая длина текста в битах. В том маловероятном (очень маловероятном) случае, если длина текста превышает 18446744073709551616 бит (2^64), берутся младшие 64 бита представления. Я специально не пишу здесь кода - в зависимости от места хранения информации он будут разный. Написать его самому несложно, вариант для файла смотри в примере. Теперь надо заполнить 4 глобальные переменные начальными значениями: procedure MD5Init; begin md5a:=$67452301; md5b:=$efcdab89; md5c:=$98badcfe; md5d:=$10325476; end; Это необходимо делать перед каждым новым текстом. Теперь основной цикл, он выполняется, пока не исчерпаются 512-битовые блоки сообщения. Сначала объясню на словах. Блоки разбиваются на 16 подблоков. Цикл состоит из 4 этапов. Каждый этап - из 16 операций. Общий вид операции: Что получилось XX(a, b, c, d, m, s, t) XX - название операции a, b, c, d - переменные md5a, md5b, md5c и md5d m - 32-битный подблок текста s - количество бит, на которое циклически влево сдвигается результат t - константа для суммирования Результат заносится в a. Здесь есть две небольшие трудности. Первая: сдвиг битов циклический, поэтому простой shl использовать нельзя. Есть два способа. Первый - писать вот так: function ROL(c:Longword;n:byte):Longword; begin Result:= (c shl n) or (c shr (32-n)); end; Но это, ИМХО, некрасиво. Второй способ - воспользоваться assembler'ом. Я его не знаю, поэтому обратился за помощью к другу. Ответ его состоял из одного слова: rol. Сначала я подумал, что он имеет в виду Россию-он-лайн :), но оказалось, что это команда asm'а, как раз и делающая циклический сдвиг влево. Итак, пишем: |