Главная > криптография, Программирование > Криптография: Шифр Виженера и его реализация на Delphi.

Криптография: Шифр Виженера и его реализация на Delphi.

Немного теории. Шифр Виженера представляет собой усовершенствованную многоалфавитную систему шифрования (или, как её ещё называют, полиалфавитная). Идея шифра состоит в использовании в качестве ключа (кодовое слово) текст самого сообщения (открытого - не зашифрованного) или же шифрованного текста (закрытого). Кроме того, для усиления стойкости шифра, в качестве первого символа ключа берется случайным образом буква из алфавита. Авторами этой идеи являются Джероламо Кардано и собственно сам Блез де Виженер. Данный шифр также имеет другое название "шифр самоключ". Этот шифр Виженер описал в своей книге "Трактат о шифрах". В своем трактате Блез описал этот шифр следующим образом. В простейшем случае за основу бралась таблица Тритемия, в последствии которая получила название таблица Виженера.

* АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ь Ы Ъ Э Ю Я абвгдежзийклмнопрстуфхцчшщьыъэюя бвгдежзийклмнопрстуфхцчшщьыъэюяА вгдежзийклмнопрстуфхцчшщьыъэюяАБ гдежзийклмнопрстуфхцчшщьыъэюяАБВ дежзийклмнопрстуфхцчшщьыъэюяАБВГ ежзийклмнопрстуфхцчшщьыъэюяАБВГД жзийклмнопрстуфхцчшщьыъэюяАБВГДЕ зийклмнопрстуфхцчшщьыъэюяАБВГДЕЖ ийклмнопрстуфхцчшщьыъэюяАБВГДЕЖЗ йклмнопрстуфхцчшщьыъэюяАБВГДЕЖЗИ клмнопрстуфхцчшщьыъэюяАБВГДЕЖЗИЙ лмнопрстуфхцчшщьыъэюяАБВГДЕЖЗИЙК мнопрстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛ нопрстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМ опрстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМН прстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНО рстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОП стуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПР туфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРС уфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТ фхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУ хцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФ цчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХ чшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦ шщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧ щьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШ ьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩ ыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬ ъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫ эюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪ юяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭ яАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮ

Таблица Виженера

Замечу, в общем случае таблица Виженера состоит из алфавита, циклически сдвинутого на один символ в лево, однако возможны и другие перестановки - это на Ваше усмотрение. Кроме того, первая строка может представлять собой алфавит, случайным образом перемешанный.

Процесс шифрования выглядит следующим образом. Открытый текст(который надо зашифровать, записывается в строчку без пробелов. Далее необходимо определить ключ. Виженер предлагал в качестве ключа использовать сам открытый текст, с добавлением к началу ключа символ выбранный случайным образом. Но замечу что не обязательно следовать установленному правилу создателя шифра. В качестве ключа вполне возможно использовать и любую другую последовательность символов, длиною равной длине открытого текста.

После всего проделанного, для получения шифр-текста (криптограмма) берем первый символ открытого текста в качестве указателя строки в Таблице Виженера, а стоящую под ним букву - в качестве столбца. На пересечении этой пары из таблице выписываем символ шифр-текста. Далее повторяем эти действия для всех оставшихся символов. Для примера рассмотрим шифрование открытого текста - "яблочный джем". В качестве ключа будем использовать сам открытый текст с добавлением в начала случайного символа - у меня это вышло "щ". Повторюсь что ключ может быть образован иным способом, к примеру просто перемешанный случайным образом открытый текст - "ляйычнбо жемд". Но ключ должен быть известен получателю шифра, то есть известна схема перемешивания открытого текста, для того чтобы он мог расшифровать криптограмму. Так, теперь, записываем открытый текст в строку без пробелов, а под ней также записываем ключ.

Получаем:

открытый текст:  я б л о ч н ы й д ж е м
ключ:            щ я б л о ч н ы й д ж е
               ---------------------------
шифр-текст:      ш а м щ е д й д н к л с

Для того, чтобы восстановить (расшифровать) открытый текст, необходимо знать шифр-текст и ключ. Далее берем первую букву ключа определяем соответствующий ей столбец в Таблице Виженера и пробегаемся по нему сверху вниз пока не встретим первый символ шифр-текста. Как только встретили нужный символ, выписываем букву указывающую на эту строку - таким образом мы получаем первый символ открытого текста. Проделываем те же действия для оставшихся символов ключа и шифр-текста.

Шифр Виженера был незаслуженно забыт на долгое время. И многие по сей день под этим шифром понимают самый простой вариант с коротким ключевым словом и с таблицей, состоящей из обычных алфавитов.

А теперь, рассмотрим программную реализацию шифра Виженера на Delphi.

Для начала нам необходимо сгенерировать саму таблицу Виженера. Для этого

необходимо объявить следующие глобальные переменные:


mas_alf: array[1..32] of char = ('А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ь','Ы','Ъ','Э','Ю','Я');
tab_Vig: array[1..32,1..32] of Char;

Ну а теперь напишем код генерации таблицы:


var
i,j,k,n:integer;
begin
k:=0;
n:=k;

for i:=Ord('А')-191 to Ord('Я')-191 do
begin
k:=n+1;
for j:=Ord('А')-191 to Ord('Я')-191 do
begin
if k = 33 then
k:=1;
tab_vig[i][j]:=mas_alf[k];
k:=k+1;
end;
n:=n+1;
end;
end;

Таблица есть и можно смело приступать к реализации процедуры шифрования. Смотрим:


var
key : array [0..255] of Char;
s:char;
k:Boolean;
length_key,length_text,i,j,c,stroka,stolbec: integer;
begin
Label5.Caption:='';//
Memo2.Clear;//
length_key:=Edit1.GetTextLen;
Edit1.GetTextBuf(key,sizeof(key));
length_text:=Memo1.GetTextLen;
//выводим таблицу Виженера
for i:=Ord('А')-191 to Ord('Я')-191 do
begin
for j:=Ord('А')-191 to Ord('Я')-191 do
begin
Label5.Caption:= Label5.Caption +' '+ tab_Vig[i][j];
end;
Label5.Caption := Label5.Caption + #13+#10;
end;
//приступаем к процессу шифрования
j:=1;
c:=0;
k:=false;
Memo2.Lines.Add('Зашифрованный текст:');
Memo2.Lines.Add('------------------------');
for i:= 0 to Memo1.Lines.Count-1 do
begin
s:=Memo1.Lines[i][j];
if ((s <> #0) or (s <> #13)) then
while k = false do
begin
if Ord(key[c])>223 then
stolbec:=Ord(key[c])-32-191
else
stolbec:=Ord(s)-191;
if Ord(s)>223 then
stroka:=Ord(s)-32-191
else
stroka:=Ord(s)-191;
Memo2.Text:=Memo2.Text+tab_Vig[stroka][stolbec];
if(c < length_key-1)then
c:=c+1
else
c:=0;
j:=j+1;
s:=Memo1.Lines[i][j];
if(s = #0) then
k:=true;
end;
k:=false;
j:=1;
end;
Memo2.Lines.Add('------------------------');
end;

Так как шифрование реализовано, значит пора рассмотреть процедуру расшифровки. Смотрим:


var
key : array [0..255] of Char;
s:char;
k:Boolean;
length_key,length_text,i,j,c,stroka,stolbec,q: integer;
begin
Label5.Caption:='';//
Memo2.Clear;//
length_key:=Edit1.GetTextLen;
Edit1.GetTextBuf(key,sizeof(key));
length_text:=Memo1.GetTextLen;
j:=1;
c:=0;
k:=false;
Memo2.Lines.Add('Расшифрованный текст:');
Memo2.Lines.Add('------------------------');
for i:= 0 to Memo1.Lines.Count-1 do
begin
if Ord(Memo1.Lines[i][j])>223 then
s:=Ord(Memo1.Lines[i][j])-32-191
else
s:=Ord(Memo1.Lines[i][j])-191;
s:=Memo1.Lines[i][j];
if ((s <> #0) or (s <> #13)) then
while k = false do
begin
if Ord(key[c])>223 then
stolbec:=Ord(key[c])-32-191
else
stolbec:=Ord(s)-191;
for q:=1 to 32 do
begin
if tab_Vig[q][stolbec] = s then
begin
Memo2.Text:=Memo2.Text+Chr(q+191);
break;
end;
end;

if(c < length_key-1)then
c:=c+1
else
c:=0;
j:=j+1;
s:=Memo1.Lines[i][j];
if(s = #0) then
k:=true;
end;
k:=false;
j:=1;
end;
Memo2.Lines.Add('------------------------');
end;

Что ж, на этом все, если Вы обнаружили какие то неточности, или что-то не понятно прошу отписывать в комментарии. Спасибо за внимание.

Update: Тут была ссылка на пример, но она стала битой. По просьбе можно попробовать восстановить.

Рекомендую для прочтения:
Книга Чарльз Уэзерелл, "Этюды для программистов".

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.2/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.3/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.4/5.5/5. (12 голосов, средний: 5,00 из 5)
Загрузка...
  1. Александр
    5 февраля 2009 в 16:46 | #1

    Шифр Виженера интересен, когда начальный алфавит для циклического сдвига также является перемешанным. Вы об этом упомянули.

    Про шифр Виженера интересно написано в старой, но это этого не менее интересной, в книге Чарльза Уэззерелла "Этюды для программистов". Я ее читал как на русском, так и в оригинале. Забавно, что метод "взлома", оригинально предложенный Уэззереллом, был неверный, а наши, когда переводили, предложили правильный метод, и расшифровали им пример. Еще один прикольный момент: в английской книге была банальная опечатка - одна строка шифровки была просто пропущена, нормально!? Но наши додумкали и до этого и все равно расшифровали. Как мне сказал один из технических переводчиков, они потом связывались с Уэззерелом, и он подтвердил факт обидной опечатки.

  2. C0ffe1n
    5 февраля 2009 в 18:26 | #2

    @Александр
    Я упоменул ;), сразу же в первом обзаце после заголовка "Таблица Виженера". Благодарю, за интересную справку о шифре... Я даже в недоумении и в полном восторге от наших людей, респект им и уважуха =))

  3. Александр
    7 февраля 2009 в 03:22 | #3

    Если вдруг интересно, есть djv-шка с русским вариантом этой книги. Могу кинуть по почте, если не получается найти самостоятельно.

  4. C0ffe1n
    7 февраля 2009 в 14:20 | #4

    @Александр
    Конечно интересно, и я думаю многим тоже. Скинь на почту или можешь зайти на форум и там выложить ссылку.(только зарегаться прийдется)

  5. Александр
    10 февраля 2009 в 03:43 | #5

    @C0ffe1n
    Не подскажешь почту, куда кинуть? чего-то сходу не найду в профайле...

  6. Аскамик
    12 февраля 2009 в 13:34 | #6

    @Александр
    ""Если вдруг интересно, есть djv-шка с русским вариантом этой книги. Могу кинуть по почте, если не получается найти самостоятельно.""
    скинь пожалуйста мне на почту.. книгу или ссылку на скачку этой книги)
    моё мыло twinsilf@mail.ru

  7. C0ffe1n
    22 февраля 2009 в 00:37 | #7

    @Аскамик
    Книгу можешь скачать отсюда (битая ссылка удалена)

  8. Александр
    27 февраля 2009 в 12:26 | #8

    Забыл совсем. Я там тоже написал, откуда можно скачать русскую djvu'шку и скан главы шифр из английского оригинала.

  9. C0ffe1n
    27 февраля 2009 в 13:27 | #9
  10. }I{ULIK
    28 февраля 2009 в 16:29 | #10

    слушай не сможещ чуть переделать свою прогу нужно короче чтобы небыло буквы 'Й' а после буквы 'Я' был типо пробел вот такой '_' целый день голову ломал так и не допер очен надо Заранее спасыбо Учител

    • C0ffe1n
      28 февраля 2009 в 20:16 | #11

      }I{ULIK, отписывай на форум свою проблему, обсудим ;)

  11. }I{ULIK
    28 февраля 2009 в 20:45 | #12

    Короче надо написать прогу чтобы зашифровывала текст методом виженера с начяльным алфавитом ->
    'А','Б','В','Г','Д','Е','Ж','З','И','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ь','Ы','Ъ','Э','Ю','Я','_' пробывал просто так и написать а она при шифровке подставляет не ту которая на пересечении а которая правее ее

  12. C0ffe1n
    28 февраля 2009 в 21:41 | #13

    @}I{ULIK, проблема в том что таблица Виженера формируется по диапазону кодов заглавных русских символов [192..223] с учетом выравнивания, вычитая из каждого значения кода 191. ТАким образом становиться видно как формируется таблица русского алфавита. ЧТобы добавить пробел необходимо переписать код герерации таблицы так чтобы можно было добавить пробел. ЛУчше всего забить массив в ручную. И дальше все будет нормально.

  13. Игорь
    9 марта 2009 в 13:16 | #14

    Я пишу открытый текст: я б л о ч н ы й д ж е м
    ключ: щ я б л о ч н ы й д ж е
    ---------------------------
    шифр-текст: ш а м щ е д й д н к л с

    а когда дешифрует получается

    Расшифрованный текст:
    ------------------------
    ------------------------

  14. Игорь
    9 марта 2009 в 13:22 | #15

    А почему не английского текста?

  15. C0ffe1n
    9 марта 2009 в 20:08 | #16

    @Игорь
    для того чтобы расшифровать полученное ссообщение, его необходимо скопировать и вставить в верхнее поле(где открытый текст), после чего нажать кнопку дешифровать.
    Для того чтобы можно было работать с английским алфавитом, достаточно заменить русский на английсский. Можешь воспользоваться примером который я выложил здесь (битая ссылка удалена). Он немного переделан, там тебе тока надо заменить алфавит и изменить размерность массива. Будут вопросы отписывай их на форуме ;).

  16. Заурбек
    6 апреля 2013 в 13:30 | #17

    Можно исходник пожалуйста ... (цензура: email удалил, мы его вы и так видим)

  17. lizz
    8 апреля 2013 в 11:24 | #18

    @Заурбек
    Спрошу у автора статьи. Как будет ответ - дам знать.

  18. Ник
    18 апреля 2013 в 16:33 | #19

    Помогите !
    Зашифровать сообщение с помощью шифра Виженера. В качестве ключевого слова использовать фамилию зайцев
    информация это сведения независимо от формы их представления

    За ранее спасибо !

  19. lizz
    19 апреля 2013 в 13:35 | #20

    @ Ник
    А что вы пытались сделать и что именно не получилось?

  20. Ник
    21 апреля 2013 в 11:30 | #21

    @ lizz
    уже не надо все решено! когда просят ответ его надо давать а не вопросом на вопрос отвечать , это не помощь, да и все по русски написано что надо было сделать.

  21. lizz
    21 апреля 2013 в 13:45 | #22

    @ Ник
    Когда просят помощи - надо разобраться что у человека не получается и что он делает не так. Дать же ответ без объяснений - медвежья услуга, вы всё равно ничего не поймёте. Вы же не будете ребёнка учить таблице умножения не объясняя почему 2 х 2 = 4. Если вы не хотите разбираться, но вам нужен только ответ - это уже просьба не помочь, а сделать за вас. Надеюсь, вы поняли мою мысль.

  22. аНДРЕЙ
    9 июня 2013 в 18:05 | #23

    Программа работает не верно!!! похоже автор держит всех за тупиц. или хреновый программист?

  23. lizz
    10 июня 2013 в 10:19 | #24

    @аНДРЕЙ
    Конкретику, пожалуйста. До вас никто таких заявлений не делал.

  24. Аноним
    25 июня 2013 в 14:00 | #25

    В этом типизированном файле символьного типа находится зашифрованное сообщение - out_03_02.dan
    Для шифрования использовался шифр Виженера.
    Алфавитом являлась кодовая таблица ASCII, где содержится 255 символов.
    Ключ также зашифрован, но в загадке:
    В этой газете могли напечатать любое объявление. Например, об услугах кучера и прачки, о продаже коляски из Парижа (б/у), прочных дрожек (некондиция), семян репы и редиса, дачи со всеми угодьями даже старых подошв. Однако объявление именно об этом чиновник печатать в ней отказался. О чем же таком было это объявление, и кто его пытался дать (ключ - имя)?
    СРОЧНО

  25. Аноним
    25 июня 2013 в 14:16 | #26

    @ Аноним
    Ключ Платон

  26. Аноним
    17 октября 2014 в 17:50 | #27

    s:char;
    а
    s:=(Ord(Memo1.Lines[i][j])-32-191)

    типа integer.

    В итоге вроде Incompatible types

  27. Аноним
    17 октября 2014 в 18:03 | #28

    if Ord(Memo1.Lines[i][j])>223 then

    s:=Ord(Memo1.Lines[i][j])-32-191

    else

    s:=Ord(Memo1.Lines[i][j])-191;

    s:=Memo1.Lines[i][j];

    Так зачем в итоге все присваивания делали, если в конце сразу присвоили другое?
    Кажется, Дешифрование не работает правильно

  28. FLUF
    6 ноября 2015 в 12:38 | #29

    А можно посмотреть исходник всё-таки? программа не работает

  1. Пока что нет уведомлений.