Szyfr Bazeries wykorzystuje do szyfrowanie dwa szachownice Polibiusza oraz klucz liczbę. Pierwsza z szachownic powstaje na podstawie alfabetu. Wybrany alfabet do szyfrowania (maksymalnie 25 znaków) należy wpisać pionowo do kolejnych kolumn. Z reguły w szyfrze Bazeries łączy się znaki I oraz J do I. Druga szachownica powstaje na podstawie klucza liczby zapisanego słownie. Do kolejnych pól kwadratu wpisywane są kolejne nie występujące wcześniej w zapisie słownym litery. Pozostałe wolne pola należy uzupełnić kolejnymi literami alfabetu, które jeszcze nie zostały wykorzystane. Dodatkowym zabezpieczeniem jest dokonanie transpozycji tekstu. Mianowicie z klucza pobierane są kolejne cyfry (c1, c2,.., cn) w sposób cykliczny. Następnie każde kolejne ck zostaje transponowane wspak.
Przypuśćmy, że do zaszyfrowania jest tekst "DANE DO ZASZYFROWANIA" przy pomocy klucza liczby 312, który w zapisie słownym to "TRZYSTA DWANASCIE" (polskie znaki są usuwane). Wtedy do szyfrowania zostaną użyte następujące szachownice Polibiusza:
|
|
I etap szyfrowania polega na zastąpieniu znaków tekstu jawnego w szachownicy "Alfabet" na ich odpowiedniki w szachownicy "Liczba". W ten sposób powstaje wstępny szyfrogram "HTBP HL XTFXORNLCTBKT". Teraz należy podzielić tekst na grupy zgodnie z kluczem co ilustruje tabelka:
Klucz | 3 | 1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3 |
---|---|---|---|---|---|---|---|---|---|---|
Wstępny szyfrogram | HTB | P | H | L X | T | FX | ORN | L | CT | BKT |
Szyfrogram | BTH | P | H | X L | T | XF | NRO | L | TC | TKB |
Ostatecznie szyfrogram przyjmuje postać "BTHPH X LTXFNROLTCTKB". W celu odszyfrowania należy odwrotnie przyjąć szachownice. Transponowanie można zrobić po lub przez zamianą według szachownic.
Zamieszczony niżej kod zakłada poprawność danych wejściowych. Tekst jawny oraz liczba słownie powinna być zapisany wielkimi literami, ale można używać innych znaków (błędne znaki zostaną usunięte lub nie zamienione). Klucz liczba powinien być złożony z samych cyfr.
Ze względu na fakt, że dopuszczone zostały znaki inne niż litery to przyda się funkcja isLetter(), która stwierdzi czy podany znak c jest dużą literą.
Do wyszukiwania danych w tekście można skorzystać z funkcji find(), która przyjmuje trzy argumenty: data - tekst w którym szukany jest znak c, c - znak do wyszukiwania oraz max_i - ile pierwszych znaków ma być sprawdzonych pod kątem wyszukiwania znaku c.
W celu uproszczenia kodu dopisane zostało krótkie przeciążenie funkcji find(), które w przypadku nie podania argumentu max_i przyjmuje, że znak c ma zostać wyszukiwany w całej tablicy znaków data.
Istnieje możliwość przechowywania szachownicy w tablicy dwuwymiarowej, ale zdecydowanie wygodniej będzie wykorzystać do tego celu tablicy jednowymiarowej. Funkcja squareAlphabet() zwraca szachownicę "Alfabet" zapisaną jak ciąg znaków tak jakby odczytywać szachownice wiersz po wierszu.
W trakcie uzupełniania tablicy znaków należy pamiętać, że (5.) znak J powinien zostać pominięty.
Tworzenie szachownicy na podstawie tekstu jest o wiele bardziej intuicyjne niż tworzenie szachownicy alfabetu, ponieważ nie trzeba zapisywać danych pionowo w kolumnach. Funkcja squareNumber() jako argument przyjmuje data - liczba zapisana słownie.
(2.) Deklaracja tablicy znaków i (3.) indeksu zapisu kolejnego znaku. (4.) Dla każdego znaku w data: (5.) sprawdź czy dany znak jest literą i jeśli tak to czy nie występuje w szachownicy. Jeśli oba warunki są spełnione to (6.) dopisz i-ty do szachownicy. Po zakończeniu przepisywania może okazać się, że pozostały wolne miejsca.
Pozostałe pola powinny zostać uzupełnione kolejnymi literami alfabetu. Z tego powodu (9.) dla każdego znaku w alfabecie: (10.) o ile nie jest literą J i nie występuje jeszcze w szachownicy to (11.) zostaje do niej dopisany. Na koniec (14.) można dopisać znak końca danych i (15.) zwróć wskaźnik na szachownice.
Transponowanie odbywa się poprzez wywołanie funkcji transpose(), która przyjmuje dwa argumenty: data - tekst do transpozycji oraz key - liczba zapisana jako tekst. Funkcja zwraca wskaźnik na nową pozycję w pamięci.
Pobierz (2.) długość tekstu jawnego oraz (3.) klucza. Potem (4.) alokuj pamięć pod tekst wynikowy. (5.) Rozpocznij transpozycję od znaku o indeksie i = 0 i od pierwszej cyfry klucza liczby k = 0. Kontynuuj wykonywanie dopóki są znaki do przepisania. (6.) Pobierz ile znaków zgrupować i (7.) sprawdź czy jest to możliwe. Jeśli nie to (8.) zmniejsz rozmiar grupy. Następnie (7. - 8.) przepisz odwracają wybraną grupę znaków. (9.) Wskaż ile znaków zostało dopisanych i (10.) wskaż, która cyfra określa rozmiar grupy w następnej iteracji. Na koniec (11.) dopisz znak końca danych i (12.) zwróć tekst wynikowy txt.
Funkcja change() zamienia znaki tekstu data na podstawie podanych szachownic squareA i squareB. Dane są szyfrowane poprzez znajdowanie odpowiedników znaków w szachownicy squareA w szachownicy squareB.
(3.) Należy tutaj pamiętać, że w szyfrowanym tekście mogą występować znaki inne niż litery. Należy ich wtedy nie modyfikować.
Do zaszyfrowania danych służy funkcja cipher(), która przyjmuje trzy argumenty: data - tekst jawny, number - liczba zapisana jako ciąg znaków oraz spelledNumber - liczba zapisana słownie.
(2. - 3.) Utwórz szachownice i (4.) utwórz wstępny, transponowany szyfrogram, a następnie (5.) go zaszyfruj. Usuń (6.) zbędne szachownice, a na koniec (7.) zwróć wskaźnik na szyfrogram.
Deszyfrowanie różni się jedynie sposobem podania szachownic do szyfrowania.
Poniższa funkcja main() wczyta od użytkownika dane, wypisze szyfrogram oraz rozszyfrowany szyfrogram.
Napisz wersję programu, która znajdzie pierwszą literę w alfabecie, który nie występuje w tekście jawnym. W przypadku, gdy taki znak nie istnieje funkcja powinna wypisać odpowiedni komunikat.
Przykładowo dla danych:
wykluczonym znakiem z alfabetu jest litera B, a prawidłowym, wypisanym szyfrogramem jest: