Криптографические алгоритмы
В данной статье представлено несколько алгоритмов шифрования данных.
Каждый блок является самодостаточной программой, написанной на языке
программирования Borlabd Pascal 7.0
Опытному программисту не составит труда перевести алгоритмы на другой язык
программирования, например на C++ или Java.
- Программное моделирование шифрующей машины "Энигма". стр 141 - 144 книги В.Жельникова "Криптография"
- Алгоритм замены биграммами, модификация PlayFair. Описание: книга В. Жельникова "Криптография" стр 62-63. Этот алгоритм применялся Великобританией в Первую мировую войну
- Шифрование 'взбиванием', стр 138 - 139 книги В.Жельникова "Криптография"
- Шифрование тасовкой (стр 134 - 135 книги В.Жельникова "Криптография")
- Кодирование простой заменой
- Некий аналог RSA-КОДИРОВАНИЯ
program Enigma;
{ Программное моделирование шифрующей машины "Энигма" }
{ стр 141 - 144 книги В.Жельникова "Криптография" }
uses Crt;
const
Password = 231;
ns = 4;
ss: string =
' Когда программисты-фанатики собираются в своем кругу для об' +
'суждения тайн структурного программирования ';
var i, j, k, m, n: integer;
st: string;
x: integer;
s: array[0..ns, 0..32] of char;
t: char;
begin
ClrScr;
RandSeed:= Password;
Writeln(ss);
Writeln;
for i:= 0 to ns do begin
for j:= 0 to 32 do s[i, j]:= Chr(j);
for j:= 0 to 32 do begin
t:= s[i, j];
k:= Random(33);
s[i, j]:= s[i, k];
s[i, k]:= t;
end;
end;
st:= '';
for i:= 1 to Length(ss) do begin { Шифрование }
k:= Ord(ss[i]);
if k > 32 then dec(k, 128);
for j:= 0 to ns do
k:= Ord(s[j, k]);
if k < 32 then inc(k, 128);
Write(Chr(k));
st:= st + Chr(k);
k:= Random(ns); { Поворот колес }
for j:= 0 to 31 do begin
t:= s[k, j];
s[k, j]:= s[k, j + 1];
s[k, j + 1]:= t;
end;
for j:= 0 to 32 do
s[k, j]:= Chr((Ord(s[k, j]) + 32) mod 33);
end;
Writeln;
Writeln;
RandSeed:= Password;
for i:= 0 to ns do begin
for j:= 0 to 32 do
s[i, j]:= Chr(j);
for j:= 0 to 32 do begin
t:= s[i, j];
k:= Random(33);
s[i, j]:= s[i, k];
s[i, k]:= t;
end;
for j:= 0 to 32 do begin
if Ord(s[i, j]) < 64 then begin
m:= j;
n:= Ord(s[i, j]);
repeat
k:= Ord(s[i, n]);
s[i, n]:= Chr(m or 64);
m:= n;
n:= k;
until m = j;
end;
end;
for j:= 0 to 32 do
s[i, j]:= Chr(Ord(s[i, j]) and 63);
end;
ss:= st;
for i:= 1 to Length(ss) do begin
k:= Ord(ss[i]);
if k > 32 then dec(k, 128);
for j:= ns downto 0 do
k:= Ord(s[j, k]);
if k < 32 then inc(k, 32);
Write(Chr(k));
k:= Random(ns); { Поворот колес }
for j:= 0 to 31 do begin
t:= s[k, j];
s[k, j]:= s[k, j + 1];
s[k, j + 1]:= t;
end;
for j:= 0 to 32 do
s[k, j]:= Chr((Ord(s[k, j]) + 32) mod 33);
end;
Writeln;
end.
program PlayFair;
{ Алгоритм замены биграммами, модификация PlayFair }
{ Описание: книга В. Жельникова "Криптография" стр 62-63 }
{ Этот алгоритм применялся Великобританией в Первую мировую войну }
uses Dos, Crt;
type TMatrix = array[1..16, 1..16] of Char;
const
Banner = 'Реализация алгоритма шифрования PlayFair';
const InFileName: string = ''; { Имя входного файла }
OutFileName: string = ''; { Имя выходного файла }
Phase: (None, Code, Decode) = None; { Режим работы }
{ True если файл с именем Name существует, False если нет }
function Exists(Name: string): boolean;
var F: file;
Attr: word;
begin
Assign(F, Name);
GetFAttr(F, Attr);
Exists:= DosError = 0;
end;
function AskToDelete(Name: string): boolean;
var ch: char;
begin
while KeyPressed do ch:= ReadKey; { Чистим буфер }
Write('Файл с именем ', Name, ' уже существует. Перезаписать ? [Y/N]: ');
repeat
ch:= ReadKey;
until UpCase(ch) in ['Y', 'N'];
Writeln(ch);
AskToDelete:= UpCase(ch) = 'Y';
end;
{ Получение от пользователя имени входного файла. }
function AskInName(var Name: string): boolean;
var Flag: boolean;
begin
repeat
Writeln('Введите имя входного файла, или Enter для выхода');
Write('Имя файла: '); Readln(Name);
Flag:= Name = '';
if not Flag then
if Exists(Name) then Flag:= true
else Writeln('Файл с именем ', Name, ' не найден !');
until Flag;
AskInName:= Name <> '';
end;
{ Получение от пользователя имени выходного файла. }
function AskOutName(var Name: string): boolean;
var Flag: boolean;
begin
repeat
Writeln('Введите имя выходного файла или Enter для выхода');
Write('Имя файла: '); Readln(Name);
Flag:= Name = '';
if not Flag then
if not Exists(Name) then Flag:= true
else Flag:= AskToDelete(Name);
until Flag;
AskOutName:= Name <> '';
end;
{ Спрашивает режим работы программы }
function AskPhase: boolean;
var ch: char;
begin
while KeyPressed do ch:= ReadKey;
Writeln('Что вы хотите сделать с этим файлом ?');
Write('[C - зашифровать, D - расшифровать, Q - выйти]: ');
repeat
ch:= UpCase(ReadKey);
until ch in ['C', 'D', 'Q'];
Writeln(ch);
case ch of
'C': Phase:= Code;
'D': Phase:= Decode;
end;
AskPhase:= ch <> 'Q';
end;
{ Выдает небольшую справку по ключам программы и выйти }
procedure GiveHelp;
begin
Writeln;
Writeln('Программа используется следующим образом:');
Writeln('playfair [InFileName OutFileName] [-c|-d]');
Writeln('InFileName - имя исходного файла');
Writeln('OutFileName - имя результирующего файла');
Writeln('-c - шифрование');
Writeln('-d - расшифрование');
Writeln('-? - выдать это сообщение');
Halt(0);
end;
{ Проверяет данные и спрашивает недостающие }
function VerifyData: boolean;
var Res: boolean;
begin
Res:= true;
if (InFileName <> '') then begin
if not Exists(InFileName) then begin
Writeln('Файл с именем ', InFileName, ' не найден !');
Res:= AskInName(InFileName);
end
end
else Res:= AskInName(InFileName);
if Res then
if (OutFileName <> '') then begin
if Exists(OutFileName) and not AskToDelete(OutFileName) then
Res:= AskOutName(OutFileName);
end
else Res:= AskOutName(OutFileName);
if Res and (Phase = None) then Res:= AskPhase;
VerifyData:= Res;
end;
{ Получение данных из коммандной строки }
function GetStartData: boolean;
var Res: boolean; { Результат выполнения функции }
Params: string;
i, SlashPos: byte;
begin
if ParamCount = 0 then Res:= AskInName(InFileName)
else begin
Res:= false;
i:= 1;
Params:= '';
while i <= ParamCount do begin
Params:= Params + '|' + ParamStr(i);
inc(i);
end;
if Pos('?', Params) <> 0 then GiveHelp
else begin
SlashPos:= Pos('-', Params);
if SlashPos = 0 then SlashPos:= Pos('/', Params);
if SlashPos = 0 then begin
InFileName:= ParamStr(1);
OutFileName:= ParamStr(2);
end
else begin
case UpCase(Params[SlashPos + 1]) of
'C': Phase:= Code;
'D': Phase:= Decode;
else GiveHelp;
end;
if Pos('|', Params) < SlashPos then begin
InFileName:= ParamStr(1);
OutFileName:= ParamStr(2);
end;
end;
end;
Res:= VerifyData;
end;
GetStartData:= Res;
end;
function AskLoop: string;
var S: string;
Flag: boolean;
ch: Char;
begin
S:= '';
Flag:= false;
repeat
if KeyPressed then begin
ch:= ReadKey;
case ch of
#0: ch:= ReadKey;
#13: Flag:= true;
#8: if Length(S) > 0 then begin
Dec(S[0]);
Write(#8#32#8);
end;
#32..#255:
begin
S:= S + ch;
Write('*');
end;
end;
end;
until Flag;
Writeln;
AskLoop:= S;
end;
function AskPassword(var Password: string): boolean;
begin
Password:= '';
Write('Введите пароль: ');
Password:= AskLoop;
if Password = '' then Writeln('Пароль пуст ! Файл не зашифрован.');
AskPassword:= Password <> '';
end;
function ReAskPassword(Password: string): boolean;
var S: string;
begin
Write('Введите пароль снова: ');
S:= AskLoop;
if S <> Password then Writeln('Пароли не совпадают !');
ReAskPassword:= S = Password;
end;
procedure MakeMatrix(var Matrix: TMatrix; var Password: string);
var i, j, Pos: byte;
ch: char;
Used: array[#1..#255] of boolean;
begin
for ch:= #1 to #255 do Used[ch]:= false;
Pos:= 1;
for i:= 1 to 16 do begin
for j:= 1 to 16 do begin
while (Pos <= Length(Password)) and Used[Password[Pos]] do inc(Pos);
if Pos <= Length(Password) then begin
Used[Password[Pos]]:= true;
Matrix[i, j]:= Password[Pos];
inc(Pos);
end
else begin
ch:= #1;
while (Used[ch]) and (ch < #255) do inc(ch);
if not Used[ch] then begin
Matrix[i, j]:= ch;
Used[ch]:= true;
end;
end;
end;
end;
end;
procedure FindChar(ch: char; var Matrix: TMatrix; var i, j: byte);
var Flag: boolean;
k, m: byte;
begin
Flag:= false;
for k:= 1 to 16 do begin
for m:= 1 to 16 do begin
Flag:= Matrix[k, m] = ch;
if Flag then Break;
end;
if Flag then Break;
end;
i:= k;
j:= m;
end;
procedure CodeBigramm(var c1, c2: char; var Matrix: TMatrix);
var i, j: byte;
k, m: byte;
begin
FindChar(c1, Matrix, i, j);
FindChar(c2, Matrix, k, m);
if i = k then begin
if Phase = Code then begin
if j = 16 then j:= 1
else inc(j);
if m = 16 then m:= 1
else inc(m);
end
else begin
if j = 1 then j:= 16
else dec(j);
if m = 1 then m:= 16
else dec(m);
end;
c1:= Matrix[i, j];
c2:= Matrix[k, m];
end
else if j = m then begin
if Phase = Code then begin
if i = 16 then i:= 1
else inc(i);
if k = 16 then k:= 1
else inc(k);
end
else begin
if i = 1 then i:= 16
else dec(i);
if k = 1 then k:= 16
else dec(k);
end;
c1:= Matrix[i, j];
c2:= Matrix[k, m];
end
else begin
c1:= Matrix[i, m];
c2:= Matrix[k, j];
end;
end;
procedure CodeBlock(Size: word; var Buffer: array of char;
var Matrix: TMatrix);
var i: word;
begin
i:= 0;
while i <= Size do begin
CodeBigramm(Buffer[i], Buffer[i + 1], Matrix);
inc(i, 2);
end;
end;
procedure ProceedFile(var Matrix: TMatrix);
var InFile, OutFile: file;
Buffer: array[0..1024] of char;
Got: word;
begin
Assign(InFile, InFileName);
Assign(OutFile, OutFileName);
Reset(InFile, 1);
Rewrite(OutFile, 1);
repeat
BlockRead(InFile, Buffer, High(Buffer), Got);
CodeBlock(Got, Buffer, Matrix);
BlockWrite(OutFile, Buffer, Got, Got)
until Got < High(Buffer);
Close(InFile);
Close(OutFile);
end;
var Matrix: TMatrix;
Password: string;
begin
Writeln(Banner);
if GetStartData then { Разбор ключей, и заполнение данных }
if AskPassword(Password) and
((Phase <> Code) or ReAskPassword(Password)) then
begin
MakeMatrix(Matrix, Password);
ProceedFile(Matrix);
end;
end.
program Scramble;
{ Шифрование 'взбиванием',
стр 138 - 139 книги В.Жельникова "Криптография" }
uses Crt;
const Password = 231;
Count = 6; { Количество перемешиваний (Count <= 6) }
var i, j, l, kg, kl, kr: byte;
Key, ss, Sav, sc, sl, sr: string;
begin
RandSeed:= Password;
ClrScr;
ss:= '';
for i:= 1 to 64 do
ss:= ss + Chr(65 + Random(25));
Writeln(ss, ' - Text');
Sav:= ss;
Key:= '';
for i:= 1 to 32 * Count do
Key:= Key + Chr(Random(255));
{--------------- Шифрование --------------}
for i:= 0 to Count - 1 do begin
sc:= Copy(Key, i shl 5 + 1, 32);
l:= 1 shl i;
sl:= '';
sr:= '';
for j:= 1 to 32 do begin
kg:= Ord(sc[j]);
kl:= Ord(ss[j]);
kr:= Ord(ss[j + 32]);
sl:= sl + Chr(kl xor kr);
sr:= sr + Chr(kr xor kg);
end;
ss:= sr + Copy(sl, l, 255) + Copy(sl, 1, l - 1); { Перестановка }
end;
{-------------- Порча бита --------------}
ss[1]:= Chr(Ord(ss[1]) xor 4);
{-------------- Вывод на экран --------------}
for i:= 1 to 64 do begin
j:= Ord(ss[i]);
Mem[$B80A:(2 * i - 2)]:= j;
end;
GotoXY(65, 2);
Writeln(' - Code');
{-------------- Расшифровывание --------------}
for i:= Count - 1 downto 0 do begin
sc:= Copy(Key, i shl 5 + 1, 32);
l:= 1 shl i;
{ Обратная перестановка }
ss:= Copy(ss, 66 - l, 255) + Copy(ss, 33, 33 - l) + Copy(ss, 1, 32);
sl:= '';
sr:= '';
for j:= 1 to 32 do begin
kg:= Ord(sc[j]);
kl:= Ord(ss[j]);
kr:= Ord(ss[j + 32]);
sl:= sl + Chr(kl xor (kr xor kg));
sr:= sr + Chr(kr xor kg);
end;
ss:= sl + sr;
end;
{-------------- Вывод на экран --------------}
for i:= 1 to 64 do begin
j:= Ord(ss[i]);
Mem[$B814:(2 * i - 2)]:= j;
end;
GotoXY(65, 3);
Writeln(' - Text');
j:= 0;
for i:= 1 to 64 do
if ss[i] = sav[i] then Write('+')
else begin
Write('-');
inc(j);
end;
Writeln;
Writeln(j, ' errors');
end.
program Shuffle;
{ Шифрование тасовкой (стр 134 - 135 книги В.Жельникова "Криптография") }
uses Crt;
const Password = 13;
S: string = 'Вверху синева и внизу откос';
var L, i: byte;
ss: string;
m, n, t: byte;
Beg, Mid, Fin: string;
begin
ClrScr;
RandSeed:= Password; { Установка пароля }
L:= Length(S);
Writeln(s); { Вывод исходной строки }
Writeln;
ss:= ''; { Строка - шифратор, в ней }
for i:= 1 to L shl 1 do { каждые 2 символа определяют }
ss:= ss + Chr(Random(L div 2)); { размер блока с конца и с начала }
{ Шифровка }
i:= 2;
while i <= Length(ss) do begin
n:= Ord(ss[i - 1]); { Длина первого блока }
m:= Ord(ss[i]); { Длина второго блока }
Beg:= Copy(s, 1, n); { Первый блок }
Mid:= Copy(s, n + 1, l - m - n); { Серединка }
Fin:= Copy(s, l - m + 1, 255); { Второй блок }
s:= Fin + Mid + Beg; { Перетасовываем... }
inc(i, 2);
end;
Writeln(s);
Writeln;
{ Расшифровка } { При расшифровке все }
i:= Length(SS); { производится с }
while i >= 1 do begin { точностью до наоборот }
n:= Ord(SS[i - 1]);
m:= Ord(SS[i]);
Beg:= Copy(s, 1, m);
Mid:= Copy(s, m + 1, l - m - n);
Fin:= Copy(s, l - n + 1, 255);
s:= Fin + Mid + Beg;
dec(i, 2);
end;
Writeln(S);
end.
program XorCodeing; { Кодирование простой заменой }
const Password = 983100;
const Mess: string = 'Жили были старик со старухой.';
procedure CodeMess(var Mess: string);
var i: Word;
begin
RandSeed:= Password;
for i:= 1 to Length(Mess) do
Mess[i]:= Char(Random(40) xor Byte(Mess[i]));
Writeln(Mess);
end;
begin
Writeln(Mess);
CodeMess(Mess);
CodeMess(Mess);
end.
program rsa; {Некий аналог RSA-КОДИРОВАНИЯ}
uses
Crt;
var
code,
l : Integer;
onebyte : Byte;
oneword : Word;
s,
KeyFileName,
OFileName,
IFileName : String;
n,m,
d,e,
p, q : Word;
WordFile : File of Word;
ByteFile : File of Byte;
KeyFile : Text;
{Функция преобразования}
function G(x,e,n : Word) : Word;
var
i,
k,
t : Word;
begin
k:=x;
t:=x mod n;
for i:=2 to e do
t:=Word((Longint(t)*Longint(k)) mod Longint(n));
G:=t;
end;{G}
{Проверить яв-ся ли число простым}
function IsSimple(x : Word) : boolean;
var
c : LongInt;
f : boolean;
begin
c:=3;
f:=True;
f:= (x mod 2) <> 0;
f:=f and (G(x-2, x-1, x) = 1);
While f and (c < x) do
begin
f:=(x mod c) <> 0;
c:=c+2;
end;
isSimple:=f;
end;{IsSimple}
{Сформировать коэффициенты p и q}
procedure MakeValue(Var p, q : Word);
begin
Randomize;
p:=Random(255);
if p < (255/2+1)
then
p:=255-p;
while Not IsSimple(p) do
begin
p:=Random(255);
if p < (255/2+1)
then
p:=255-p;
end;
q:=Random(255);
if q < (255/2+1)
then
q:=255-q;
while Not IsSimple(q) do
begin
q:=Random(255);
if q < (255/2+1)
then
q:=255-q;
end;
if p = q
then
MakeValue(p, q);
end;{MakeValue}
{Создать ключи}
procedure MakeKey(Var d,e : Word);
var
k : LongInt;
begin
MakeValue(p,q);
repeat
n:=p*q;
m:=(p-1)*(q-1);
e:=1;
while (m mod e =0) and (e1)
and (dn;
end;
begin
repeat
ClrScr;
WriteLn('1 - Шифровать файл...');
WriteLn('2 - Расшифровать...');
WriteLn('0 - Выход');
ReadLn(l);
case l of
1:{Шифровать}
begin
ClrScr;
WriteLn('Имя исходного файла: ');
ReadLn(IFileName);
WriteLn('Имя зашифрованного файла: ');
ReadLn(OFileName);
WriteLn('Имя файла для ключей: ');
ReadLn(KeyFileName);
MakeKey(d, e);
WriteLn('p=',p,' q=',q);
WriteLn('n=',n,' m=',m);
WriteLn('d=',d,' e=',e);
{Записать ключи в файл}
Assign(KeyFile, KeyFileName);
Rewrite(KeyFile);
Str(d,s);
WriteLn(KeyFile, s);
Str(n,s);
WriteLn(KeyFile, s);
Close(KeyFile);
{Зашифровать файл}
Assign(ByteFile, IFileName);
Assign(WordFile, OFileName);
Rewrite(WordFile);
Reset(ByteFile);
while Not EOF(ByteFile) do
begin
Read(ByteFile, onebyte);
oneword:=G(Word(onebyte), e, n);
Write(WordFile, oneword);
end;{while}
Close(ByteFile);
Close(WordFile);
end;
2:{Расшифровать}
begin
ClrScr;
WriteLn('Имя зашифрованного файла: ');
ReadLn(IFileName);
WriteLn('Имя расшифрованного файла: ');
ReadLn(OFileName);
WriteLn('Имя файла ключей: ');
ReadLn(KeyFileName);
{Прочитать ключи из файла}
Assign(KeyFile, KeyFileName);
Reset(KeyFile);
ReadLn(KeyFile, s);
Val(s, d, code);
ReadLn(KeyFile, s);
Val(s, n, code);
Close(KeyFile);
{Расшифровать файл}
Assign(WordFile, IFileName);
Assign(ByteFile, OFileName);
Rewrite(ByteFile);
Reset(WordFile);
while Not EOF(WordFile) do
begin
Read(WordFile, oneword);
onebyte:=LO((G(oneword, d, n)));
Write(ByteFile, onebyte);
end;{while}
Close(WordFile);
Close(ByteFile);
end;
end;
until l = 0;
end.
PHP — это язык программирования, основанный на использовании скриптов. Данный язык широко применяется для создания различных front-end и back-end веб-приложений. Поддерживается по-умолчанию большинством хостеров, являясь одним из лидеров среди языков программирования, предназначенных для создания динамических интерактивных сайтов.
|
Интересные материалы на сайте:
|
|
Автор, разработчик: Шаров Евгений (gcmsite@yandex.ru)
(c) 2000-2020 GCM-Site - системное и веб-программирование
Цитирование материалов сайта возможно только при наличии гиперссылки
|