Шифруйся сам! Alek Silverstone Xakep, номер #065, стр. 065-110-3 Циклический сдвиг влево function ROL(c:Longword;n:byte):Longword;assembler; asm mov eax,c mov cl,n rol eax,cl end; Эта функция сдвигает 32-битовое слово c на n бит влево. Вторая проблема - константы. Таблицу констант сначала надо заполнить. В t[i] (i от 1 до 64) заносится целая часть от 2^32*|sin(i)|, где i измеряется в радианах: for i:=1 to 64 do t[i]:=trunc(4294967296*abs(sin(i))); Собственно операции приведены на врезке. Основной цикл MD5 (я назвал его MD5Do) занимает очень много места, и нет смысла приводить его здесь. Его код вместе с комментариями есть на диске. Но тут надо сделать одно важное замечание. MD5Do нужно компилить с выключенным Overflow checking (зайти в Project -> Options на вкладку Compiler и снять одноименную галку или в начале кода написать директиву компилятора {$Q-}). Если этого не сделать, то при стандартных настройках после нескольких циклов прога будет вылетать из-за переполнения в последних процедурах inc. И еще, по поводу констант. Вводить их ручками сложно (можно сойти с ума), очень легко ошибиться и очень трудно потом эту ошибку найти. Поэтому я написал небольшую программку, которая подсчитывает эти константы и выводит их (я не подсчитываю их непосредственно перед вызовом хеш-функции из-за соображений скорости). Остается только скопировать их. Теперь последний штрих. Последняя процедура возвращает значения md5a, md5b, md5c и md5d. procedure MD5Finalize(var a, b, c, d:Longword); begin a:=md5a; b:=md5b; c:=md5c; d:=md5d; end; Эта процедура возвращает в параметрах a, b, c, d четыре части результата. По стандарту MD5 возвращает значение, начиная с младшего байта a и заканчивая старшим байтом d, в шестнадцатеричном виде. С этим связана еще одна проблема (последняя на сегодня ;)) - функция IntToHex. Мне так и не удалось понять, как она работает (она на asm'е), могу лишь предположить, что проблема в порядке битов. Факт в том, что у меня вместо, например, "12345678" получалось "78563412". Поэтому пришлось писать вот такой изврат: Перемены значений function IntToHexFix(a:LongWord):string; var b,r:string[8]; begin b:=IntToHex(a,8); SetLength(r,8); r[7]:=b[1]; r[8]:=b[2]; r[5]:=b[3]; r[6]:=b[4]; r[3]:=b[5]; r[4]:=b[6]; r[1]:=b[7]; r[2]:=b[8]; Result:=r; end; Тестируем Теперь напишем небольшую программку для того, чтобы проверить наш код. Сразу оговорюсь, что сейчас мы будем тестировать только RC4 - MD5 потребовал бы слишком много места в журнале. Но не волнуйся, на диске есть все ;). Кинем на форму (Form1) кнопку (назовем ее RC4Btn), поле ввода (KeyEdit) и диалог выбора файла (OpenDialog). В последнем не забудем задать фильтр *.* (свойство Filter). Напишем такой обработчик щелчка по RC4Btn: Обрабатываем клик procedure TForm1.RC4BtnClick(Sender: TObject); var //файлы для чтения и записи информации InFile, OutFile :file of byte; t:byte; //байт для шифрования begin if OpenDialog.Execute and (KeyEdit.Text<>'') and (OpenDialog.Filename<>'') then begin // если файл выбран и ключ введен, то... |