Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.
Film nawiązujący do treści materiału: Szyfr polialfabetyczny Vigenere'a.
Podsumowanie
Zaimplementujmy w języku C++ szyfr Vigenère’a. W pierwszym kroku dodajemy wybrane biblioteki.
Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny.
Linia 2. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny.
Linia 4. using namespace std średnik.
#include <iostream>
#include <string>
using namespace std;
Kolejnym krokiem jest zdefiniowanie funkcji generujKlucz(), która ma za zadanie przygotowanie klucza o odpowiedniej długości, tj. równej długości tekstu szyfrowanego. Funkcja jako argumenty przyjmie słowo‑klucz oraz długość szyfrowanego tekstu.
Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny.
Linia 2. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny.
Linia 4. using namespace std średnik.
Linia 6. string generujKlucz otwórz nawias okrągły string slowoKlucz przecinek int dlugoscWiadomosci zamknij nawias okrągły.
Linia 7. otwórz nawias klamrowy.
Linia 8. int iterator znak równości 0 średnik.
Linia 10. while otwórz nawias okrągły slowoKlucz kropka length otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny dlugoscWiadomosci zamknij nawias okrągły.
Linia 11. otwórz nawias klamrowy.
Linia 12. slowoKlucz plus znak równości slowoKlucz otwórz nawias kwadratowy iterator zamknij nawias kwadratowy średnik.
Linia 13. iterator plus plus średnik.
Linia 14. zamknij nawias klamrowy.
Linia 16. return slowoKlucz średnik.
Linia 17. zamknij nawias klamrowy.
#include <iostream>
#include <string>
using namespace std;
string generujKlucz(string slowoKlucz, int dlugoscWiadomosci)
{
int iterator = 0;
while (slowoKlucz.length() < dlugoscWiadomosci)
{
slowoKlucz += slowoKlucz[iterator];
iterator++;
}
return slowoKlucz;
}
Przedstawiona funkcja tworzy klucz, powielając słowo klucz tak długo, aż klucz osiągnie pożądaną długość. Następnie musimy zdefiniować funkcję szyfrującą. Jej argumentami będą: szyfrowana wiadomość oraz klucz – ten, który został utworzony funkcją generujKlucz(). Funkcja szyfrująca wykonuje pętle po wszystkich znakach szyfrowanej wiadomości. Dla każdego znaku (zarówno wiadomości, jak i klucza – mają one taką samą długość) określany jest jego indeks, czyli numer znaku. Otrzymujemy go poprzez odjęcie od kodu ASCII liczby 65 (czyli kodu litery A). Tym samym litera A ma indeks 0, B - 1, C - 2 itd.
Szyfrogram powstaje następująco: suma indeksów litery wiadomości i odpowiadającej jej litery klucza dzielona jest modulo 26. Reszta z dzielenia jest indeksem kolejnej litery szyfrogramu, a więc wystarczy do niego dodać znak o kodzie ASCII, będący tym właśnie indeksem, powiększonym o 65.
Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny.
Linia 2. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny.
Linia 4. using namespace std średnik.
Linia 6. string generujKlucz otwórz nawias okrągły string slowoKlucz przecinek int dlugoscWiadomosci zamknij nawias okrągły.
Linia 7. otwórz nawias klamrowy.
Linia 8. int iterator znak równości 0 średnik.
Linia 10. while otwórz nawias okrągły slowoKlucz kropka length otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny dlugoscWiadomosci zamknij nawias okrągły.
Linia 11. otwórz nawias klamrowy.
Linia 12. slowoKlucz plus znak równości slowoKlucz otwórz nawias kwadratowy iterator zamknij nawias kwadratowy średnik.
Linia 13. iterator plus plus średnik.
Linia 14. zamknij nawias klamrowy.
Linia 16. return slowoKlucz średnik.
Linia 17. zamknij nawias klamrowy.
Linia 19. string szyfruj otwórz nawias okrągły string wiadomosc przecinek string klucz zamknij nawias okrągły.
Linia 20. otwórz nawias klamrowy.
Linia 21. string szyfrogram znak równości cudzysłów cudzysłów średnik.
Linia 23. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny wiadomosc kropka length otwórz nawias okrągły zamknij nawias okrągły średnik i plus plus zamknij nawias okrągły.
Linia 24. otwórz nawias klamrowy.
Linia 25. int indeksLiteryWiadomosci znak równości wiadomosc otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 26. int indeksLiteryKlucza znak równości klucz otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 27. int indeksLiterySzyfrogramu znak równości otwórz nawias okrągły indeksLiteryWiadomosci plus indeksLiteryKlucza zamknij nawias okrągły procent 26 średnik.
Linia 29. char kodAsciiLiterySzyfrogramu znak równości otwórz nawias okrągły char zamknij nawias okrągły otwórz nawias okrągły indeksLiterySzyfrogramu plus 65 zamknij nawias okrągły średnik.
Linia 30. szyfrogram plus znak równości kodAsciiLiterySzyfrogramu średnik.
Linia 31. zamknij nawias klamrowy.
Linia 32. return szyfrogram średnik.
Linia 33. zamknij nawias klamrowy.
#include <iostream>
#include <string>
using namespace std;
string generujKlucz(string slowoKlucz, int dlugoscWiadomosci)
{
int iterator = 0;
while (slowoKlucz.length() < dlugoscWiadomosci)
{
slowoKlucz += slowoKlucz[iterator];
iterator++;
}
return slowoKlucz;
}
string szyfruj(string wiadomosc, string klucz)
{
string szyfrogram = "";
for (int i = 0; i < wiadomosc.length(); i++)
{
int indeksLiteryWiadomosci = wiadomosc[i] - 65;
int indeksLiteryKlucza = klucz[i] - 65;
int indeksLiterySzyfrogramu = (indeksLiteryWiadomosci + indeksLiteryKlucza) % 26;
char kodAsciiLiterySzyfrogramu = (char)(indeksLiterySzyfrogramu + 65);
szyfrogram += kodAsciiLiterySzyfrogramu;
}
return szyfrogram;
}
Kolejnym etapem jest implementacja funkcji deszyfrującej. Będzie ona wyglądała bardzo podobnie. Jej argumentami są: zaszyfrowana wiadomość oraz klucz. Pojawia się tu jednak dodatkowy problem. Podczas odszyfrowania (odwrotnie niż przy szyfrowaniu) będziemy odejmować indeks litery klucza od indeksu litery szyfrogramuszyfrogramszyfrogramu. Wynik takiej operacji może być ujemny, co musimy uwzględnić przy dzieleniu modulo 26. Zdefiniujemy więc dodatkową funkcję modulo26(), która w przypadku ujemnego wyniku zwróci nam uzyskaną wartość zwiększoną o 26. W efekcie wynik będzie zawsze dodatni.
Linia 1. int modulo26 otwórz nawias okrągły int a zamknij nawias okrągły.
Linia 2. otwórz nawias klamrowy.
Linia 3. int wynik znak równości a procent 26 średnik.
Linia 4. return wynik otwórz nawias ostrokątny 0 znak zapytania wynik plus 26 dwukropek wynik średnik.
Linia 5. zamknij nawias klamrowy.
Linia 7. string deszyfruj otwórz nawias okrągły string szyfrogram przecinek string klucz zamknij nawias okrągły.
Linia 8. otwórz nawias klamrowy.
Linia 9. string wiadomosc znak równości cudzysłów cudzysłów średnik.
Linia 11. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny szyfrogram kropka length otwórz nawias okrągły zamknij nawias okrągły średnik i plus plus zamknij nawias okrągły.
Linia 12. otwórz nawias klamrowy.
Linia 13. int indeksLiterySzyfrogramu znak równości szyfrogram otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 14. int indeksLiteryKlucza znak równości klucz otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 15. int indeksLiteryWiadomosci znak równości otwórz nawias okrągły indeksLiterySzyfrogramu minus indeksLiteryKlucza zamknij nawias okrągły procent 26 średnik.
Linia 17. char kodAsciiLiteryWiadomosci znak równości otwórz nawias okrągły char zamknij nawias okrągły otwórz nawias okrągły indeksLiteryWiadomosci plus 65 zamknij nawias okrągły średnik.
Linia 18. wiadomosc plus znak równości kodAsciiLiteryWiadomosci średnik.
Linia 19. zamknij nawias klamrowy.
Linia 20. return wiadomosc średnik.
Linia 21. zamknij nawias klamrowy.
int modulo26(int a)
{
int wynik = a % 26;
return wynik < 0 ? wynik + 26 : wynik;
}
string deszyfruj(string szyfrogram, string klucz)
{
string wiadomosc = "";
for (int i = 0; i < szyfrogram.length(); i++)
{
int indeksLiterySzyfrogramu = szyfrogram[i] - 65;
int indeksLiteryKlucza = klucz[i] - 65;
int indeksLiteryWiadomosci = (indeksLiterySzyfrogramu - indeksLiteryKlucza) % 26;
char kodAsciiLiteryWiadomosci = (char)(indeksLiteryWiadomosci + 65);
wiadomosc += kodAsciiLiteryWiadomosci;
}
return wiadomosc;
}
Teraz wystarczy już tylko w odpowiedni sposób wywołać funkcję dla przykładowej wiadomości oraz klucza. Funkcja main() będzie wyglądać następująco:
Linia 1. int main otwórz nawias okrągły zamknij nawias okrągły.
Linia 2. otwórz nawias klamrowy.
Linia 3. string wiadomosc znak równości cudzysłów OPADY cudzysłów średnik.
Linia 4. string slowoKlucz znak równości cudzysłów LEJE cudzysłów średnik.
Linia 6. string klucz znak równości generujKlucz otwórz nawias okrągły slowoKlucz przecinek wiadomosc kropka length otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik.
Linia 7. string szyfrogram znak równości szyfruj otwórz nawias okrągły wiadomosc przecinek klucz zamknij nawias okrągły średnik.
Linia 9. cout otwórz nawias ostrokątny otwórz nawias ostrokątny szyfrogram otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik.
Linia 11. string odszyfrowanaWiadomosc znak równości deszyfruj otwórz nawias okrągły szyfrogram przecinek klucz zamknij nawias okrągły średnik.
Linia 13. cout otwórz nawias ostrokątny otwórz nawias ostrokątny odszyfrowanaWiadomosc otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik.
Linia 15. return 0 średnik.
Linia 16. zamknij nawias klamrowy.
Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny.
Linia 2. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny.
Linia 4. using namespace std średnik.
Linia 6. string generujKlucz otwórz nawias okrągły string slowoKlucz przecinek int dlugoscWiadomosci zamknij nawias okrągły.
Linia 7. otwórz nawias klamrowy.
Linia 8. int iterator znak równości 0 średnik.
Linia 10. while otwórz nawias okrągły slowoKlucz kropka length otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny dlugoscWiadomosci zamknij nawias okrągły.
Linia 11. otwórz nawias klamrowy.
Linia 12. slowoKlucz plus znak równości slowoKlucz otwórz nawias kwadratowy iterator zamknij nawias kwadratowy średnik.
Linia 13. iterator plus plus średnik.
Linia 14. zamknij nawias klamrowy.
Linia 16. return slowoKlucz średnik.
Linia 17. zamknij nawias klamrowy.
Linia 19. string szyfruj otwórz nawias okrągły string wiadomosc przecinek string klucz zamknij nawias okrągły.
Linia 20. otwórz nawias klamrowy.
Linia 21. string szyfrogram znak równości cudzysłów cudzysłów średnik.
Linia 23. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny wiadomosc kropka length otwórz nawias okrągły zamknij nawias okrągły średnik i plus plus zamknij nawias okrągły.
Linia 24. otwórz nawias klamrowy.
Linia 25. int indeksLiteryWiadomosci znak równości wiadomosc otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 26. int indeksLiteryKlucza znak równości klucz otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 27. int indeksLiterySzyfrogramu znak równości otwórz nawias okrągły indeksLiteryWiadomosci plus indeksLiteryKlucza zamknij nawias okrągły procent 26 średnik.
Linia 29. char kodAsciiLiterySzyfrogramu znak równości otwórz nawias okrągły char zamknij nawias okrągły otwórz nawias okrągły indeksLiterySzyfrogramu plus 65 zamknij nawias okrągły średnik.
Linia 30. szyfrogram plus znak równości kodAsciiLiterySzyfrogramu średnik.
Linia 31. zamknij nawias klamrowy.
Linia 32. return szyfrogram średnik.
Linia 33. zamknij nawias klamrowy.
Linia 35. int modulo26 otwórz nawias okrągły int a zamknij nawias okrągły.
Linia 36. otwórz nawias klamrowy.
Linia 37. int wynik znak równości a procent 26 średnik.
Linia 38. return wynik otwórz nawias ostrokątny 0 znak zapytania wynik plus 26 dwukropek wynik średnik.
Linia 39. zamknij nawias klamrowy.
Linia 41. string deszyfruj otwórz nawias okrągły string szyfrogram przecinek string klucz zamknij nawias okrągły.
Linia 42. otwórz nawias klamrowy.
Linia 43. string wiadomosc znak równości cudzysłów cudzysłów średnik.
Linia 45. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny szyfrogram kropka length otwórz nawias okrągły zamknij nawias okrągły średnik i plus plus zamknij nawias okrągły.
Linia 46. otwórz nawias klamrowy.
Linia 47. int indeksLiterySzyfrogramu znak równości szyfrogram otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 48. int indeksLiteryKlucza znak równości klucz otwórz nawias kwadratowy i zamknij nawias kwadratowy minus 65 średnik.
Linia 49. int indeksLiteryWiadomosci znak równości modulo26 otwórz nawias okrągły indeksLiterySzyfrogramu minus indeksLiteryKlucza zamknij nawias okrągły średnik.
Linia 51. char kodAsciiLiteryWiadomosci znak równości otwórz nawias okrągły char zamknij nawias okrągły otwórz nawias okrągły indeksLiteryWiadomosci plus 65 zamknij nawias okrągły średnik.
Linia 52. wiadomosc plus znak równości kodAsciiLiteryWiadomosci średnik.
Linia 53. zamknij nawias klamrowy.
Linia 54. return wiadomosc średnik.
Linia 55. zamknij nawias klamrowy.
Linia 58. int main otwórz nawias okrągły zamknij nawias okrągły.
Linia 59. otwórz nawias klamrowy.
Linia 60. string wiadomosc znak równości cudzysłów OPADY cudzysłów średnik.
Linia 61. string slowoKlucz znak równości cudzysłów LEJE cudzysłów średnik.
Linia 63. string klucz znak równości generujKlucz otwórz nawias okrągły slowoKlucz przecinek wiadomosc kropka length otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik.
Linia 64. string szyfrogram znak równości szyfruj otwórz nawias okrągły wiadomosc przecinek klucz zamknij nawias okrągły średnik.
Linia 66. cout otwórz nawias ostrokątny otwórz nawias ostrokątny szyfrogram otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik.
Linia 68. string odszyfrowanaWiadomosc znak równości deszyfruj otwórz nawias okrągły szyfrogram przecinek klucz zamknij nawias okrągły średnik.
Linia 70. cout otwórz nawias ostrokątny otwórz nawias ostrokątny odszyfrowanaWiadomosc otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik.
Linia 72. return 0 średnik.
Linia 73. zamknij nawias klamrowy.
#include <iostream>
#include <string>
using namespace std;
string generujKlucz(string slowoKlucz, int dlugoscWiadomosci)
{
int iterator = 0;
while (slowoKlucz.length() < dlugoscWiadomosci)
{
slowoKlucz += slowoKlucz[iterator];
iterator++;
}
return slowoKlucz;
}
string szyfruj(string wiadomosc, string klucz)
{
string szyfrogram = "";
for (int i = 0; i < wiadomosc.length(); i++)
{
int indeksLiteryWiadomosci = wiadomosc[i] - 65;
int indeksLiteryKlucza = klucz[i] - 65;
int indeksLiterySzyfrogramu = (indeksLiteryWiadomosci + indeksLiteryKlucza) % 26;
char kodAsciiLiterySzyfrogramu = (char)(indeksLiterySzyfrogramu + 65);
szyfrogram += kodAsciiLiterySzyfrogramu;
}
return szyfrogram;
}
int modulo26(int a)
{
int wynik = a % 26;
return wynik < 0 ? wynik + 26 : wynik;
}
string deszyfruj(string szyfrogram, string klucz)
{
string wiadomosc = "";
for (int i = 0; i < szyfrogram.length(); i++)
{
int indeksLiterySzyfrogramu = szyfrogram[i] - 65;
int indeksLiteryKlucza = klucz[i] - 65;
int indeksLiteryWiadomosci = modulo26(indeksLiterySzyfrogramu - indeksLiteryKlucza);
char kodAsciiLiteryWiadomosci = (char)(indeksLiteryWiadomosci + 65);
wiadomosc += kodAsciiLiteryWiadomosci;
}
return wiadomosc;
}
int main()
{
string wiadomosc = "OPADY";
string slowoKlucz = "LEJE";
string klucz = generujKlucz(slowoKlucz, wiadomosc.length());
string szyfrogram = szyfruj(wiadomosc, klucz);
cout << szyfrogram << endl;
string odszyfrowanaWiadomosc = deszyfruj(szyfrogram, klucz);
cout << odszyfrowanaWiadomosc << endl;
return 0;
}
Po uruchomieniu programu najpierw generowany jest klucz na podstawie słowa „LEJE”. Następnie wykonywana jest funkcja szyfruj() i powstaje szyfrogram, który zostaje wyświetlony na ekranie. W kolejnym etapie szyfrogram jest z powrotem odszyfrowywany za pomocą funkcji deszyfruj(), a powstała wiadomość jest wyświetlana na ekranie. W przypadku naszych przykładowych słów powstały szyfrogram ma postać „ZTJHJ”. Po odszyfrowaniu uzyskujemy prawidłową postać odszyfrowaną: „OPADY”.
Słownik
alfabet szyfrowy
alfabet szyfrowy
przekształcony alfabet służący do zaszyfrowywania tekstu jawnego
graficzny interfejs
graficzny interfejs
(ang. Graphical User Interface); interfejs pozwalający komunikować się z programem za pomocą wyświetlanych okien
szyfrogram
szyfrogram
zaszyfrowana wiadomość
szyfrowanie
szyfrowanie
przekształcenie tekstu jawnego w sposób uniemożliwiający odczytanie oryginalnej treści bez dokonania procesu deszyfrowania, do przeprowadzenia którego niezbędna jest znajomość klucza szyfrującego
tekst jawny
tekst jawny
tekst przed zaszyfrowaniem lub po odszyfrowaniu; jest to zwyczajny, niezaszyfrowany tekst, który można swobodnie przeczytać