Java - Cézarova šifra - pomoc, při dešifrování program hází error
Dobrý den,
Učím se teprve chvíli javu. Chtěl jsem si skusit napsat program který bude trochu pokročileji pracovat s caesarovou šifrou,ale nedopadlo to zrovna nejlépe.
Zašifrovat se mi to daří dobře, ale rozšifrování nejde. Přitom v editoru žádné errory, ani warningy nemám :/.
package šifrovač;
import java.util.Scanner;
/**
*
* @author Slu
*/
public class Šifrovač {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Chcete šifrovat / dešifrovat? [1/2]");
if (Integer.parseInt(sc.nextLine()) == 1)
{
System.out.println("Zadejte to co chcete zašifrovat");
String sentence = sc.nextLine();
String sifra = "";
System.out.println("Zadej posun. (v číslech)");
int sifrkod = Integer.parseInt(sc.nextLine().trim());
System.out.println("zadej oddělovač znaků");
String oddel = String.valueOf(sc.nextLine());
System.out.println("zadal jsi "+sentence+". Šifruji kodem "+"X1"+sifrkod+"abc"+oddel);
for (char c: sentence.toCharArray())
{
int i = (int)c;
sifra += 26-i+97+sifrkod+oddel; //26 je pocetpismen,97 je start A v ASCII.
}
sifra = sifra.toUpperCase();
System.out.println("úspěšně zašifrováno do "+sifra);
}
else
{
System.out.println("co chcete rozšifrovat?");
String zasifrovane = sc.nextLine();
System.out.println();
System.out.println("zadej !KOMPLETNÍ! šifrovací kod");
String sifrokod = sc.nextLine();
boolean zacateksifr = sifrokod.startsWith("X1");
boolean stredsifr = sifrokod.contains("abc");
if ((zacateksifr == true) && (stredsifr == true))
{
System.out.println("zašifrovaný text je "+zasifrovane+". Dešifruji klíčem "+sifrokod);
//vyčištění a nalezení posunu a separátoru
String separator = sifrokod.substring(sifrokod.lastIndexOf("abc"));
String posun = sifrokod.replace(separator, "");
posun = posun.replace("X1", "");
separator = separator.replace("abc", "");
System.out.println(posun+" "+separator);
//vyčištěno, hurá na dešifraci.
String desifrovano = "";
String[] sifrapole = zasifrovane.split(separator);
for (String i: sifrapole) {
for (int a = 0; a < sifrapole.length; a++) {
int finalniznakcislo = 26+Integer.parseInt(sifrapole[a])-97+Integer.parseInt(posun);
char finalniznak = (char)finalniznakcislo;
desifrovano += finalniznak;
}
}
System.out.println(desifrovano);
}
else
System.out.println("Tohle NENÍ platný dešifrovací kod.");
}
}
}
Kdyžtak výstup programu je zde 251kw8
Když při šifrování přičítáš, tak bys při dešifrování měl odečítat a naopak.
to dělám. problém je, že místo znaků mi tam vyběhnou takové čtverečky místo znaků. tzn. jako kdyby daný znak neexistoval.
Ono to uz aj blbo sifrujes, to si na to dosiel jak na ten vzorec sifra += 26-i+97+sifrkod+oddel? A potom z toho este urobis uppercase??
Desifrovanie je este divnejsie.
26 je počet písmen. chtěl jsem ať a je 26 a z je 0, tzn ať je to reverzivně. 97 je ascii kod a.
Tzn potom z toho vyjde, pokud chci šifrovat A: 26 -i (=97, protože máme A)+ 97 (vykompenzujeme hodnotu A)+ POSUN v ASCII + oddělovač, ať to jde posléze rozšifrovat.
co to furt meles, jaky oddelovac. Ked sifrujes A tak urobis A+posun. Cezarova sifra nema ziaden oddelovac ani nic podobne. Kvoli prechodu Z->A musis urobit bud modulo (zvysok po deleni) alebo if. To sa neda scitanim alebo odcitanim.
tak oddělovač je tam třeba dát, aby se při dešifrování znaky od sebe daly rozeznat, tak že je rozdělíš do pole pomocí split("něco"), ne ?
ne. Pisal si ze robis cezarovu sifru. Si o nej najprv nieco precitaj, aby si vedel co vlastne robis :)
normalny clovek by si urobil najprv uppercase, a potom
sifrznak += kluc;
if(sifrznak>'Z') sifrznak-='Z'-'A'+1;
desifrovanie bude logicky opacne (odcitanie posunu a test na <'A')
To podle mě právě neděláš. Proto se nejspíš dostáváš do oblasti netisknutelných znaků.