Strona główna » Algorytmy » Szyfry » Szyfr Porta

Szyfr Porta

Metoda szyfrowania

Szyfr Porta jest to szyfr wieloalfabetowy, który jest niemalże identyczny do szyfru Vigenère. Zasadniczą różnicą w obu szyfrach jest ilość alfabetów użytych do zabezpieczenia danych. W szyfrze Vigenère jest ich 26 (każda litera ma swój alfabet). Z kolei szyfr Porta ma ich tylko 13. Do szyfrowania danych używa się słowa klucza oraz niezależnej od szyfrowanego tekstu i klucza tabelki. W tabelce rozpisane zostały używane do szyfrowania alfabety dla każdej litery alfabetu tj.:

Kluczabcdefghijklmnopqrstuvwxyz
ABnopqrstuvwxyzabcdefghijklm
CDopqrstuvwxyznmabcdefghijkl
EFpqrstuvwxyznolmabcdefghijk
GHqrstuvwxyznopklmabcdefghij
IJrstuvwxyznopqjklmabcdefghi
KLstuvwxyznopqrijklmabcdefgh
MNtuvwxyznopqrshijklmabcdefg
OPuvwxyznopqrstghijklmabcdef
QRvwxyznopqrstufghijklmabcde
STwxyznopqrstuvefghijklmabcd
UVxyznopqrstuvwdefghijklmabc
WXyznopqrstuvwxcdefghijklmab
YZznopqrstuvwxybcdefghijklma

Szyfrowanie i deszyfrowanie

W celu zaszyfrowania tekstu należy najpierw ustalić klucz. Klucz może być dowolnej długości i powinien składać się tylko z liter alfabetu, które zostały uwzględnione podczas tworzenia tabelki. Posiadając klucz i tekst można przejść do szyfrowania. Szyfrowanie polega na zamianie każdej litery w następujący sposób. Dla i-tej litery należy wziąć i-ty znak z klucza (jeśli klucz jest krótszy od tekstu to należy wziąć i mod długość klucza) i znaleźć w którym wierszu kolumny Klucz występuje litera. Kolejny krok polega na pobranie i-tej litery z tekstu. Należy ją zastąpić przez pole wskazane przez znaleziony wcześniej wiersz oraz kolumnę, która ma tą samą wartość co i-ta wartość tekstu. Deszyfrowanie polega na ponownym zaszyfrowaniu tekstu tym samym kluczem.

Przykład

Przykładowo za klucz zostanie przyjęte słowo HASLO, a szyfrowany tekst to TAJNA INFORMACJA. Pierwszy krok polega na zaszyfrowaniu litery T. Z klucza pobierany jest odpowiedni znak. W tym przypadku jest to H i można go znaleźć w 4 wierszu tabelki. Natomiast pole w kolumnie T i wierszu 4 ma wartość D. Litera A jest szyfrowana przez literę A. W takim razie w szyfrogramie ma wartość N. Ostateczny zaszyfrowany tekst to DNSIU YAOJKPNYOU. W celu zwiększenia skuteczności szyfrowania z szyfrowanego tekstu można usunąć wszystkie znaki niebędące literami, albo cyframi.

Implementacja

Strategia

Program będzie szyfrował tekst zapisany przy pomocy małych liter alfabetu łacińskiego. Należy zauważyć, że tabelka jest tak skonstruowana, że należy ją wczytać do programu. W tym przypadku nie wystarczy alfabet przesunąć o sumę miejsce litery n w alfabecie jak było w przypadku szyfru Vigenère. Numer wiersza też można wyliczyć na podstawie numeru litery w alfabecie. Wystarczy odjąć jeden, podzielić przez dwa, zaokrąglić wynik, a następnie dodać 1 (pierwszy i ostatni krok jest pomijany podczas pisania w C++, ponieważ pierwszy indeks to 0, a nie 1).

Wracają co problemu z kluczem strategia polega na zapisaniu wszystkich wierszy tabeli w postaci tekstu. Wszystkie dane nie będą rozdzielone, ani spacją, ani znakiem nowej linii - wszystkie dane mają tę samą długość i wiersze też, więc istnieje możliwość wyliczenia, który znak chcemy pobrać.

Szyfrowanie

Funkcja change() będzie służyła do szyfrowania i deszyfrowania danych. Będzie przyjmować trzy argumenty: txt - tekst do zaszyfrowania, key - klucz użyty do szyfrowania danych oraz table - tablica znaków w tabelce. W tym przypadku jest założenie, że tabelka ma szerokość 26 znaków.

  1. char* change (char* txt, char* key, char* table) {
  2.   char* wynik = new char[strlen(txt) + 1];
  3.   wynik[strlen(txt)] = '\0';
  4.   for(int i = 0; txt[i]; i++) {
  5.     if((txt[i] >= 'a' && txt[i] <= 'z')) {
  6.       wynik[i] = table[((key[i % strlen(key)] - 'a') / 2) * 26 + txt[i] - 'a'];
  7.     } else {
  8.       wynik[i] = txt[i];
  9.     }
  10.   }
  11.   return wynik;
  12. }

(2.) Zaalokowanie pamięci pod tekst wynikowy i (3.) zaznaczenie gdzie dane się kończą. (4.) Dla każdego znaku w tekście: (5.) sprawdzenie czy jest małą literą alfabetu łacińskiego. (6.) Jeśli jest to pobieramy odpowiedni znak z podane tabelki. (7.) Jednak jeśli jest to inny znak to (8.) przepisz znak. (9.) Na koniec zwróć szyfrogram.

Testowanie funkcji

Powyższą funkcję można przetestować przy pomocy poniższej funkcji main(). W celu zachowania czytelności kodu część wartości zmiennej table została zastąpiona trzykropkiem. Pełna wersja kodu jest dostępna do pobrania poniżej.

  1. int main () {
  2.   char* table = "nopqrstuvwxyzabcdefghijklmopqrstuvwxyznmabcdefghijklpqrstuvwxyznolmabcdefghijkqrstuvwxyznopklmabcdefghijrstuvwxyznopqjklmabcdefghistuvwxyznopqrijklmabcdefghtuvwxyznopqrshijklmabcdefguvwxyznopqrstghijklmabcdefvwxyznopqrstufghijklmabcdewxyznopqrstuvefghijklmabcdxyznopqrstuvwdefghijklmabcyznopqrstuvwxcdefghijklmabznopqrstuvwxybcdefghijklma";
  3.   int TXT_LENGTH = 256;
  4.   cout << "Podaj tekst do zaszyfrowania:\n";
  5.   char* txt = new char[TXT_LENGTH];
  6.   cin.getline(txt, TXT_LENGTH);
  7.   cout << "Podaj klucz:\n";
  8.   char* key = new char[TXT_LENGTH];
  9.   cin.getline(key, TXT_LENGTH);
  10.   char* txtc = change(txt, key, table);
  11.   cout << txtc << endl;
  12.   char* txtd = change(txtc, key, table);
  13.   cout << txtd << endl;
  14.   delete[] txt, txtc, txtd, key;
  15.   system("pause");
  16.   return 0;
  17. }

Zadania

Zadanie 1

Napisz program, który:

  1. zaszyfruje w taki sam sposób duże litery alfabetu łacińskiego jak ich małe odpowiedniki
  2. podawany klucz dalej będzie złożony jedynie z małych liter alfabetu łacińskiego

Przykładowo dla danych klucza klucz oraz wiadomości To jest tajna INFORMACJA! poprawnym wynikiem będzie:

  1. Bj xqab fzoix UIXEDYSUTO!