Strona główna » Algorytmy » Szyfry » Szyfr Kodowana zamiana
 

Szyfr Kodowana zamiana

Opis szyfru

Szyfr Kodowana zamiana szyfruje poprzez zamianę odpowiednich par znaków na podstawie klucza. Klucz używany do szyfrowania to lista liczb dodatnich. (Istnieje możliwość dopuszczenia liczb ujemnych.) Szyfrowanie polega na tym, że dla każdego znaku jest wykonywana zamiana jego razem z znakiem położonym k pozycji dalej. k jest to i-ta liczba pobrana z klucza. W związku z tym, że pobierana wartość z klucza może nie istnieć to należy pobrać wtedy wartość k mod długość klucza. Podobnie należy postępować podczas zamiany, gdy nie istnieje pozycja i + k należy zamienić i-ty znak z i + k mod długość tekstu.

Przykład

Szyfrowanie

Przykładowo weźmy tekst INFORMACJA oraz klucz [1, 2, 3]. Wtedy kolejno należy dokonać następujących zamian:

PozycjaZnak 1KluczZnak 2Po zamianie
----INFORMACJA
1I1NNIFORMACJA
2I2ONOFIRMACJA
3F3MNOMIRFACJA
4I1RNOMRIFACJA
5I2ANOMRAFICJA
6F3JNOMRAJICFA
7I1CNOMRAJCIFA
8I2ANOMRAJCAFI
9F3ONFMRAJCAOI
10I1NIFMRAJCAON

Po zaszyfrowaniu szyfrogram to: IFMRAJCAON.

Deszyfrowanie

Proces deszyfrowania jest odwrotnością procesu szyfrowania. Należy dokonać tych samych operacji zamian, ale zaczynają od ostatniego znaku:

PozycjaZnak 1KluczZnak 2Po zamianie
10N1IIFMRAJCAON
9O3FNFMRAJCAOI
8A2INOMRAJCAFI
7C1INOMRAJCIFA
6J3FNOMRAJICFA
5A2INOMRAFICJA
4R1INOMRIFACJA
3M3FNOMIRFACJA
2O2INOFIRMACJA
1N1INIFORMACJA
----INFORMACJA

Tekst został prawidłowo rozszyfrowany: INFORMACJA.

Implementacja

Zamiana

Ze względu na fakt, że zamiana znaków przyda się podczas szyfrowania i deszyfrowania to warto napisać funkcję swapChar(), która przyjmie dwa wskaźniki i zamieni wartości znajdujące się pod tymi adresami:

  1. void swapChar(char& c1, char& c2) {
  2.   char ct = c1;
  3.   c1 = c2;
  4.   c2 = ct;
  5. }

Szyfrowanie

Funkcja szyfrująca cipher() przyjmuje trzy argumenty: txt - tekst do zaszyfrowania, key - lista liczb klucza oraz keyl - długość klucza.

  1. char* cipher(char* txt, int* key, int keyl) {
  2.   int dl = strlen(txt);
  3.   char* txtc = new char[dl + 1];
  4.   for (int i = 0; txt[i - 1]; i++)
  5.     txtc[i] = txt[i];
  6.   for (int i = 0; txt[i]; i++)
  7.     swapChar(txtc[i], txtc[(i + key[i % keyl]) % dl]);
  8.   return txtc;
  9. }

(2.) Pobierz długość tekstu. (3. - 5.) Skopiuj tekst do nowego miejsca w pamięci. (6.) Dla każdego kolejnego znaku: (7.) dokonaj odpowiedniej zamiany. (8.) Zwróć szyfrogram.

Deszyfrowanie

Funkcja deszyfrująca decipher() przyjmuje trzy argumenty: txt - tekst do rozszyfrowania, key - lista liczb klucza oraz keyl - długość klucza.

  1. char* decipher(char* txt, int* key, int keyl) {
  2.   int dl = strlen(txt);
  3.   char* txtd = new char[dl + 1];
  4.   for (int i = 0; txt[i - 1]; i++)
  5.     txtd[i] = txt[i];
  6.   for (int i = dl - 1; i >= 0; i--)
  7.     swapChar(txtd[i], txtd[(i + key[i % keyl] + dl) % dl]);
  8.   return txtd;
  9. }

(2.) Pobierz długość tekstu. (3. - 5.) Skopiuj tekst do nowego miejsca w pamięci. (6.) Dla każdego kolejnego znaku: (7.) dokonaj odpowiedniej zamiany. Warto tutaj zwrócić uwagę na fakt, że podczas wyliczania znaku do zamiany może wyjść liczba ujemna, dlatego należy dodać długość tekstu do wyliczonej wartości i + k i pobrać resztę z dzielenie przez długość klucza. (8.) Zwróć tekst jawny.

Testowanie funkcji

Poniższa funkcja main() pozwala przetestować działanie programu. Na początku należy podać długość klucza, listę liczba oraz tekst do zaszyfrowania. Następnie program wypisze na ekran szyfrogram oraz tekst jawny uzyskane przy pomocy napisanych funkcji.

  1. int main () {
  2.   int n;
  3.   cout << "Podaj dlugosc klucza: ";
  4.   cin >> n;
  5.   cout << "Podaj " << n << " elementow klucza:\n";
  6.   int* key = new int[n];
  7.   for (int i = 0; i < n; i++)
  8.     cin >> key[i];
  9.   char* txt = new char[512];
  10.   cout << "Podaj tekst do zaszyfrowania:\n";
  11.   cin.ignore();
  12.   cin.getline(txt, 512);
  13.   char* txtc = cipher(txt, key, n);
  14.   cout << "\nszyfrogram: " << txtc << endl;
  15.   char* txtd = decipher(txtc, key, n);
  16.   cout << "tekst jawny: " << txtd << endl;
  17.   delete[] txt, txtc, txtd;
  18.   system("pause");
  19.   return 0;
  20. }

Zadania

Zadanie 1

Zmodyfikuj kod źródłowy implementacji tak, aby można było wprowadzić do klucza zarówno wartości dodatnie jak i ujemne. Przykładowo dla słowa INFORMACJA oraz klucza [1 -2 3 -4] program powinien wypisać:

  1. NAMCFIOJAR