Autor rozwiązania: Maciej Muras

Plik z zadaniami można pobrać ze strony: https://cke.gov.pl/images/_EGZAMIN_MATURALNY_OD_2015/Arkusze_egzaminacyjne/2016/formula_od_2015/MIN-R2_1P-162.pdf

Pliki do zadania:

dane_6_3

dane_6_2 (UWAGA !!! ORYGINALNY PLIK ZAWIERA NIEKOMPLETNE DANE)

dane_6_1

Podstawieniowy szyfr Cezara z przesunięciem (kluczem) k polega na zastąpieniu każdego
znaku jawnego znakiem leżącym w alfabecie o k pozycji w prawo od zastępowanego znaku.
Przykład: znak ‘B’ po zakodowaniu kluczem k=3 zastąpiony zostanie znakiem ‘E’.
… A B C D E F …
1 2 3
Przy szyfrowaniu znaku należy postępować w sposób cykliczny, to znaczy, jeżeli znak nie
posiada w alfabecie następnika przesuniętego o k pozycji, to alfabet „zawija się” i za literą Z
następuje znów litera A.
Przykład: jawny znak ‘X’ po zakodowaniu kluczem k=3 zastąpiony zostanie znakiem ‘A’,
znak ‘Y’ – znakiem ‘B’, natomiast ‘Z’ – znakiem ‘C’.
… W X Y Z A B C D …
W tym zadaniu rozpatrujemy tylko słowa zbudowane z wielkich liter alfabetu angielskiego
(o kodach ASCII odpowiednio od 65 do 90), o długościach nie większych niż 30 znaków.

Rozwiązanie:

package com.company;
import java.util.*;
import java.io.*;
public class Main {
    public static String zaszyfruj(String slowoOdkodowane, int klucz){
        char tablicaLiter[]=new char[29];
        char literaZakodowana;
        String slowoZakodowane;
        tablicaLiter=slowoOdkodowane.toCharArray();
        slowoZakodowane="";
        for (char literaOdkodowana:tablicaLiter){
            literaZakodowana=(char)(literaOdkodowana+klucz%26);
            if (literaZakodowana>90) literaZakodowana-=26;
            if (literaZakodowana<65) literaZakodowana+=26;
            slowoZakodowane=slowoZakodowane+Character.toString(literaZakodowana);
        }
        return slowoZakodowane;
    }
    public static void main(String[] args) throws FileNotFoundException {
// ----------------------------------------- zadanie 6.1 -----------------------------------------
/*
W pliku dane_6_1.txt znajduje się 100 słów. Słowa umieszczono w osobnych wierszach.
Fragment pliku dane_6_1.txt:
INTERPRETOWANIE
ROZWESELANIE
KONSERWOWANIE
Napisz program, który zaszyfruje słowa z pliku dane_6_1.txt z użyciem klucza
k = 107. Wynik zapisz do pliku wyniki_6_1.txt, każde słowo w osobnym wierszu,
w porządku odpowiadającym kolejności słów z pliku z danymi.
Uwaga:
Dla pierwszego słowa z pliku dane_6_1.txt (INTERPRETOWANIE) wynikiem jest
słowo LQWHUSUHWRZDQLH. 
*/
    Scanner odczyt = new Scanner (new File("dane_6_1.txt"));
    PrintWriter zapis = new PrintWriter("wyniki_6_1.txt");
    while (odczyt.hasNextLine()) {
        zapis.println(zaszyfruj(odczyt.nextLine(),107%26));
    }
        odczyt.close();
        zapis.close();
// ----------------------------------------- zadanie 6.2 -----------------------------------------
/*
W pliku dane_6_2.txt zapisano 3 000 szyfrogramów i odpowiadające im klucze
szyfrujące. W każdym wierszu znajduje się jeden szyfrogram (zaszyfrowane słowo)
i po pojedynczym znaku odstępu odpowiadający mu klucz (maksymalnie czterocyfrowa
liczba).
Fragment pliku dane_6_2.txt:
BCYKUNCM 1718
YFOGNSKGYW 7580
WARDA 9334 
Strona 7 z 8 MIN_2R
Napisz program, który odszyfruje słowa zaszyfrowane podanymi kluczami. Wynik zapisz
w pliku wyniki_6_2.txt: każde odszyfrowane słowo w osobnym wierszu, w porządku
odpowiadającym kolejności szyfrogramów z pliku z danymi.
Uwaga:
Dla pierwszego szyfrogramu z pliku dane_6_2.txt (BCYKUNCM) wynikiem jest słowo
ZAWISLAK. 
*/
         odczyt = new Scanner (new File("dane_6_2.txt"));
         zapis = new PrintWriter("wyniki_6_2.txt");
       String paraSlowoZakodowaneKlucz[]=new String[1];
        while (odczyt.hasNextLine()) {
            paraSlowoZakodowaneKlucz=(odczyt.nextLine()).split(" ");
            if (paraSlowoZakodowaneKlucz.length==2) {
                //sprawdzam czy mam tablicę składającą się z pary Słowo-klucz, (2 elementy)
                // weryfikacja jest zastosowana tylko z powodu błędu w dostarczonym pliku z danymi w roku 2016
                zapis.println(zaszyfruj(paraSlowoZakodowaneKlucz[0],-(Integer.parseInt(paraSlowoZakodowaneKlucz[1]))
                        %26));
            }
        }
        odczyt.close();
        zapis.close();
// ----------------------------------------- zadanie 6.3 -----------------------------------------
/*
W pliku dane_6_3.txt zapisano 3 000 par słów, po jednej parze w wierszu, oddzielonych
pojedynczym znakiem odstępu. Drugie słowo w każdej parze jest szyfrogramem pierwszego
z nieznanym kluczem.
Niektóre szyfrogramy są błędne, co oznacza, że niektóre litery w słowie zakodowano
z różnymi przesunięciami. Słowo ma zawsze tę samą długość co odpowiadający
mu szyfrogram.
Fragment pliku dane_6_3.txt:
ZAWISLAK EFBNXQFP
KRASZEWSKI XENFMRJFXV
Napisz program, który wyszuka i wypisze te słowa z pliku dane_6_3.txt, które błędnie
zaszyfrowano. Wynik zapisz w pliku wyniki_6_3.txt: każde słowo w osobnym wierszu,
w porządku odpowiadającym kolejności tych słów z pliku z danymi.
Uwaga:
Pierwsze słowo w pliku wynikowym to SMIGIELSKI. 
*/

       odczyt = new Scanner (new File("dane_6_3.txt"));
        zapis = new PrintWriter("wyniki_6_3.txt");
        String  paraSlowoOdkodowaneZakodowane[]=new String[1];
        String zaszyfrowane;
        int klucz;
        while (odczyt.hasNextLine()) {
            paraSlowoOdkodowaneZakodowane=(odczyt.nextLine()).split(" ");
                klucz=(paraSlowoOdkodowaneZakodowane[1].charAt(0)-paraSlowoOdkodowaneZakodowane[0].charAt(0));
                zaszyfrowane=zaszyfruj(paraSlowoOdkodowaneZakodowane[0],klucz);
                if ((paraSlowoOdkodowaneZakodowane[1].equals(zaszyfrowane))==false) {
                    zapis.println(paraSlowoOdkodowaneZakodowane[0]);
                }
        }
        odczyt.close();
        zapis.close();
    }
}