Шифрование в DELPHI

Шифрование в DELPHI
Данные надо беречь. Сам посуди, обидно, если открытие ценой в сто миллионов енотов или рецепт безалкогольной водки, над которым ты корпел три вечера в мрачном подвале нелегального компьютерного клуба, уплывет к злостному ленивому конкуренту, который, пользуясь твоим похмельем, наложил грязную лапу на приватные дискеты с ценнейшей инфой?! Дальше можно не продолжать. Шифруем, шифруем, шифруем!..
Добрый дядюшка borland предоставил нам несколько занятных функций для работы со строками, о которых не все знают. Сосредоточены они в модуле strutils.pas. 
Такие функции, как RightStr(), LeftStr() совмещают стандартные команды Copy() и Delete(): так, LeftStr() возвращает значение левой части строки до указанной вами позиции (что вытворяет RightStr(), догадайся сам), а функция ReverseString() и вовсе делает зеркальное отображение данной строки: 321 вместо 123. Используем ее в особенности, чтобы осложнить жизнь хитрому дешифровщику.
Алгоритм шифрования будет прост, как win 3.1. С каждым символом кодируемого документа проделаем следующее:
:1. Преобразуем символ в число командой Ord.
:2. Преобразуем каждый символ пользовательского пароля в число и сумму этих чисел прибавим к полученному в пункте 1.
:3. От результата отнимаем число, равное позиции данного символа. То есть буковки будут шифроваться по-разному в зависимости от их позиции в строке :).
:4. То, что получилось, запишем обратно из чисел в символы командой Chr. Как видишь, после всех наших манипуляций этот символ уже будет другим.
:5. Запишем всю строку навыворот командой ReverseString.
Дешифровка, как ты догадываешься, будет производиться в обратном порядке.
Теперь, когда алгоритм намертво засел в голове, реализуем соответствующую программу. 
Внимание! Не исключено, что это будет первая твоя программа с настоящим синтаксисом команд:
 <команда> <путь> <пароль>
- так будет выглядеть он в консоли нашего приложения (да, оно будет консольным!). Команд всего две: crypt и decrypt соответственно зашифровать и дешифровать файл, путь к которому указывается после пробела, а затем - твой пароль. НЕ ЗАБУДЬ ЕГО! Предупреждаю совершенно серьезно. Запомнил? В бой!
 crypt c:\file.txt linuxmustsurvive
- закодируем file.txt. 
Результат (зашифрованный текст) сохраниться в той же директории, что и исполняемый файл нашего приложения под именем translated_file.txt.
 decrypt c:\translated_file.txt linuxmustsurvive
- дешифровка.
Реализовывается это вот как:
program crypter;
{$apptype console}
uses
 sysutils,
 strutils; //!!
var
 f, // входящий файл
 f1: TextFile; // результат (файл с переводом)
 todo, Filename, passw, line, TranslatedFile: string;
 Position, IsCrypt: Integer;
// находим сумму числовых значений символов пароля
function Password(psw: string): Integer;
var
 i: Integer;
begin
 Result := 0;
 for i:=1 to Length(psw) do
 Result := Result + Ord(psw[i]);
end;
function Crypt(CryptStr: string): string;
var
 s: string;
 i: Integer;
begin
 Result := ;
 if CryptStr = EmptyStr then Exit;
 for i := 1 to Length(CryptStr) do
 begin
 s := LeftStr(CryptStr, 1);
 CryptStr := RightStr(CryptStr, Length(CryptStr)-1);
 // ШИФРОВКА:
 s := Chr(Ord(s[1]) + Password(passw)-i);
 Result := Result + s;
 end;
 Result := ReverseString(Result);
end;
function Decrypt(DecryptStr: string): string;
var
 i: Integer;
 s: string;
begin
 Result := ;
 DecryptStr := ReverseString(DecryptStr);
 if DecryptStr = EmptyStr then Exit;
 for i := 1 to Length(DecryptStr) do
 begin
 s := LeftStr(DecryptStr, 1);
 DecryptStr := RightStr(DecryptStr, Length(DecryptStr)-1);
 // ДЕШИФРОВКА:
 Result := Result + Chr(Ord(s[1]) - Password(passw)+i);
 end;
end;
begin
 while True do
 begin
 IsCrypt := 0;
 WriteLn(#10 + 'crypter >' + #10);
 // Какую команду ввел юзер?
 ReadLn(todo);
 if LowerCase(todo) = 'exit' then exit;
 if AnsiContainsText(todo, 'decrypt') then
 IsCrypt := 1
 else if AnsiContainsText(todo, 'crypt') then
 IsCrypt := 2;
 // прочитав команду, удаляем ее из строки и читаем дальше
 Position := Pos(' ', todo);
 if Position > 0 then
 todo := RightStr(todo, Length(todo) - Position);
 // Читаем путь к файлу
 Position := Pos(' ', todo);
 if Position > 0 then
 FileName := LeftStr(todo, Position-1);
 // Читаем пароль
 passw := RightStr(todo, Length(todo) - Position);
 // Всё правильно? Начинаем!
 if (IsCrypt <= 0) or (passw = EmptyStr)
 or (not FileExists(FileName)) then
 WriteLn('wrong command')
 else
 begin
 TranslatedFile := ExtractFilePath(ParamStr(0)) +
 'translated_' + ExtractFileName(FileName);
 // соединяемся с файлами
 AssignFile(f, FileName);
 AssignFile(f1, TranslatedFile);
 // переходим в начало файла
 Rewrite(f1);
 Reset(f);
 // читаем строки, пока не дойдем до конца файла
 while not Eof(f) do
 begin
 // читаем из переводимого файла
 ReadLn(f, line);
 if IsCrypt = 1 then line := Decrypt(line);
 if IsCrypt = 2 then line := Crypt(line);
 // записываем в файл с переводом
 WriteLn(f1, line);
 end;
 // отсоединяемся от файлов
 CloseFile(f);
 CloseFile(f1);
 end;
 end;
end.
Вот, собственно, и всё. Еще раз напоминаю, что результат (файл с переводом) сохранится В ТОЙ ЖЕ ДИРЕКТОРИИ, что и наше приложение, а не в той, где лежит исходный файл. В заключение процитирую отрывок из статьи «Криптография в c++» в номере 3.03 журнала «Хакер»:
//(с) Николай «gorlum» Андреев
Но я хочу тебя предупредить: в нашей стране, согласно указу № 334 от 1995 года, производить и распространять любые шифрующие средства можно, только имея лицензию ФАПСИ. Соответственно, шифровать нельзя :). Поэтому пиши программы только для личного пользования и только в познавательных целях.
Author: Трофим Роцкий
ID: 03983
Category:Алгоритмы
Category:Шифрование