Program: napisać program implementujący szyfr Polibiusza.
Z hasłem (podrozdział 4.2, wykład 1). Program czyta dane ze standardowego wejścia, przetwarza (szyfruje/deszyfruje) i wynik wypisuje na standardowe wyjście. W wierszu poleceń podajemy akcję (szyfrowanie albo deszyfrowanie) oraz hasło.
Film:
Kod programu:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char answer = 0;
int i,j,k=0,l,pozycjaUnikat=0,czyJest,licznik,przerwij=0;
char haslo[10];
char unikat[10]=" ";
char macierz[5][5];
printf("SZYFR POLIBIUSZA\n\n");
printf("Pierw trzeba wygenerowac tablice!\n");
printf("Podaj HASLO ktore bedzie stanowic klucz (maksymalnie 10 znakow): ");
/////////////////////////////////////////////Generowanie tablicy z unikatowymi znakami z podanego przez uzytkownika hasla
do{
for(k=0;k<sizeof(haslo);k++)
{
haslo[k]=0;
}
scanf("%10s", haslo);
przerwij=0;
for(k=0;k<sizeof(haslo);k++)
{
haslo[k]= toupper(haslo[k]);
if (haslo[k]== 'J')
haslo[k]= 'I';
if((int)haslo[k]!=0 && ((char)haslo[k]<=64 ||(char)haslo[k]>=91))
przerwij=1;
}
if(przerwij==0)
{
k=0;
while(haslo[k])
{
czyJest = 0;
haslo[k]= toupper(haslo[k]);
if (haslo[k]== 'J')
haslo[k]= 'I';
for(l=0;l<sizeof(unikat);l++)
{
if (unikat[l]==haslo[k])
czyJest = 1;
}
if (czyJest == 0)
{
unikat[pozycjaUnikat]=haslo[k];
pozycjaUnikat++;
}
k++;
}
/////////////////////////////////////////////Ujednolicenie macierzy znakami spacji
for (i = 0; i<5; i++)
{
for (j = 0; j<5; j++)
{
macierz[i][j]=' ';
}
j=0;
}
/////////////////////////////////////////////Wygenerowanie tablicy znakow
/////////////////////////////////////////////W pierwszej kolenosci dodanie znakow z hasla
printf("\nGeneruje tablice.\n");
i=0;
j=0;
for (licznik = 0; licznik<sizeof(unikat); licznik++)
{
if(unikat[licznik]!=0)
{
macierz[i][j]=unikat[licznik];
j++;
}
if(j==5)
{
j=0;
i++;
}
}
/////////////////////////////////////////////Uzupelnienie tablicy pozostalymi znakami alfabetu
int pierwszy_ascii;
int zapamietane_i=0;
int zapamietane_j=0;
for (pierwszy_ascii = 65; pierwszy_ascii<=90; pierwszy_ascii++)
{
if(pierwszy_ascii!=74)
{
czyJest = 0;
for (i = 0; i<5; i++)
{
for (j = 0; j<5; j++)
{
if(zapamietane_i==0 && zapamietane_j==0 &&macierz[i][j]==' ')
{
zapamietane_i=i;
zapamietane_j=j;
}
int ii=(int)macierz[i][j];
if(pierwszy_ascii==ii)
{
czyJest=1;
}
}
j=0;
}
if(czyJest==0)
{
macierz[zapamietane_i][zapamietane_j]=pierwszy_ascii;
}
}
zapamietane_i=0;
zapamietane_j=0;
}
/////////////////////////////////////////////Wyœweitlenie tablicy
printf("\nWyswietlam wygenerowana tablice.\n\n");
for (i = 0; i<5; i++)
{
for (j = 0; j<5; j++)
{
printf(" %c",macierz[i][j]);
}
printf("\n");
j=0;
}
}
else
{
printf("\nNiepoprawne haslo, podaj litery!\n\n");
}
}while(przerwij==1);
printf("\nMENU\n");
printf("K. Kodowanie\n");
printf("O. Odkodowanie\n");
printf("E. Wyjdz z programu\n");
printf("Wybierz opcje: ");
/////////////////////////////////////////////Petla switch pozwalajaca na kodowanie/odkodowywanie
int a;
do{
scanf(" %c", &answer);
switch (answer)
{
case 'K':
printf("\nWybrano kodowanie.\n");
printf("Podaj slowo do zaszyfrowania: ");
scanf("%10s", haslo);
printf("\nZakodowane slowo to: ");
k=0;
while(haslo[k])
{
if((int)haslo[k]==74)
haslo[k]=73;
haslo[k]= toupper(haslo[k]);
k++;
}
for (licznik=0;licznik<sizeof(haslo);licznik++)
{
for (i = 0; i<5; i++)
{
for (j = 0; j<5; j++)
{
if(haslo[licznik]==macierz[i][j])
{
printf("%d%d ",i+1,j+1);
}
}
j=0;
}
i=0;
}
for(a=0;a<sizeof(haslo);a++)
{
haslo[a]=0;
}
printf("\n\nWybierz kolejna opcje z menu: ");
break;
case 'O':
printf("\nWybrano odkodowywanie.\n");
printf("\n(Aby wyjsc z tej funkcji wcisnij 'E')\n");
printf("\nPodaj kody liczbowe dzielac je spacja (limit 20 znakow): ");
char dataBuffer[20];
int start;
int koniec;
int licznik_cyfer;
for(i=0;i<sizeof(dataBuffer);i++)
{
dataBuffer[i]=' ';
}
while (1)
{
start=0;
koniec=0;
int petla_i=0;
int petla_j=0;
licznik_cyfer=0;
if (fgets(dataBuffer, 20, stdin) && dataBuffer[strlen(dataBuffer) - 1] == '\n' && dataBuffer[0]!='E')
{
for(i=0;i<sizeof(dataBuffer);i++)
{
if(dataBuffer[i]!=32 && dataBuffer[i]!=10 && dataBuffer[i]!=0)
licznik_cyfer++;
else if(dataBuffer[i]==32 && licznik_cyfer>0)
{
koniec=i;
char subbuff[5];
memcpy( subbuff, &dataBuffer[start], koniec );
subbuff[licznik_cyfer] = '\0';
start=i+1;
if(licznik_cyfer!=2 || (char)subbuff[0]>=54 || (char)subbuff[1]>=54 || (char)subbuff[0]<=48 || (char)subbuff[1]<=48)
{
printf("\nJeden z argumentow jest niewlasciwy!\nPodaj jeszcze raz: ");
break;
}
else
{
for (petla_i = 0; petla_i<5; petla_i++)
{
for (petla_j = 0; petla_j<5; petla_j++)
{
if((char)subbuff[0]-48==petla_i+1 && (char)subbuff[1]-48==petla_j+1)
{
printf("%c ",macierz[petla_i][petla_j]);
break;
}
}
petla_j=0;
}
petla_i=0;
}
licznik_cyfer=0;
}
}
for(i=0;i<sizeof(dataBuffer);i++)
{
dataBuffer[i]=32;
}
}
else
{
fputs("Wyjscie z funkcji odkodowywania.\n", stderr);
printf("\n\nWybierz kolejna opcje z menu: ");
break;
}
}
break;
case 'E':
printf("\nWylaczam program.\n");
break;
}
}while(answer!='E');
return 0;
}
Słowniczek pojęć:
Klasyczna szachownica Polibiusza jest kwadratową tabelą, w której pierwszy wiersz zawiera współrzędne pionowe (kolumn), a pierwsza kolumna współrzędne poziome (wierszy). Metoda rozwidlania polega na dodaniu (jako drugiego od góry) wiersza bez współrzędnej poziomej. Do komórek tego wiersza wpisuje się słowo-klucz, które może zawierać najwyżej 8 liter. Pozostałe pola tego wiersza pozostawia się niewypełnione. Cyfry będące współrzędnymi pionowymi niewypełnionych komórek wpisuje się jako współrzędne poziome wierszy od trzeciego w dół. Powstaje tabela, która ma 10 kolumn, a liczba wierszy zależy od długości słowa-klucza. Następnie wypełnia się powstałą szachownicę pozostałymi literami alfabetu (z pominięciem liter z klucza) i ewentualnie innymi znakami. Można to robić najprościej – wierszami alfabetycznie lub według metody ustalonej między osobami, które będą używać tabeli. Liczba znaków, które można w zmieścić w takiej tabeli można opisać wzorem:
liczba znaków w tabeli = 10 × liczba wierszy ze współrzędnymi + liczba znaków słowa-klucza.