Шифруем файл с помощью пароля (исходники)Источник: programmersclub Руслан Аблязов
Здравствуйте, уважаемые delphi'сты и не только. Сегодня я вам расскажу, как можно зашифровать файл с помощью пароля. Я напишу 2 функции, которые всё это делают (разумеется, одна функция будет зашифровывать, а другая расшифровывать) и засуну их в отдельный модуль, чтобы ими было проще пользоваться. Итак, приступим.
Согласно этому алгоритму не трудно понять, каким будет алгоритм расшифровки. Он будет точно таким же только с тем отличием, что вместо некоторой функции cript будет применяться функция ей обратная. Поясню данный алгоритм на таблице, допустим, что пароль будет равен "qwerty", схема шифровки будет такая (напомню, что функция ord возвращает цифровой код буквы в кодировке ANSI):
Для лучшего понимания, в таблице я не буду указывать цифровые коды букв пароля, я просто укажу сами буквы. Разумеется, под буквами понимается их цифровой код.
С алгоритмом вроде разобрались, теперь надо подумать о функции, которая будет шифровать байт с помощью приращения. Самый простой способ это ксорить xn и dx. Вот так: xk:=xn xor dx; Этот способ примечателен тем, что для него не нужно создавать способа дешифровки, потому что декриптор ксора - это тот же ксор. xk:=xn xor dx; После всех этих манипуляций xdk будет равно xn. Следовательно, для расшифровки нам не надо создавать декриптор. Шифровать с помощью ксора примитивно и просто. Есть более лучший метод. Можно просто к начальному значению байта прибавлять значение dx, а при расшифровке вычитать. По-моему этот метод лучше и оригинальнее. НО здесь тоже есть загвоздка. Проблема в том, что максимальное значение байта 28 это 256, но у нас есть ещё и ноль, значит диапазон значений байта [0..255]. Следовательно, если начальное значение байта было равно 245, а приращение равно 45, и если их сложить то получается 290, и присваивании такого значения переменной размером с байт, произойдёт переполнение и просто-напросто ей присвоится 0. Есть выход: можно просто брать остаток от 256. При расшифровке смотреть если dx больше чем xn, то просто сначала из xn вычесть dx, а потом прибавить 256. Вот эти 2 функции: function plus(xn,dx:byte):byte; function minus(xn,dx:byte):byte; Вот и у нас есть криптор и декриптор. Теперь приступим к написанию самих функции шифровки и расшифровки. Сначала напишем криптор. Function CriptFile( ACF_AutoRename :=(Flags and CF_AutoRename) = CF_AutoRename; Обрабатывает флаги которые мы приняли и потом их обрабатываем. Константы CF_* и переменные ACF_* опишу позже. if ACF_AutoRename then Здесь я поясню подробнее. Константа CF_Dest_NOT_CREATE говорит функции, что шифровать надо в искомый файл, то есть искомый файл, и файл назначение совпадают. Но промежуточный файл нужен в любом случае, поэтому мы его создаём на диске С:, потом мы заменим искомый файл этим промежуточным, и промежуточный потом удалим. all_mass:=0;//эта переменная нужна для прогресса Дальше идёт алгоритм отличный от того, который я указывал в начале, но он выполняет тоже самое только быстрее. Он быстрее, потому что он не вычисляет номер буквы, которую надо брать из пароля, она берётся сама по себе, согласно номеру повтора во внутреннем цикле. for i:=1 to (FSize div kl)+1 do CloseHandle(SourceHFile); Вот константы, которые я использовал в этой функции (изменять их нерекомендуется): const implementation uses …………; var Функции. DeCriptFile я не буду описывать, потому что она точно такая же, всего лишь за двумя отличиями: if ACF_AutoRename then и разумеется: Кстати о флагах. Их можно комбинировать с помощью оператора or. procedure TForm1.Button1Click(Sender: TObject); procedure TForm1.Button2Click(Sender: TObject); Короче всё смотрите в исходниках. Там всё есть. Копируете этот модель в расшаренную для дельфи папку, добавляете в выражение uses модуль FileCript и пользуетесь им на здоровье.
|