Szyfr Trifid został opracowany przez francuza Felixa Delastelle. Na tle innych szyfrów wyróżnia się faktem, że klucz użyty do szyfrowania można przedstawić jako sześcian podzielony na 27 małych sześcianów. Technika szyfrowania korzysta również z grupowania znaków i ich transpozycji. Z tego powodu szyfr ten jest odporny na większość standardowych sposobów łamania szyfrów.
Podczas szyfrowania na początku należy ustalić klucz, który będzie znany zarówno nadawcy i odbiorcy. Większość metod szyfrowania korzysta z dwuwymiarowej tablicy 5x5. Jednak taki zabieg powodował zamianę jednego znaku alfabetu na jeden z możliwych do zaszyfrowania (zwykle j na i). Klucz w szyfrze Trifid to sześcian 3x3x3, więc mieści się tam cały alfabet oraz np. dodatkowy znak przestankowy. Oryginalnie jest to kropka, ale lepszym pomysłem wydaje się znak przerwy.
Ze względu na fakt, że ciężko byłoby odczytywać dane z sześcianu to klucz można przechować jako ciąg znaków, który później można zamienić na trzy tablice reprezentujące kolejne warstwy sześcianu. Na potrzeby przykładu za klucz zostanie przyjęte RNXBJSGLUAQ.MTPYCEKVFOZHDWI. Na podstawie zapisu klucza można utworzyć odpowiednie tablice:
|
|
|
Ze względu na fakt, że można interpretować ciąg znaków dowolnie zdecydowanie lepszym pomysłem jest wymiana wypełnionych tabelek.
W celu wykorzystania kilku metod szyfrowania w jednej wymusza podania prócz klucz liczby, która będzie oznaczać okresowość. Może być to dowolna liczba. Oznacza ona po ile znaków będzie w każdej szyfrowanej grupie. W przykładzie okresowość zostanie ustalona na 4.
Podczas szyfrowania każdy z znaków ma swój kod na który składa się numer warstwy, numer wiersza, a na końcu numer kolumny. Przykładowo dla podanego wyżej klucza symbol Y ma kod 231. Pierwszy krok podczas szyfrowania tekstu polega na zapisaniu pod każdą literą ich kodów w pionowych słupkach. Wypisywane kolumny najlepiej grupować po tyle elementów jaką wartość ma okresowość. W tym przypadku zgodnie z założeniem kolumny będą grupowane po 4. Szyfrując tekst TRIFID otrzymamy taką tabelkę:
Znak | I | N | F | O | R | M | A | C | J | A | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Warstwa | 3 | 2 | 3 | 3 | 1 | 2 | 2 | 2 | 1 | 2 | ||
Wiersz | 3 | 2 | 1 | 2 | 1 | 2 | 1 | 3 | 2 | 1 | ||
Kolumna | 3 | 1 | 3 | 1 | 1 | 1 | 1 | 2 | 2 | 1 |
Kolejny krok polega na tym, aby dla każdej z grup zapisać wszystkie numerki kodów jako ciąg znaków odczytując kolejne wiersze. Przykładowo dla grupy znaków INFO będzie to 323332123131. Następnie taki kod rozdziela się na grupy znaków po 3: 323 332 123 131, a potem każda z grup jest zamieniana na znak, który dany kod reprezentuje. Dla grupy, która ma mniej znaków niż wynosi okresowość zasada pozostaje taka sama. W celu lepszego zrozumienia zamianę przedstawia poniższa tabelka:
Warstwa | 3 | 3 | 1 | 1 | 1 | 2 | 1 | 1 | 1 | 1 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Wiersz | 2 | 3 | 2 | 3 | 2 | 1 | 3 | 1 | 2 | 2 | ||
Kolumna | 3 | 2 | 3 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | ||
Znak | F | D | S | Y | J | Q | G | N | J | B |
Ostatecznie szyfrogram to FDSYJQGNJB.
W procesie deszyfrowania wykonuje się dokładnie te same kroki co podczas szyfrowania. Różnica tkwi podczas tworzenia "transpozycji", ponieważ należy wtedy odczytany ciąg cyfr zamienić na grupy mające po tyle cyfr ile wynosi okresowość, aby odczytać pionowo kody liter tekstu jawnego.
Poniższa implementacja jest przykładowa, dlatego pozwala ona na wprowadzenie dowolnej tablicy, okresowości i tekstu do zaszyfrowania. Należy jednak pamiętać, że tekst musi mieć długość, która jest wielokrotnością okresowości. W innym przypadku nie zostanie zaszyfrowany cały tekst. Ponadto istnieje założenie, że wprowadzony tekst składa się jedynie ze znaków występujących w wprowadzonym kluczu.
Wielkość tablicy zostanie wykorzystana w kodzie niejeden raz, dlatego została utworzona stała keyN, której zostanie przypisana wartość 3. Taki zabieg pozwoli na dalszy rozwój implementacji.
Ze względu na fakt, że wprowadzony klucz będzie przechowywany jako tekst to będzie potrzebna funkcja, która wyszuka w nim konkretną wartość i zwróci odpowiednią pozycję. Zadanie to realizuje funkcja findChar(), która dla danego ciągu key i znaku c zwraca pozycję znaku c w key.
Dokładniejsze przyjrzenie się kodom znaków wskazuje, że jeśli kod potraktować jako liczbę w systemie trójkowym to k-ty znak kodu można wyodrębnić z pozycji znaku na liście. Funkcja getPosition() zwraca dla danej liczby a cyfrę, która stoi na pozycji st + 1 od prawej strony w zapisie trójkowym liczby a.
Funkcja szyfrująca cipher() przyjmuje trzy argumenty: txt - tekst do zaszyfrowania, key - klucz szyfrujący tekst oraz period - okresowość grupowania.
(2.) Pobierz długość tekstu i (3.) wylicz ile będzie grup do zaszyfrowania. (4.) Zaalokuj pamięć pod wynik. (5.) Dla każdej grupy i (6.) każdego znaku w grupie (7.) ustal pozycję znaku wynikowego na 0. (8.) Dla każdej cyfry kodującej zaszyfrowany znak pobierz odpowiednie cyfry z znaków tekstu jawnego. (9.) Dopisz znak na listę wynikową. (12.) Dopisz znak końca danych i (13.) zwróć wynik.
Funkcja deszyfrująca decipher() różni się od funkcji szyfrującej tylko sposobem (9.) wyboru jaki znak ma zostać dopisany do wyniku.
Powyższe funkcje można przetestować przy pomocy poniższej funkcji main(), która poprosi o podanie danych, a następnie wypisze szyfrogram oraz rozkodowany szyfrogram na ekran: