Programowanie i algorytmy

KONKURS FRAKTAL

fraktal

VII edycja konkursu programistycznego

FRAKTAL

8-9 kwietnia 2017

czytaj więcej

Szyfr przestawieniowy

powrót

Szyfr przestawieniowy charakteryzuje się tym, że w tekście zaszyfrowanym występują wszystkie znaki tekstu szyfrowanego (jawnego), ale są one poprzestawiane według ściśle określonego schematu np.:

Zamiana sąsiadujących liter

Kolejne pary znaków zamieniamy miejscami. Jeśli liczba znaków jest nieparzysta, to ostatnia litera zostaje niezmieniona. Dla przykładu popatrzmy na wyraz lokomotywa:

Tekst jawny:

{tex}lokomotywa{/tex}

Tekst zaszyfrowany (szyfrogram) 

{tex}olokomywaw{/tex}

Pierwsze {tex}o{/tex} zamieniamy z literą {tex}l{/tex}, drugie {tex}o{/tex} z literą {tex}k{/tex}, itd.

Żeby odszyfrować szyfrogram należy wykonać ponownie zamianę sąsiadujących liter parami.

 

#include<iostream>
#include<cstring>
using namespace std;
 
void kodowanie(char *napis)
{
  int dl = strlen(napis); //wyznaczenie liczby znaków
 
  for(int i=0; i<dl-1; i+=2) //przesuwamy się o dwa znaki
  //zamiana sąsiadujących znaków
  {
    char pom = napis[i];
    napis[i] = napis[i+1]; //dlatego w pętli i<dl-1
    napis[i+1] = pom;  
  }
}
 
int main()
{
  char napis[100];
 
  cout<<"Podaj napis do zaszyfrowania: ";
  cin.getline(napis, 100);
 
  cout<<"Przed szyfrowaniem: ";
  cout<<napis<<endl;
 
  //szyfrujemy
  kodowanie(napis);
 
  cout<<"Szyfrogram: ";
  cout<<napis<<endl;
 
  //deszyfrujemy
  kodowanie(napis);
 
  cout<<"Tekst jawny: ";
  cout<<napis<<endl;
 
  cin.get();
  return 0;
}
 

 

Przesunięcie spółgłosek o jedno miejsce

Drugim przykładem jest przesunięcie spółgłosek o jedno (kilka miejsc) miejsce w prawo (lewo). Ostatnia spółgłoska po prawej stronie "wskoczy" na miejsce pierwszej od lewej. Samogłoski zostają na swoich miejscach:

Dla słowa lokomotywa szyfrogram będzie wyglądał następująco:

Tekst jawny:

{tex}lokomotywa{/tex}

Szyfrogram:

{tex}wolokomyta{/tex}

Aby otrzymać tekst przed zaszyfrowaniem wystarczy przesunąć spółgłoski o jedno miejsce w lewo.

Rozwiązanie zagadnienia szyfrowania jest następujące:

  • pierwszą znalezioną spółgłoskę i jej pozycję zapamiętujemy
  • kolejną spółgłoskę zapamiętujemy a w to miejsce nadpisujemy poprzednią
  • gdy wszystkie spółgłoski będą już przesunięte, należy ostatnią przypisać do pozycji, którą zapamiętalismy w pierwszym kroku

Deszyfrowanie będzie polegało na zastosowaniu powyższych kroków przechodząc wszystkie znaki od prawej do lewej.

Rozwiązanie w C++:

#include<iostream>
#include<cstring>
using namespace std;
 
bool czy_spolgloska(char litera)
{
  //sprawdzamy czy samogłoska - jest ich mniej
  switch(litera)
  {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
    case 'y':
      return 0;  
  }
  return 1;
}
 
void kodowanie(char *napis)
{
  int dl = strlen(napis); //wyznaczenie liczby znaków
 
  //należy zapamiętać pozycję pierwszej spółgłoski
  bool f=1;  //czy dana spółgłoska jest pierwsza
  int nr;   //pozycja pierwszej spółgłoski
  char first;  //przechowujemy spółgłoskę do podmiany
 
  for(int i=0;i<dl;i++)
    {
      if(czy_spolgloska(napis[i]))
      {
        if(f)  //jesli wczytana spółgłoska jest pierwsza
        {    //to ją spamiętujemy
          nr = i;
          first = napis[i];
          f = 0;
        }
        else //podmiana
        {
          char pom = napis[i];
          napis[i] = first;
          first = pom;
        }  
      }
 
    }
    if(!f)
      napis[nr] = first;
}
 
void dekodowanie(char *napis)
{
  int dl = strlen(napis); //wyznaczenie liczby znaków
 
  //należy zapamiętać pozycję pierwszej spółgłoski
  bool f=1;  //czy dana spółgłoska jest pierwsza
  int nr;   //pozycja pierwszej spółgłoski
  char first;  //przechowujemy spółgłoskę do podmiany
 
  for(int i=dl-1;i>=0;i--)
    {
      if(czy_spolgloska(napis[i]))
      {
        if(f)  //jesli wczytana spółgłoska jest ostatnia
        {    //to ją spamiętujemy
          nr = i;
          first = napis[i];
          f = 0;
        }
        else //podmiana
        {
          char pom = napis[i];
          napis[i] = first;
          first = pom;
        }  
      }
 
    }
    if(!f)
      napis[nr] = first;
}
 
int main()
{
  char napis[100];
 
  cout<<"Podaj napis do zaszyfrowania: ";
  cin>>napis;
 
  cout<<"Przed szyfrowaniem: ";
  cout<<napis<<endl;
 
  //szyfrujemy
  kodowanie(napis);
 
  cout<<"Szyfrogram: ";
  cout<<napis<<endl;
 
  //deszyfrujemy
  dekodowanie(napis);
 
  cout<<"Tekst jawny: ";
  cout<<napis<<endl;
 
  cin.get();
  return 0;
}
 

 

Oczywiscie to są tylko dwa przykłady szyfrowania przestawieniowego. Można samemu spróbować wymysleć mniej lub bardziej złożony szyfr, który w jakis sposób (niewielki) zabezpieczy dane.