Strona główna » Algorytmy » Szyfry » Świńska Łacina
 

Świńska Łacina

Wstęp

Świńska Łacina to gra językowa powiązana przede wszystkim z językiem angielskim znana również pod nazwą Igpay Atinlay. Nazwa jest myląca, ponieważ nie korzysta ona bezpośrednio z łaciny. W rzeczywistości jest to zbiór zasad, które zamieniają zwykłe angielskie słowa w wyrazy, które brzmią niezrozumiale (jak łacina dla większości ludzi). Jest to prosty sposób na ukrycie wiadomości, ale bardzo łatwy do złamania.

Zasady

Świńska Łacina składa się z zaledwie trzech zasad. Jeśli pierwsza litera szyfrowanego wyrazu to samogłoska to na koniec należy dopisać "way". Jeśli jednak pierwsze są spógłoski (maksymalnie dwie) to należy je przenieść na koniec wyrazu i dopisać końcókę "ay". W zależności od języka zasady te można modyfikować tak, aby wyraz wynikowy było obcobrzmiący.

Przykład

Szyfrując tekst "wyraz" zamieniamy go na "yrazway", ponieważ w przenosimy na koniec i dodajemy "ay". Z kolei dla angielskiego słowa "book" zamiana zwróci "ookbay". Oczywiście należy pamiętać, że nawet jeśli wyraz to "a" to należy go zamianić na "away" (pierwsza litera to samogłoska).

Nazwa

Znając już zasadę szyfrowania wyrazów nietrudno wyjaśnić drugą nazwę pod jaką jest znana ta gra. Spróbujemy teraz dokonać procesu deszyfrowania. Otóż w wyrazach "Igpay Atinlay" możemy usunąć "ay", a następnie przenieść ostatni znak (tj. spółgłoskę) na początek. Otrzymujemy wtedy "Pig Latin" czyli angielską, oryginalną nazwę gry.

Implementacja

Celem implementacji jest napisanie zestawu funkcji, które pozwolą na szyfrowanie oraz deszyfrowanie wyrazów według reguł zasady gry Świńska Łacina. Pisanie kodu najlepiej rozpocząć od napisania funkcji, która sprawdzi czy podany znak to samogłoska czy nie. Zakładamy, że nie używamy polskich znaków, a wyrazy składają się tylko z małych liter alfabetu łacińskiego.

Samogłoska

Funkcja czySamogloska() sprawdza czy podany znak c jest samogłoską. Wynikiem jest wartość logiczna.

  1. static bool czySamogloska(char c) {
  2.   return "aeiou".IndexOf(c) != -1;
  3. }

Szyfrowanie

Poniższa funkcja szyfruj() zwraca podany wyraz zmodyfikowany według zasad rozgrywki. Uwzględnia on warunek, że na koniec może zostać przesunięta nie jedna, a dwie spółgłoski.

  1. static string szyfruj(string wyraz) {
  2.   if (czySamogloska(wyraz[0])) {
  3.     return wyraz + "way";
  4.   } else {
  5.     int ile = 1;
  6.     if (wyraz.Length > 1 && !czySamogloska(wyraz[1]))
  7.       ile++;
  8.     return wyraz.Substring(ile, wyraz.Length - ile)
  9.       + wyraz.Substring(0, ile) + "ay";
  10.   }
  11. }

Pierwszy warunek sprawdza czy wyraz rozpoczyna się od samogłoski. To jest najprostszy przypadek, gdzie wystarczy dopisać na koniec "way". Jednak jeśli warunek nie jest spełnione to z pewnością pierwsza jest spółgłoska, ale warto sprawdzić jeszcze czy drugi znak nie jest spółgłoską i dopiero wtedy odpowiedni przebudować wyraz.

Deszyfrowanie

Nie istnieje metoda gwarantująca 100% skuteczności deszyfrowania jeśli program nie ma wczytanego słownika, aby upewnić się co do poprawności słowa. Możliwe jest jednak uzyskanie wysokiej skuteczności przy pomocy poniższej funkcji deszyfruj().

  1. static string deszyfruj(string wyraz) {
  2.   if (czySamogloska(wyraz[0])) {
  3.     return wyraz.Substring(0, wyraz.Length - 3);
  4.   } else {
  5.     int ile = 1;
  6.     if (wyraz.Length > 1 && !czySamogloska(wyraz[wyraz.Length - 4]))
  7.       ile++;
  8.     return wyraz.Substring(wyraz.Length - 2 - ile, ile)
  9.       + wyraz.Substring(0, wyraz.Length - 2 - ile);
  10.   }
  11. }

Podczas deszyfrowania istnieje problem polegający na rozpoznaniu ile spółgłosek zostało przesuniętych. Chociażby zaszyfrowany wyraz "pig" to "igpay". Podczas deszyfrowania na końcu są dwie spółgłoski, ale w rzezywistości należy przesunąć tylko jedną.

Testowanie funkcji

W celu przetestowania kodu można skorzystac z poniższego fragmentu kodu, który wczyta wyraz do zaszyfrowania, a program wypisze zaszyfrowną wersję, a następnie ją rozszyfruje.

  1. static void Main(string[] args) {
  2.   Console.Write("Podaj wyraz: ");
  3.   string wyraz = Console.ReadLine();
  4.   string zaszyfrowany = szyfruj(wyraz);
  5.   Console.WriteLine("Zaszyfrowany: " + zaszyfrowany);
  6.   Console.WriteLine("Odszyfrowany: " + deszyfruj(zaszyfrowany));
  7.   Console.ReadKey();
  8. }