Strona główna » Algorytmy » Szyfry » Szyfr Trójkwadratowy
 

Szyfr Trójkwadratowy

Wstęp

Do szyfrowania szyfrem Trójkwadratowym potrzebne są trzy tablice Polibiusza, a z tekstu jawnego szyfrowane są pary liter. Zaletą tego szyfru jest fakt, że szyfrując kilka razy ten sam tekst tą samą tablicą można uzyskać różne szyfrogramy. Wadą tego rozwiązania jest wzrost długości szyfrogramu względem tekstu jawnego o 50%.

Opis

Szyfrowanie

W celu zaszyfrowania danych na początku należy zbudować trzy tablice Polibiusza o wymiarach 5×5. Oznacza to, że można zaszyfrować maksymalnie 25 znaków. W każdym kwadracie zestaw znaków musi być identyczny. Proces szyfrowania danych polega na zaszyfrowaniu każdej pary znaków w następujący sposób:

Pobieramy współrzędne (x1, y1) pierwszej litery z pary w kwadracie numer 1 oraz wspórzędne (x2, y2) drugiej litery w kwadracie numer 2. Pierwsza litera, którą dopisujemy do szyfrogramu to dowolna z kwadratu numer 1, która jest w tym samym wierszu co pierwsza litera z pary. Następna litera ma współrzędne (x2, y1) i jest pobierana z trzeciego kwadratu. Trzecia dopisywana litera do szyfrogramu może być dowolną z kolumny z kwadratu 2 w którym znajduje się druga litera z pary.

Przykład

Niech szyfrowanym tekstem będzie "TAJNAINFORMACJA". Ze względu na to, że ilość znaków jest nieparzysta to na koniec należy dopisać dowolny znak z alfabetu np. X. Tekst będzie szyfrowany przez następujące kwadraty:

ABCDE
FGHIJ
KLMNO
PQRST
UWXYZ
AFKPU
BGLQW
CHMRX
DINSY
EJOTZ
ACFJO
BEINS
DHMRW
GLQUY
KPTXZ

Kwadrat po lewej stronie będzie kwadratem numer 1, kwadrat u góry kwadrat 2, a ostatni będzie kwadratem 3. Takie ustawienie znacznie usprawnia proces wybierania znaku z kwadratu numer 3, ponieważ leży on wtedy na przecięciu wiersza z kwadratu numer 1 i kolumny znaku z kwadratu 2.

Pierwszy etap polega na pogrupowaniu znaków w pary i odczytaniu współrzędnych tych znaków. Na tej podstawie możliwe jest utworzenie trzech znaków, które potem zostaną zapisane do szyfrogramu.

ParyTAJNAINFORMACJAX
(x1, y1)(4, 5)(2, 5)(1, 1)(3, 4)(3, 5)(3, 3)(1, 3)(1, 1)
(x2, y2)(1, 1)(4, 3)(4, 2)(1, 2)(3, 4)(1, 1)(5, 2)(3, 5)
(x1, losowe)(4, 3)(2, 1)(1, 5)(3, 5)(3, 4)(3, 1)(1, 5)(1, 3)
(x2, y1)(1, 5)(4, 5)(4, 1)(1, 4)(3, 5)(1, 3)(5, 3)(3, 1)
(losowe, y2)(1, 1)(2, 3)(2, 2)(4, 2)(3, 4)(1, 1)(4, 2)(2, 5)
TrójkiRKACXHKJETGNQTQFDAKWNDFP

Zaszyfrowany tekst jawny daje przykładowy szyfrogram "RKACXHKJETGNQTQFDAKWNDFP". W celu rozszyfrowania danych należy sporządzić podobną tabelkę, ale należy zamienić sekcję Trójek i Par miejscami.

Implementacja

Założenia

Kwadraty, które służą do szyfrowania będą przetrzymywane jako łańcuch znaków. Wszystkie prowadzone dane będą zapisane włącznie wielkimi literami (drukowanymi). Program nie sprawdza poprawności danych wejściowych, więc zakłada się, że nie jest to potrzebne.

Funkcje pomocnicze

Współrzędne znaku

Funkcja znajdz() przyjmuje dwa argumenty: tekst - dane kwadratu oraz c - znak do wyszukania w kwadracie. Wynikiem działania funkcji jest pozycja znaku c w kwadracie w postaci pary współrzędnych (x, y).

C++
C#
  1. para znajdz(string tekst, char c) {
  2.   int poz = tekst.find(c);
  3.   return make_pair(poz % 5, poz / 5);
  4. }

Losowanie znaku

Funkcja losujProcz() przyjmuje dwa argumenty: max - zakres losowania oraz procz - wartość, która jest wykluczona z losowania. Wynikiem działania funkcji jest wartość z zbioru {0, 1, .., max} / {procz}.

C++
C#
  1. int losujProcz(int max, int procz) {
  2.   int los = rand() % max;
  3.   if (los == max)
  4.     los = (los + 1) % max;
  5.   return los;
  6. }

Szyfrowanie

Funkcja szyfruj() przyjmuje cztery argumenty: tekst - tekst do zaszyfrowania, kw1, kw2, kw3 - kolejne zapisy kwadratów jako ciągu znaków. Wynikiem działania funkcji jest zwrócenie poprawnego szyfrogramu.

C++
C#
  1. string szyfruj(string tekst, string kw1, string kw2, string kw3) {
  2.   string wynik = "";
  3.   if (tekst.length() % 2 == 1)
  4.     tekst += 'X';
  5.   for (int i = 0; i < tekst.length(); i += 2) {
  6.     para poz1 = znajdz(kw1, tekst[i]);
  7.     para poz3 = znajdz(kw2, tekst[i + 1]);
  8.     wynik += kw1[5 * losujProcz(5, poz1.second) + poz1.first];
  9.     wynik += kw3[5 * poz1.second + poz3.first];
  10.     wynik += kw2[5 * poz3.second + losujProcz(5, poz3.first)];
  11.   }
  12.   return wynik;
  13. }

(2.) Zadeklaruj zmienną do zapisu wyniku i (3.) upewnij się, że tekst ma parzystą długość, jeśli nie to (4.) dopisz znak 'X'. Następnie (5.) dla każdej pary: (6. - 7.) znajdź współrzędne znaków i na ich podstawie (8. - 10.) dopisz odpowiednie znaki wybierając z właściwych kwadratów.

Deszyfrowanie

Funkcja rozszyfruj() przyjmuje takie same argumenty jak funkcja szyfruj(). Wykonywane kroki są analogiczne. Wynikiem działania funkcji jest rozszyfrowany tekst.

C++
C#
  1. string rozszyfruj(string szyfr, string kw1, string kw2, string kw3) {
  2.   string wynik = "";
  3.   for (int i = 0; i < szyfr.length(); i += 3) {
  4.     para poz1 = znajdz(kw1, szyfr[i]);
  5.     para poz2 = znajdz(kw3, szyfr[i + 1]);
  6.     para poz3 = znajdz(kw2, szyfr[i + 2]);
  7.     wynik += kw1[5 * poz2.second + poz1.first];
  8.     wynik += kw2[5 * poz3.second + poz2.first];
  9.   }
  10.   return wynik;
  11. }

Testowanie funkcji

W celu przetestowania działania napisanych funkcji można posłużyć się poniższym kodem, który wczytuje od użytkownika potrzebne informacje. Kwadraty powinny być zapisane jako ciąg 25 wielkich liter, a tekst do zaszyfrowania również powinien się składać tylko z wielkich liter.

C++
C#
  1. int main () {
  2.   srand(time(0));
  3.   string kw1, kw2, kw3, tekst;
  4.   cout << "Podaj litery pierwszego kwadratu:\n";
  5.   getline(cin, kw1);
  6.   cout << "Podaj litery drugiego kwadratu:\n";
  7.   getline(cin, kw2);
  8.   cout << "Podaj litery trzeciego kwadratu:\n";
  9.   getline(cin, kw3);
  10.   cout << "Podaj tekst do zaszyfrowania:\n";
  11.   getline(cin, tekst);
  12.   cout << "\nSzyfrogram:" << endl;
  13.   string szyfr = szyfruj(tekst, kw1, kw2, kw3);
  14.   cout << szyfr;
  15.   cout << "\nTekst jawny:" << endl;
  16.   cout << rozszyfruj(szyfr, kw1, kw2, kw3);
  17.   system("pause");
  18.   return 0;
  19. }
Zadania
Zadanie 1
Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1