Szyfr Tabelka polega na zamianie każdego znaku w tekście jawnym na pary cyfr. Przed szyfrowaniem ustalamy klucz - tabelkę. Tabelkę tworzy się wypisując jako nagłówki wszystkie cyfry parzyste, a jako nagłówki kolumn cyfry nieparzyste. Każde pole z 25 w tabelce wpisujemy jeden znak. Potem przy szyfrowaniu znaku szukamy go w tabelce i odczytujemy nagłówek wiersza oraz kolumny. Teksty nagłówków zapisane koło siebie tworzą parę cyfr, która odpowiada znakowi do zaszyfrowania. Przyjmując, że nagłówek kolumny to y, a nagłówek wiersza to x to dany znak możemy zaszyfrować na dwa sposoby: jako xy lub yx.
Weźmy przykładowo tabelkę 5x5, którą wypełnimy znakami alfabetu łacińskiego (z alfabetu pomijamy literę V):
x | 1 | 3 | 5 | 7 | 9 |
0 | A | B | C | D | E |
2 | F | G | H | I | J |
4 | K | L | M | N | O |
6 | P | Q | R | S | T |
8 | U | W | X | Y | Z |
Spróbujmy teraz zaszyfrować wyraz INFORMACJA. Szukamy I. Mamy w kolumnie 4, wierszu 2. Pobieramy kolejno nagłówki: 7 i 2. Zapisujemy to jako 72 lub 27. Kolejność nie ma tu znaczenia, ponieważ w tabelce obie współrzędne pozwolą prawidłowo rozszyfrować tekst. Szyfrujemy dalej N: 74, F: 12, O: 49, R: 56, M: 54, A: 10, C: 50, J: 92, A: 01 - A występuje tutaj drugi raz, więc możemy zapisać liczbę na drugi sposób, aby trudniej było go złamać. Oczywiście ma to sens jeśli ktoś nie będzie wiedział, że używamy szyfru tabelki. Wszystkie cyfry zapisujemy koło siebie i uzyskujemy np. 27741249565410509201.
Podczas rozszyfrowania należy pamiętać, że bierzemy po dwie kolejne cyfry, które nie oznaczają pozycji, a nagłówki tabelki, więc rozszyfrowując: bierzemy kolejno 27 i odczytujemy, że to 2 wiersz i 4 kolumna. Co jeśli byśmy mieli liczbę 72? Zamieniamy je miejscami. Możemy to zrobić, ponieważ cyfry parzyste są nagłówkami wierszy, a nieparzyste kolumn.
Napisz program, który na wejściu otrzyma tabelkę 5x5 oraz 5 linii po 5 znaków rozdzielonych spacjami, które będą tworzyły tabelkę. Zakładamy, że i-ty wiersz ma nagłówek 2·(i - 1), a j-ta kolumna ma nagłówek 2·j - 1. Szósta linijka to tekst zaszyfrowany złożony tylko ze znaków, wprowadzonych do tabelki. Na wyjście powinien zostać wypisany zaszyfrowany tekst zgodnie z szyfrowaniem Tabelka. Przykładowo dla wejścia:
Funkcja findChar() pomoże znaleźć określony znak w tabelce i zwróci zaszyfrowany tekst.
(2.) Alokujemy bufor do którego zapiszemy nagłówki tabeli. Nie ma tutaj potrzeby na dodawanie znaku końca ciągu - wiemy, że zaszyfrowany znak jest reprezentowany przez dwuznakowy wyraz. (3.) Dla każdego wiersza i (4.) każdego znaku (5.) sprawdzamy gdzie jest nasz szukany znak look. Kiedy go znajdziemy: (6., 7.) ustalamy bufor na odpowiednie wartości i (8.)go zwracamy. Jeśli nie znajdziemy znaku to przejdziemy do linijki (12). Nie ustalamy żadnej wartości bufora, ponieważ nie powinniśmy się znaleźć w tym miejscu zgodnie z wytycznymi zadania.
Główna funkcja cipher() będzie kontrolować funkcję findChar() i zapisywać jej wyniki tworząc zaszyfrowany tekst:
(1.) Funkcja przyjmuje tekst do zaszyfrowania, tabelkę oraz jej wymiary. cipher() zwróci wskaźnik na zaszyfrowany tekst. (2.) Wyliczamy długość tekstu wynikowego i (3.) alokujemy odpowiednio dużo pamięci. (4.) Dla każdego znaku wywołujemy funkcję findChar() i odczytujemy bufor. (4., 5.) Na odpowiednie pozycje przepisujemy bufor i (6.) go usuwamy. (8.) Dopisujemy znak końca tekstu zaszyfrowanego i (9.) zwracamy wynik.
Do deszyfrowania stworzymy funkcję pomocniczą getChar(), która pozwoli na uzyskanie odpowiedniego znaku z tabeli:
(1.) Możemy szyfrować znak na dwa sposoby, więc jeśli pierwsza "współrzędna" nie jest parzysta to zamieniamy je miejscami. (2.) zwracamy znak na prawdziwej pozycji.
Funkcja deszyfrująca jest prostsza niż szyfrująca. Zakładamy poprawność wprowadzonej tabelki i nie sprawdzamy czy nie będziemy pobierać znaków poza tabelką, więc nie potrzebujemy znać jej wielkości.
(2.) Wyliczamy długość. (3.) Alokujemy pamięć pod wynik. (4.) Dla każdej pary znaków pobieramy odpowiedni znak z tabeli odczytując go przy pomocy: getChar(). (5.) Dodajemy znak końca linii i (6.) zwracamy wynik.
Poniższa funkcja sprawdza szyfrowanie i odszyfrowywanie na podstawie wprowadzonego klucza oraz tekstu.
Zmodyfikuj kod, aby program losowo wybierał czy odczytane pary liczb szyfrujących będą zapisane w postaci (x, y) czy (y, x).
Zmodyfikuj funkcję, aby:
otrzymujemy: