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

Szyfr Bifid

Szyfr

Szyfr Bifid w celu zaszyfrowania danych korzysta z szachownicy Polibiusza oraz słowa kluczowego. Na podstawie słowa kluczowego tworzy się alfabet w którym najpierw występują pierwsze wystąpienia unikalnych liter z słowa klucza, a następnie dopisywane są pozostałe litery alfabetu. Znak I oraz J są nierozróżnialne. Tak przygotowany alfabet należy wpisać do szachownicy Polibiusza w spirali, zgodnie z ruchem wskazówek zegara począwszy od lewego, górnego rogu.

Szyfrując dane dla każdej litery należy znaleźć ich pozycje w szachownicy Polibiusza, a następnie zapisać w kolumnie pod daną literą. Numer wiersza ma się znajdować nad numerem kolumny. Następnie odczytywane są kolejne pary współrzędnych odczytując liczby kolejno najpierw z oznaczeń wierszy, a potem kolumn. Każda para jest później zamieniana na literę na podstawie szachownicy Polibiusza. Ze względu na to, że znaki interpunkcyjne nie są szyfrowane to zaleca się ich usunięcia.

Przykład

Szyfrowanie

Weźmy przykładowo słowo kluczowe "TAJNEHASLO". Na jego podstawie zostaje utworzony alfabet "TAINEHSLOBCDFGKMPQRUVWXYZ", które następnie zostaje zapisane do szachownicy Polibiusza w następujący sposób:

#12345
1TAINE
2MPQRH
3KYZUS
4GXWVL
5FDCBO

Po przygotowaniu szachownicy można przejść do szyfrowania danych. Szyfrowanym tekstem jawnym będzie "TAJNAINFORMACJA". Na początek dla każdej litery szukamy jej współrzędnych w szachownicy Polibiusza:

LiteraTAJNAINFORMACJA
Wiersz111111155221511
Kolumna123423415412332

Teraz kolejny krok polega na odczytaniu poziomo wiersza Wiersz potem Kolumna i pogrupować liczby parami tak, aby uzyskać współrzędne dla litery do szyfrogramu. Proces ten jest następujący:

Para(1, 1)(1, 1)(1, 1)(1, 5)(5, 2)(2, 1)(5, 1)(1, 1)(2, 3)(4, 2)(3, 4)(1, 5)(4, 1)(2, 3)(3, 2)
SzyfrogramTTTEDMFTQXUEGQY

Zaszyfrowany tekst "TAJNAINFORMACJA" przy pomocy słowa kluczowego "TAJNEHASLO" to "TTTEDMFTQXUEGQY".

Deszyfrowanie

Należy utworzyć szachownicę Polibiusza, a następnie odwrócić proces szyfrowania. Uwaga ze względu na zastosowanie szachownicy Polibiusza litery I oraz J są nierozróżnialne, więc rozszyfrowywując utworzony wcześniej szyfrogram otrzymamy nie "TAJNAINFORMACJA", a "TAINAINFORMACIA".

Implementacja

Szachownica Polibiusza

Pierwszą zasadniczą funkcją potrzebną do poprawnego działania programu jest napisanie funkcji utworzSzachownice(), która pozwoli na wygenerowanie szachownicy Polibiusza na podstawie podanego słowa klucz.

C++
C#
  1. string utworzSzachownice(string klucz) {
  2.   string alfabet = "";
  3.   for (int i = 0; klucz[i]; i++) {
  4.     char c = klucz[i];
  5.     if (c == 'J')
  6.       c = 'I';
  7.     if (alfabet.find(c) == string::npos)
  8.       alfabet += c;
  9.   }
  10.   for (int i = 'A'; i <= 'Z'; i++) {
  11.     if (i != 'J' && alfabet.find(i) == string::npos) {
  12.       alfabet += (char)(i);
  13.     }
  14.   }
  15.   string szachownica(alfabet);
  16.   int n = 5, x = 0, y = 0;
  17.   int left = 0, right = n - 1, top = 0, bottom = n - 1;
  18.   int przesx = 1, przesy = 0;
  19.   for (int i = 0; i < alfabet.length(); i++) {
  20.     szachownica[y + n * x] = alfabet[i];
  21.     move(x, y, przesx, przesy, left, right, top, bottom);
  22.   }
  23.   return szachownica;
  24. }

Na początek (2.) deklarowana jest zmienna do przechowywania utworzonego alfabetu. Potem (3. - 9.) z podanego słowa klucz wybieranego są kolejne unikalne litery z uwzględnieniem faktu, że jak trafimy na J to jest to I. Potem (10. - 14.) alfabet jest uzupełniany pozostałymi literami z alfabetu łacińskiego. (15.) Szachownica będzie przechowywana jako tekst. Początkowo przypisywana jest wartość zmiennej alfabet (praktycznie chodzi o to by szachownica miała taką samą długość jak alfabet). Po (16. - 23.) transpozycji elementów (24.) zwracana jest szachownica.

Strategia dokonywania transpozycji polega na tym, aby na bieżąco przechowywać aktualną pozycję zapisu (x, y), jej przesunięcie (przesx, przesy) oraz wymiary ograniczeń (lewy, prawy, gora, dol). Początkowo ograniczenia wskazują kolejno na pierwszą kolumnę i ostatnią, pierwszy wiersz i ostatni. Potem w momencie, gdy dojdzie do odbicia w prawo podczas zapisu to ograniczenia będą odpowiednio modyfikowane. Poniższy kod umożliwia przesuwanie miejsca zapisu po spirali:

C++
C#
  1. void move(int &x, int &y, int &przesx, int &przesy, int &lewy, int &prawy, int &gora, int &dol) {
  2.   if (x == lewy && przesx == -1) {
  3.     dol--;
  4.     przesx = 0;
  5.     przesy = -1;
  6.   } else if (y == gora && przesy == -1) {
  7.     lewy++;
  8.     przesx = 1;
  9.     przesy = 0;
  10.   } else if (x == prawy && przesx == 1) {
  11.     gora++;
  12.     przesx = 0;
  13.     przesy = 1;
  14.   } else if (y == dol && przesy == 1) {
  15.     prawy--;
  16.     przesx = -1;
  17.     przesy = 0;
  18.   }
  19.   x += przesx;
  20.   y += przesy;
  21. }
Podobne rozwiązanie zostało zastosowane w szyfrze Ślimakowym.

Szyfrowanie danych

Funkcja szyfrująca przyjmuje dwa argumenty: tekst - tekst jawny do zaszyfrowania oraz klucz - słowo klucz użyte do utworzenia szachownicy.

C++
C#
  1. string szyfruj(string tekst, string klucz) {
  2.   string szachownica = utworzSzachownice(klucz);
  3.   int* dane = new int[tekst.length() * 2];
  4.   for (int i = 0; i < tekst.length(); i++) {
  5.     char c = tekst[i];
  6.     if (c == 'J') c = 'I';
  7.     int pos = szachownica.find(c);
  8.     dane[i] = pos % 5;
  9.     dane[i + tekst.length()] = pos / 5;
  10.   }
  11.   string wynik = "";
  12.   for (int i = 0; i < 2 * tekst.length(); i += 2)
  13.     wynik += szachownica[dane[i] + dane[i + 1] * 5];
  14.   delete dane;
  15.   return wynik;
  16. }

(2.) Na początku należy utworzyć szachownice oraz (3.) zaalokować miejsce pod wartości współrzędnych. Potem (4. - 10.) dla każdej litery znajdź pozycję w szachownicy i na jej podstawie wylicz wiersz oraz kolumne. Potem (11.) utwórz wynik i (12. - 13.) przetłumacz kolejne pary liczb na znaki z szachownicy. (14.) Dealokuj niepotrzebną pamięć i (15.) zwróć wynik.

Rozszyfrowanie danych

Funkcja deszyfrująca działa analogicznie do funkcji szyfruj i przyjmuje dwa argumenty: tekst - szyfrogram do rozszyfrowania oraz klucz - słowo klucz użyte do utworzenia szachownicy.

C++
C#
  1. string rozszyfruj(string tekst, string klucz) {
  2.   string szachownica = utworzSzachownice(klucz);
  3.   int* dane = new int[tekst.length() * 2];
  4.   for (int i = 0; i < tekst.length(); i++) {
  5.     int pos = szachownica.find(tekst[i]);
  6.     dane[2 * i] = pos % 5;
  7.     dane[2 * i + 1] = pos / 5;
  8.   }
  9.   string wynik = "";
  10.   for (int i = 0; i < tekst.length(); i++)
  11.     wynik += szachownica[dane[i] + dane[i + tekst.length()] * 5];
  12.   delete dane;
  13.   return wynik;
  14. }

Testowanie funkcji

W celu przestowania działania napisanych funkcji szyfrującej i rozszyfrującej można skorzystać z poniższego fragmentu kodu:

C++
C#
  1. int main() {
  2.   string klucz, tekstJawny, szyfrogram;
  3.   cout << "Podaj slowo klucz:\n";
  4.   std::getline(std::cin, klucz);
  5.   cout << "Podaj tekst jawny:\n";
  6.   std::getline(std::cin, tekstJawny);
  7.   szyfrogram = szyfruj(tekstJawny, klucz);
  8.   cout << "Szyfrogram to:\n" << szyfrogram << endl;
  9.   tekstJawny = rozszyfruj(szyfrogram, klucz);
  10.   cout << "Rozszyfrowany szyfrogram to:\n" << tekstJawny << endl;
  11.   system("pause");
  12.   return 0;
  13. }
Zadania
Zadanie 1
Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1