Sprawdź się
Szyfr Vigenère'a
Najważniejsze informacje dotyczące szyfrowania oraz deszyfrowania wiadomości za pomocą szyfru Vigenère'a oraz jego implementacji w języku Java znajdziesz w następujących e‑materiałach:
Szyfr polialfabetycznyPrHtFJ1fbSzyfr polialfabetyczny,
Implementacja szyfru polialfabetycznego w języku JavaPsGfmF0phImplementacja szyfru polialfabetycznego w języku Java.
W tej sekcji rozwiniesz – przygotowany wcześniej – projekt o nową funkcję. Będzie nią możliwość zaszyfrowania wiadomości za pomocą szyfru Vigenère'a. Implementacja nowej funkcji odbędzie się w dwóch etapach – w ramach dwóch osobnych ćwiczeń. Pierwsze z nich dotyczy utworzenia poprawnej tablicy Vigenère'a – jak na rysunku poniżej. Natomiast drugie – implementacji osobnej funkcji, wykorzystującej utworzoną tablicę do szyfrowania za pomocą szyfru Vigenère'a.
Ponieważ dotychczasowe funkcje szyfrowania i deszyfrowania operują na wielkich literach, szyfrowanie za pomocą szyfru Vigenère'a również będzie się na nich opierać. W związku z tym tablica szyfrowania ma składać się z wielkich liter.
Tablica ta jest w kształcie kwadratu o boku składającym się z wszystkich liter alfabetu.
ierwszy wiersz zawiera litery alfabetu od A do Z.
Pierwsza kolumna zawiera litery alfabetu od A do Z.
W kolejnych kolumnach, litera początkowa alfabetu przenoszona jest do ostatniego wiersza w danej kolumnie.

Do istniejącego programu dopisz wnętrze funkcji wypelnijTabele(), tak aby wypełniła tablicę tabela (o wymiarach 26 na 26), zgodnie z tablicą Vigenère'a. Przetestuj działanie, wypisując zawartość kolejnych wierszy tabeli.
Specyfikacja:
Wynik:
Program na standardowe wyjście wypisuje zawartość kolejnych wierszy tabeli Vigenère'a (każdy od nowej linii).
Przykładowe rozwiązanie zadania:
public class Projekt {
static final String menu = "Jaką operację chcesz wykonać (wybierz odpowiednią liczbę 1-3)? \n" +
"1. Szyfrowanie \n" +
"2. Deszyfrowanie \n" +
"3. Zakończ program";
static final String algorytmMenu = "Wybierz algorytm \n" +
"1. Szyfr Cezara \n" +
"2. Szyfr płotkowy";
static char[][] tabela = new char[26][26];
static void wypelnijTabele() {
char[] alfabet = new char[26];
for (int i = 65, z = 0; i < 91; i++, z++) {
alfabet[z] = (char) i;
}
for (int j = 0; j < 26; j++) {
for (int k = 0; k < 26; k++) {
tabela[j][k] = alfabet[k];
}
for (int l = 0; l < 26 - 1; l++) {
char temp = alfabet[l];
alfabet[l] = alfabet[l + 1];
alfabet[l + 1] = temp;
}
}
}
static String szyfrujCezarem(String tekst, int klucz) {
String wynik = "";
int ruch = 0;
if (klucz > 0) {
if (klucz > 26) {
klucz = klucz % 26;
}
for (int i = 0; i < tekst.length(); i++) {
ruch = 0;
if (tekst.charAt(i) + klucz > 90) {
ruch = (tekst.charAt(i) + klucz) - 26;
} else {
ruch = tekst.charAt(i) + klucz;
}
wynik += (char)(ruch);
}
} else if (klucz < 0) {
if (klucz < -26) {
klucz = klucz % -26;
}
for (int i = 0; i < tekst.length(); i++) {
ruch = 0;
if (tekst.charAt(i) + klucz < 65) {
ruch = (tekst.charAt(i) + klucz) + 26;
} else {
ruch = tekst.charAt(i) + klucz;
}
wynik += (char)(ruch);
}
} else {
wynik = tekst;
}
return wynik;
}
static String deszyfrujCezarem(String tekst, int klucz) {
return szyfrujCezarem(tekst, -klucz);
}
static String szyfrujMetodaPlotkowa(String tekst, int klucz) {
String wynik = "";
boolean wDol = true;
Character[][] plot = new Character[tekst.length()][klucz];
for (int i = 0, j = 0; i < tekst.length(); i++) {
plot[i][j] = tekst.charAt(i);
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
for (int j = 0; j < klucz; j++) {
for (int i = 0; i < plot.length; i++) {
if (plot[i][j] != null) {
wynik += plot[i][j];
}
}
}
return wynik;
}
static String deszyfrujMetodaPlotkowa(String tekst, int klucz) {
String wynik = "";
boolean wDol = true;
Character[][] plot = new Character[tekst.length()][klucz];
for (int i = 0, j = 0; i < tekst.length(); i++) {
plot[i][j] = 'X';
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
for (int i = 0, k = 0; i < klucz; i++) {
for(int j = 0; j < tekst.length(); j++) {
if (plot[j][i] != null) {
plot[j][i] = tekst.charAt(k);
k++;
}
}
}
for (int i = 0, j = 0; i < tekst.length(); i++) {
wynik += plot[i][j];
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
return wynik;
}
public static void main(String[] args) {
wypelnijTabele();
for (int m = 0; m < 26; m++) {
for (int n = 0; n < 26; n++) {
System.out.print(tabela[m][n]);
}
System.out.println();
}
}
}Wykorzystując zaimplementowaną wcześniej tablicę, napisz funkcję, która będzie dokonywała szyfrowania zadanego słowa dla wprowadzonej wartości klucza, przy użyciu algorytmu Vigenère'a. Wyjście programu powinno się zgadzać z przedstawionym wyjściem. Komentarze „brakujący kod” sugerują, gdzie mają zostać dokonane zmiany. Działanie programu przetestuj, szyfrując słowo „PROGRAM” dla klucza „KLUCZ”.
Specyfikacja:
Dane:
kluczVigenere– klucz, którym zaszyfrowana zostanie zmiennatekst; ciąg znakówtekst– słowo do zaszyfrowania; ciąg znaków
Wynik:
Program na standardowe wyjście wypisuje zaszyfrowane słowo.
Przykładowe wyjście:
Jaką operację chcesz wykonać (wybierz odpowiednią liczbę 1-3)?
1. Szyfrowanie
2. Deszyfrowanie
3. Zakończ program
Wybrana operacja: 1
Wybierz algorytm
1. Szyfr Cezara
2. Szyfr płotkowy
3. Szyfr Vigenere'a
Wybrany algorytm: 3
Slowo do zaszyfrowania: PROGRAM
Ciąg znaków pełniący rolę klucza szyfrującego: KLUCZ
ZCIIQKXPrzykładowe rozwiązanie zadania:
public class Projekt {
static final String menu = "Jaką operację chcesz wykonać (wybierz odpowiednią liczbę 1-3)? \n" +
"1. Szyfrowanie \n" +
"2. Deszyfrowanie \n" +
"3. Zakończ program";
static final String algorytmMenu = "Wybierz algorytm \n" +
"1. Szyfr Cezara \n" +
"2. Szyfr Płotkowy \n" +
"3. Szyfr Vigenere'a";
static char[][] tabela = new char[26][26];
static void wypelnijTabele() {
char[] alfabet = new char[26];
for (int i = 65, z = 0; i < 91; i++, z++) {
alfabet[z] = (char) i;
}
for (int j = 0; j < 26; j++) {
for (int k = 0; k < 26; k++) {
tabela[j][k] = alfabet[k];
}
for (int l = 0; l < 26 - 1; l++) {
char temp = alfabet[l];
alfabet[l] = alfabet[l + 1];
alfabet[l + 1] = temp;
}
}
}
static String szyfrujVigenerem(String tekst, String klucz) {
String wynik = "";
for (int i = 0, j = 0; i < tekst.length(); i++) {
wynik += tabela[(int)(tekst.charAt(i)-65)][(int)(klucz.charAt(j)-65)];
if (j == klucz.length() - 1) {
j = 0;
} else {
j++;
}
}
return wynik;
}
static String szyfrujCezarem(String tekst, int klucz) {
String wynik = "";
int ruch = 0;
if (klucz > 0) {
if (klucz > 26) {
klucz = klucz % 26;
}
for (int i = 0; i < tekst.length(); i++) {
ruch = 0;
if (tekst.charAt(i) + klucz > 90) {
ruch = (tekst.charAt(i) + klucz) - 26;
} else {
ruch = tekst.charAt(i) + klucz;
}
wynik += (char)(ruch);
}
} else if (klucz < 0) {
if (klucz < -26) {
klucz = klucz % -26;
}
for (int i = 0; i < tekst.length(); i++) {
ruch = 0;
if (tekst.charAt(i) + klucz < 65) {
ruch = (tekst.charAt(i) + klucz) + 26;
} else {
ruch = tekst.charAt(i) + klucz;
}
wynik += (char)(ruch);
}
} else {
wynik = tekst;
}
return wynik;
}
static String deszyfrujMetodaPlotkowa(String tekst, int klucz) {
String wynik = "";
boolean wDol = true;
Character[][] plot = new Character[tekst.length()][klucz];
for (int i = 0, j = 0; i < tekst.length(); i++) {
plot[i][j] = 'X';
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
for (int i = 0, k = 0; i < klucz; i++) {
for(int j = 0; j < tekst.length(); j++) {
if (plot[j][i] != null) {
plot[j][i] = tekst.charAt(k);
k++;
}
}
}
for (int i = 0, j = 0; i < tekst.length(); i++) {
wynik += plot[i][j];
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
return wynik;
}
static String szyfrujMetodaPlotkowa(String tekst, int klucz) {
String wynik = "";
boolean wDol = true;
Character[][] plot = new Character[tekst.length()][klucz];
for (int i = 0, j = 0; i < tekst.length(); i++) {
plot[i][j] = tekst.charAt(i);
if (j == klucz - 1) {
wDol = false;
} else if (j == 0) {
wDol = true;
}
if (wDol) {
j++;
} else {
j--;
}
}
for (int j = 0; j < klucz; j++) {
for (int i = 0; i < plot.length; i++) {
if (plot[i][j] != null) {
wynik += plot[i][j];
}
}
}
return wynik;
}
public static void main(String[] args) {
wypelnijTabele();
System.out.println(menu);
int wyborOperacji = 1;
if (wyborOperacji == 3) {
System.exit(0);
}
System.out.println("Wybrana operacja: " + wyborOperacji);
System.out.println(algorytmMenu);
int wyborAlgorytmu = 3;
System.out.println("Wybrany algorytm: " + wyborAlgorytmu);
String tekst = "PROGRAM";
System.out.println("Slowo do zaszyfrowania: " + tekst);
int klucz = 0;
String kluczVigenere = "";
if (wyborAlgorytmu == 3) {
kluczVigenere = "KLUCZ";
System.out.println("Ciąg znaków pełniący rolę klucza szyfrującego: " + kluczVigenere);
} else {
System.out.println("Podaj wartość klucza szyfrującego");
klucz = 0;
}
switch (wyborOperacji) {
case 1:
switch (wyborAlgorytmu) {
case 1:
System.out.println(szyfrujCezarem(tekst, klucz));
break;
case 2:
System.out.println(szyfrujMetodaPlotkowa(tekst, klucz));
break;
case 3:
System.out.println(szyfrujVigenerem(tekst, kluczVigenere));
}
break;
case 2:
switch (wyborAlgorytmu) {
case 1:
System.out.println(szyfrujCezarem(tekst, -klucz));
break;
case 2:
System.out.println(deszyfrujMetodaPlotkowa(tekst, klucz));
break;
}
break;
}
}
}