Strona główna » Algorytmy » Szyfry » Szyfr Condi
 

Szyfr Condi

O szyfrze

Szyfr Condi to szyfr, który wykorzystuje przesunięcia do szyfrowania kolejnych liter. W celu zaszyfrowania trzeba jedynie podać przesunięcie pierwszego znaku. Każdy następny znak jest szyfrowany na podstawie poprzedniego. W celu zwiększenia bezpieczeństwa danych wykorzystywane jest słowo klucz, które ustala alfabet na podstawie określa się litery po przesunięciu. Podczas szyfrowania zachowywane są wszystkie znaki interpunkcyjne.

Przykład

Alfabet i słowo klucz

Pierwszy etap szyfrowania rozpoczyna się od ustalenia słowa klucza. Przyjmijmy, że taki słowem będzie wyraz "KLUCZ". Należy z niego wybrać wszystkie unikalne pierwsze wystąpienia liter, a następnie dopisać wszystkie litery alfabetu w kolejności alfabetycznej, które nie wystąpiły w słowie klucz. Na koniec należy ponumerować kolejne litery. Wynik tego etap został przedstawiony w tabeli.

1234567891011121314151617181920212223242526
KLUCZABDEFGHIJMNOPQRSTVWXY

Najprotszym sprawdzeniem czy alfabet jest poprawny jest porównanie długości alfabetu powstałego z wybranym np. łacińskim oraz sprawdzenie czy żadna litera się nie powtarza.

Szyfrowanie

Każda kolejna litera jest szyfrowana poprzez przesunięcie jej o tyle pozycji jaką pozycje ma poprzednia litera w szyfrowanym tekście. Jednak pierwsza litera nie ma nic przed sobą, więc potrzebne jest wstępne przesunięcie. Przyjmijmy, że początkowe przesunięcie ma wartość 7. Wtedy kolejne litery są szyfrowane następująco:

PrzesunięcieLiteraPozycjaNowa Litera
7T22U
22A6L
6J14R
14N16C
16A6T
6---
6I13Q
13N16U
16F10Y
10O17K
17R20G
20M15E
15A6S
6C4F
4J14P
14A6R

Ostatecznie szyfrogram to: "ULRCT QUYKGESFPR".

Deszyfrowanie

Rozszyfrowywanie danych należy tak jak szyfrowanie przeprowadzić od lewej do prawej. W celu rozszyfrowania pierwszej litery należy przesunąć ją o ustalone przesunięcie w lewo. Dopiero pozycja odszyfrowanej litery może posłużyć do odszyfrowania kolejnej litery.

Implementacja

Przedstawiona przykładowa implementacja pozwala na zaszyfrowanie jedynie wielkich liter. Wszystkie pozostałe znaki są traktowane jako interpunkcyjne i są przepisywane na tą samą pozycję w wyniku w której są zapisane w szyfrowanym tekście bez zmian. Program zakłada poprawność danych wejściowych.

Tworzenie alfabetu

Funkcja utworzAlfabet() przyjmuje tylko jeden argument: slowoKluczowe - jest to słowo kluczowe. Zwracanym wynikiem jest alfabet potrzebny do szyfrowania. Dokładane litery są tutaj pobierane z alfabetu łacińskiego.

C++
C#
  1. char* utworzAlfabet(char* slowoKluczowe) {
  2.   int dl = 'Z' - 'A' + 1;
  3.   char* alfabet = new char[dl + 1];
  4.   int zapis = 0;
  5.   for (int i = 0; i < strlen(slowoKluczowe); i++) {
  6.     if (wyszukaj(alfabet, slowoKluczowe[i]) == -1)
  7.       alfabet[zapis++] = slowoKluczowe[i];
  8.   }
  9.   for (int i = 'A'; i <= 'Z'; i++) {
  10.     if (wyszukaj(alfabet, i) == -1)
  11.       alfabet[zapis++] = i;
  12.   }
  13.   alfabet[zapis] = '\0';
  14.   return alfabet;
  15. }

Szyfrowanie

Przedstawiona funkcja szyfrująca szyfruj() przyjmuje trzy argumenty: tekst - tekst do zaszyfrowania, klucz - słowo klucz na podstawie którego będzie ustalony alfabet oraz przes - liczba oznaczająca przesunięcie pierwszego znaku. Wynikiem działania funkcji jest szyfrogram.

C++
C#
  1. char* szyfruj(char* tekst, char* klucz, int przes) {
  2.   int dl = strlen(tekst);
  3.   char* alfabet = utworzAlfabet(klucz);
  4.   char* wynik = new char[dl + 1];
  5.   for (int i = 0; i < dl; i++) {
  6.     char c = tekst[i];
  7.     if (c >= 'A' && c <= 'Z') {
  8.       int pos = wyszukaj(alfabet, c);
  9.       wynik[i] = alfabet[(pos + przes) % 26];
  10.       przes = pos + 1;
  11.     } else {
  12.       wynik[i] = c;
  13.     }
  14.   }
  15.   wynik[dl] = '\0';
  16.   delete alfabet;
  17.   return wynik;
  18. }

Deszyfrowanie

Poniższa funkcja deszyfrująca rozszyfruj() przyjmuje trzy argumenty: tekst - szyfrogram do rozszyfrowania, klucz - słowo klucz na podstawie którego będzie ustalony alfabet oraz przes - liczba oznaczająca przesunięcie pierwszego znaku. Wynikiem działania funkcji jest szyfrogram.

C++
C#
  1. char* rozszyfruj(char* tekst, char* klucz, int przes) {
  2.   int dl = strlen(tekst);
  3.   char* alfabet = utworzAlfabet(klucz);
  4.   char* wynik = new char[dl + 1];
  5.   for (int i = 0; i < dl; i++) {
  6.     char c = tekst[i];
  7.     if (c >= 'A' && c <= 'Z') {
  8.       int pos = wyszukaj(alfabet, c);
  9.       wynik[i] = alfabet[(pos - przes + 26) % 26];
  10.       przes = wyszukaj(alfabet, wynik[i]) + 1;
  11.     } else {
  12.       wynik[i] = c;
  13.     }
  14.   }
  15.   wynik[dl] = '\0';
  16.   delete alfabet;
  17.   return wynik;
  18. }

Testowanie funkcji

Działanie funkcji można przetestować przy pomocy poniższego fragmentu kodu:

C++
C#
  1. int main () {
  2.   char* klucz = new char[16];
  3.   cout << "Podaj slowo kluczowe:\n";
  4.   cin.getline(klucz, 32);
  5.   char* tekst = new char[512];
  6.   cout << "Podaj tekst do zaszyfrowania:\n";
  7.   cin.getline(tekst, 512);
  8.   int liczba;
  9.   cout << "Podaj poczatkowe przesuniecie:\n p = ";
  10.   cin >> liczba;
  11.   char* szyfrogram = szyfruj(tekst, klucz, liczba);
  12.   cout << "\n\nSzyfrogram to:\n" << szyfrogram << endl;
  13.   char* tekstjawny = rozszyfruj(szyfrogram, klucz, liczba);
  14.   cout << "\n\nTekst jawny to:\n" << tekstjawny << endl;
  15.   delete klucz, tekst, szyfrogram, tekstjawny;
  16.   system("pause");
  17.   return 0;
  18. }

Zadania

Zadanie 1

W przypadku szyfru Condi każdy następny znak jest szyfrowany na podstawie poprzedniego. Uogólnijmy to do przypadku szyfrowania, gdzie n-ty znak będzie szyfrowany na podstawie znaku na pozycji n - k. Pierwsze k znaków powinno zostać zaszyfrowane przez przesunięcie podane na początku. Napisz funkcje i sprawdź ich działanie.

Przykład

Szyfrują wyrażenie "TAJNA INFORMACJA" przy pomocy słowa klucz "KLUCZ", przesunięcia 7 na podstawie wyrazu o k = 3 pozycji wcześniej otrzymamy szyfrogram:

  1. UISVL QANOBZNSDS