Strona główna » Algorytmy » Szyfry » Szyfrowanie kluczem
 

Szyfrowanie kluczem

Zadanie

Napisz aplikację, która wczyta tekst do zaszyfrowania oraz klucz. Tekst i klucz składa się wyłącznie z dużych liter alfabetu łacińskiego, spacji, myślników i liczb. Tekst powinien zostać zaszyfrowany przy pomocy specjalnego hasła.

Hasło tworzy się przy pomocy klucza. Z klucza usuwamy wszystkie znaki nie będące literami oraz znaki, które mają już odpowiednik w części wyrazu przed dana literą czyli klucz TEST KLUCZA zostanie zamieniony na TESKLUCZA. Hasło jest uzupełnione przez kolejne litery alfabetu, które nie występują w kluczu. Przykładowo klucz TEST KLUCZA da hasło: TESKLUCZABDFGHIJMNOPQRWVXY.

Szyfrowanie polega na zamianie litery A na pierwszy znak z hasła, literę B na drugi itd...

Przykładowo szyfrując zdanie TEKST DO ZASZYFROWANIA przy pomocy klucza HASLO MASLO otrzymamy:

  1. TOFRT LK RZYMQKWHJDH

Implementacja

Przed główną funkcją

Hasło będzie zawsze zawierać wszystkie litery alfabetu, więc ma stałą długość, którą przechowamy w zmiennej stałej key_length:

  1. const int key_length = 'Z' - 'A' + 1;

Szyfrowanie i deszyfrowanie będzie można wykonać przy pomocy tej samej funkcji. Będzie ona przyjmować dwa łańcuchy znaków z czego jeden będzie tekstem do zaszyfrowania, a drugi hasłem.

  1. void changeTxt(char* text, char* code){
  2.   for(int i = 0; text[i]; i++)
  3.     if(text[i] >= 'A' && text[i] <= 'Z')
  4.       text[i] = code[text[i] - 'A'];
  5. }

(2.) Dla każdego znaku z tekstu, (3.) pod warunkiem, że jest dużą literą, (4.) znajdujemy odpowiedni znak w haśle. Odbywa się to poprzez odjęcia od wybranego znaku znak "A".

Funkcja główna

Prze rozpoczęciem szyfrowania alokujemy pamięć, aby móc wczytać tekst oraz klucz.

  1. int main () {
  2.   char* text = new char[128];
  3.   char* keyword = new char[128];
  4.   char* key = new char[key_length];

(2.) char* text będzie przechowywać tekst do zaszyfrowania. (3.) char* keyword wczyta klucz według, którego powstanie hasło, a (4.) char* key jest to nasz właściwe hasło.

  1.   cin.getline(text,128);
  2.   cin.getline(keyword,128);
  3.   key[key_length - 1] = '\0';

Wczytujemy (5.) tekst oraz (6.) klucz. (7.) W haśle ostatni znak ustawiamy na znak specjalny końca \0. Nie ma to znaczenia na proces ustalania hasła, ale ma na jego wypisywanie na ekran (np. w celach testowych).

  1.   int key_i = 0;
  2.   for(int i = 0; keyword[i]; i++){
  3.     bool dodaj = true;
  4.     if(keyword[i] >= 'A' && keyword[i] <= 'Z'){
  5.       for(int j = 0; j < key_i; j++){
  6.         if(key[j] == keyword[i]){
  7.           dodaj = false;
  8.         }
  9.       }
  10.       if(dodaj){
  11.         key[key_i++] = keyword[i];
  12.       }
  13.     }
  14.   }

Rozpoczynamy proces tworzenia hasła na podstawie klucza. (8.) Zmienna key_i jest zmienną pomocnicza, która podpowiada ile mamy już ustawionych znaków w haśle. (9.) Dla każdego znaku w kluczu: (10.) Zakładamy, że aktualnie sprawdzany znak dodajemy do hasła. (11.) Sprawdzamy czy znak jest literą. Jeśli tak to przechodzimy do (12.), a jeśli nie to znak pomijamy. (12.) Sprawdzamy czy w haśle dotąd ustalonym sprawdzany znak nie występuje. (14.) Jeśli występuje to zmieniamy dodaj na false co oznacza, że nasze przypuszczenie w (10.) było fałszywe i tego znaku nie dodajemy. (18.) Po zakończeniu pętli jeśli mamy dodać to dodajemy i-ty znak do hasła i zwiększamy długość hasła.

  1.   for(int i = 0; i < key_length; i++){
  2.     bool dodaj = true;
  3.     for(int j = 0; j < key_i; j++){
  4.       if(key[j] == 'A' + i){
  5.         dodaj = false;
  6.       }
  7.     }
  8.     if(dodaj){
  9.       key[key_i++] = 'A' + i;
  10.     }
  11.   }

Kolejny krok polega na uzupełnieniu hasła brakującymi literami. Algorytm jest bardzo podobny do (9. - 21.) z tą różnicą, że zamiast sprawdzać kolejne znaki z klucza to sprawdzamy kolejne litery alfabetu.

  1.   changeTxt(text, key);
  2.   cout << text << endl;

Mając już hasło pozostaje jedynie (33.) wywołać funkcję changeTxt() z odpowiednimi argumentami: text i key oraz (34.) wypisać zaszyfrowany tekst na ekran.

  1.   char* key_d = new char[key_length];
  2.   for(int i = 0; i < key_length; i++){
  3.     key_d[key[i] - 'A'] = 'A' + i;
  4.   }

Do deszyfrowania potrzebujemy jednak hasła deszyfrującego, które ma taką samą długość jak hasło. (35.) Deklarujemy nowy łańcuch znaków i (36.) dla każdego znaku z hasła. i-ty znak hasła deszyfrującego wskazuje literę, która była zmieniona przez i-ty znak hasła.

  1.   changeTxt(text, key_d);
  2.   cout << text << endl;
  3.   delete[] text, keyword, key, key_d;
  4.   system("pause");
  5.   return 0;
  6. }

(39.) Wywołujemy ponownie changeTxt() zmieniając hasło na hasło deszyfrujące i (40.) wypisujemy wynik na ekran. (41.) Dealokujemy pamięć, (42.) czekamy na użytkownika i (43.) kończymy program.

Zadania

Zadanie 1

Napisz program o podobnym działaniu, który: