Strona główna » Algorytmy » Szyfry » Szyfr Wężyk

Szyfr Wężyk

O szyfrze

Szyfrowanie polega na zapisie tekstu jawnego w postaci węża, a następnie odczytanie każdej linijki po kolei. Węża tworzymy zapisując pierwszą literę w dolnej linijce. Następną linijkę wyżej. Następną też, ale dwie kolejno o linijkę niżej. Przepisywanie powtarzamy, aż przepiszemy wszystkie litery.

Weźmy przykładowo wyrażenie TAJNA INFORMACJA i zapiszmy w postaci "węża":

  1.   J   N   M   A
  2.  A N I F R A J
  3. T   A   O   C

Wszystkie znaki interpunkcyjne oraz spacje usuwamy. Po odpowiednim zapisaniu możemy odczytać szyfrogram - odczytujemy kolejne linijki "węża": JNMA ANIFRAJ TAOC.

Chcąc odszyfrować nasz tekst należy pamiętać, że pierwsza litera jest w ostatnim wyrazie i znajduje się w lewym dolnym rogu. Kolejna litera leży w drugim wyrazie, trzecia w pierwszym, czwarta w drugim itd.

Zadanie 1

Spróbujemy teraz napisać funkcję, która zaszyfruje wprowadzony tekst i go wypisze na ekran. Przykładowo dla tekstu:

  1. SZYFR WEZYK

otrzymamy szyfrogram:

  1. YE ZFWZK SRY

Przed szyfrowaniem

Napiszemy na początek funkcję ifLetter(), która będzie sprawdzać czy dany znak jest literą. Pozwoli to nam napisać bardziej elegancki kod i zwiększy przejrzystość do ewentualnego testowania:

  1. bool ifLetter(char c){
  2.   return ((c>='a'&&c<='z') || (c>='A'&&c<='Z'));
  3. }

(2.) Zwracamy wynik sprawdzania odpowiednich zakresów.

Szyfrowanie

Nasza funkcja przyjmie tylko jeden argument txt, który będzie przechowywał tekst do zaszyfrowania:

  1. char* cipher(const char* txt){
  2.   int dl = 0;
  3.   char* temp = new char[strlen(txt)];
  4.   for(int i = 0; txt[i]; i++)
  5.     if(ifLetter(txt[i]))
  6.       temp[dl++] = txt[i];

(2.) Ustalamy długość tekstu dl wynikowego na 0. (3.) Stworzymy najpierw łańcuch znaków, który nie będzie zawierał żadnych spacji, znaków interpunkcyjnych oraz cyfr. (4.) Dla każdego znaku w tekście jawnym: (5.) sprawdzamy czy dany znak jest literą i jeśli tak jest to (6.) przepisujemy ten znak do tablicy tymczasowej i zwiększamy długość tekstu wynikowego.

  1.   char* wynik = new char[dl + 3];
  2.   int j = 0;
  3.   for(int i = 2; i < dl; i+=4) wynik[j++]=temp[i];
  4.   wynik[j++]=' ';
  5.   for(int i = 1; i < dl; i+=2) wynik[j++]=temp[i];
  6.   wynik[j++]=' ';
  7.   for(int i = 0; i < dl; i+=4) wynik[j++]=temp[i];
  8.   wynik[j++]=' ';
  9.   wynik[dl+2]='\0';
  10.   return wynik;
  11. }

(7.) Alokujemy pamięć pod tekst wynikowy. Zauważmy teraz, że pierwsza linijka węża to co czwarty znak począwszy od drugiego. Druga linijka to co drugi znak począwszy od drugiego znaku w tekście jawnym, a ostatnia linijka to co czwarty znak począwszy od pierwszego. Przepisywanie kolejnych linijek przeprowadzamy w linijkach (9. - 14.). (8.) Zmienna j pamięta, który znak tekstu tymczasowego przeglądamy, a następnie (9.) przepisujemy odpowiednio znaki pamiętając, że (10.) po każdej linijce dopisujemy znak przerwy - spacje. (15.) Dopisujemy na odpowiednim miejscu znak \0 i (16.) zwracamy wynik.

Deszyfrowanie

Podczas deszyfrowania zastosujemy metodę, którą szyfrowaliśmy:

  1. char* decipher(const char* txt){
  2.   char* wynik = new char[strlen(txt) - 1];
  3.   int j = 0;
  4.   for(int i = 2; txt[j]!=' '; j++){
  5.     wynik[i]=txt[j];
  6.     i+=4;
  7.   }
  8.   j++;
  9.   for(int i = 1;txt[j]!=' '; j++){
  10.     wynik[i]=txt[j];
  11.     i+=2;
  12.   }
  13.   j++;
  14.   for(int i = 0;txt[j]; j++){
  15.     wynik[i]=txt[j];
  16.     i+=4;
  17.   }
  18.   j++;
  19.   wynik[strlen(txt) - 2]='\0';
  20.   return wynik;
  21. }

Każdą linijkę odpowiednio rozszyfrowujemy. Warto zauważyć, że w tekście wynikowym nie ma spacji, ani znaków interpunkcyjnych, którymi musimy się przejmować.

Testowanie funkcji

Poniższa funkcja main() pozwala przetestować napisane funkcje:

  1. int main () {
  2.   char* txt = new char[128];
  3.   cin.getline(txt, 128);
  4.   char* txtc = cipher(txt);
  5.   cout << txtc << endl;
  6.   char* txtd = decipher(txtc);
  7.   cout << txtd << endl;
  8.   delete[] txt, txtc, txtd;
  9.   system("pause");
  10.   return 0;
  11. }

Zadania

Zadanie 1

Zmodyfikuj kod, aby wężyk nie zaczynał się od ostatniej, a od pierwszej linijki oraz, żeby można było szyfrować cyfry.

Przykładowo wężyk wyglądałby tak:

  1. S   R   Y   1
  2.  Z F W Z K 0 6
  3.   Y   E   2

Przykładowo dla danych:

  1. SZYFR WEZYK 2016

otrzymamy:

  1. SRY1 ZFWZK06 YE2