I'm just a beginning programmer, and I'm here to find a bug in my program. The program only reads the uppercase letters in my text file, even though I have a lowercase case in my encrypt and decrypt methods. I'm guessing it's a problem with the caesarEncipher method. (Ignore my Decipher case in the main, I will get to it soon.)
import java.util.*;
import java.io.*;
public class Cipher {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.println("Welcome to CaesarCipher");
System.out.println();
System.out.println("Enter 1 to Encipher, 2 to Decipher, or -1 to exit");
int choice = 0;
do {
choice = scan.nextInt();
if (choice == 1) {
System.out.println("What non-negative shift should be used?");
int shift = scan.nextInt();
System.out.println("What is the input file name?");
String input = scan.next();
System.out.println("What is the output file name?");
String output = scan.next();
System.out.println(caesarEncipher(input, shift, output));
} else if (choice == 2) {
} else if (choice == -1) {
System.out.println("Thank you for using CaesarCipher");
break;
}
} while (choice != 1 && choice != 2 && choice != -1);
}
public static String caesarEncipher(String inputString, int shift, String output) throws FileNotFoundException {
File outFile = new File(output);
PrintStream encoded = new PrintStream(outFile); // creates new file for the output
File input = new File(inputString); // creates file with String to scan
Scanner scan = new Scanner(input); // creates Scanner
while (scan.hasNextLine()) {
String cipher = scan.nextLine(); // gets next line of file
String encipher = ""; // String to be added to new file
int i;
for (i = 0; i < cipher.length(); i++) {
String curr = cipher.substring(i, i + 1); // current character
String newChar = encrypt(curr, shift);
encipher = encipher + newChar;
}
encoded.println(encipher);
}
encoded.close();
return "DONE";
}
public static String encrypt(String str, int shift) {
String encrypted = "";
for (int i = 0; i < 1; i++) {
int c = str.charAt(i);
if (Character.isUpperCase(c)) {//if uppercase
c = c + (shift % 26);
if (c > 'Z') { //resets if it passes 'Z'
c = c - 26;
} else if (Character.isLowerCase(c)) {// if lowercase
c = c + (shift % 26);
if (c > 'z') { // resets if it passes 'z'
c = c - 26;
}
}
encrypted = encrypted + (char) c; // adds the encrypted character to the string
}
}
return encrypted;
}
public static String decrypt(String str, int shift) {
String decrypted = "";
for (int i = 0; i < 1; i++) {
int c = str.charAt(i);
if (Character.isUpperCase(c)) //if uppercase
{
c = c + (shift % 26);
if (c < 'A') { //resets if it passes 'A'
c = c + 26;
}
} else if (Character.isLowerCase(c)) // if lowercase
{
c = c + (shift % 26);
if (c < 'a') { // resets if it passes 'a'
c = c + 26;
}
}
decrypted = decrypted + (char) c; // adds the derypted character to the string
}
return decrypted;
}
}
In encrypt() method: This part of code
else if(Character.isLowerCase(c)) {
c=c+(shift%26);
if(c>'z') {
c=c-26;
}
}
encrypted=encrypted+(char)c;
belongs to if(c>'Z') instead of if(Character.isUpperCase(c))
Related
I have commented where I am getting error messages. On the promptUser method, it is asking me to insert "VariableDeclaratorld." On the other error message for String s1= mc1.doEncryption(en); It says that en cannot be resolved to a variable.
import java.util.Scanner;
public class MyCypher{
int cypher = 13;
public MyCypher(int cypher){
this.cypher = cypher;
}
public int getCypher(){
return cypher;
}
MyCypher mc1 = new MyCypher(cypher);
//I am getting an error on the line below
public String promptUser(en){
String en = sc.next().toLowerCase();
Scanner sc= new Scanner(System.in);
System.out.println("Enter the message:");
return en;
}
public String doEncryption(String s){
String encrypted = "";
char[] array = s.toCharArray();
for (int i = 0; i < array.length; i++) {
char shift = s.charAt(i);
if (shift >= 'a' && shift <= 'z') {
shift = (char) (shift + cypher);
if (shift > 'z') {
shift = (char)(shift - 'z' + 'a' - 1);
encrypted += shift;
}
}
else
encrypted += shift;
}
return encrypted;
}
//On the line below it says that en cannot be resolved to a variable
String s1= mc1.doEncryption(en);
public String doDecryption(String s){
String s1;
System.out.println("Encrypted message: " + s1);
String s2 = mc1.doDecryption(s1);
System.out.println("Decrypted message: " + s2);
}
}
You need to declare the Scanner before you read from the console like so:
Scanner sc = new Scanner(System in):
String en = sc.next().toLowerCase();
I am new in JAVA Programming and I am trying to create a caesar cipher encrypt/decrypt program. Unfortunately, my program is only working in lower cases. I cannot see where did I go wrong I tried reviewing my code for several times but I cant seem to find out the problem. Here is my code so far:
import java.util.Scanner;
public class CaesarCipher {
public static String encrypt(String plainText, int shift) {
if (shift > 26) {
shift = shift % 26;
} else if (shift < 0) {
shift = (shift % 26) + 26;
}
String cipherText = "";
int length = plainText.length();
for (int i = 0; i < length; i++) {
char ch = plainText.charAt(i);
if (Character.isLetter(ch)) {
if (Character.isLowerCase(ch)) {
char c = (char) (ch + shift);
if (c > 'z') {
cipherText += (char) (ch - (26 - shift));
} else {
cipherText += c;
}
} else if (Character.isUpperCase(ch)) {
char c = (char) (ch + shift);
if (c > 'Z') {
cipherText += (char) (ch - (26 - shift));
} else {
cipherText += c;
}
}
} else {
cipherText += ch;
}
}
return cipherText;
}
// Decrypt
public static String decrypt(String plainText, int shift) {
if (shift > 26) {
shift = shift % 26;
} else if (shift < 0) {
shift = (shift % 26) + 26;
}
String cipherText = "";
int length = plainText.length();
for (int i = 0; i < length; i++) {
char ch = plainText.charAt(i);
if (Character.isLetter(ch)) {
if (Character.isLowerCase(ch)) {
char c = (char) (ch - shift);
if (c < 'a') {
cipherText += (char) (ch + (26 - shift));
} else {
cipherText += c;
}
} else if (Character.isUpperCase(ch)) {
char c = (char) (ch + shift);
if (c < 'A') {
cipherText += (char) (ch + (26 - shift));
} else {
cipherText += c;
}
}
} else {
cipherText += ch;
}
}
return cipherText;
}
public static void main(String[] args) {
Scanner input1 = new Scanner(System.in);
Scanner input2 = new Scanner(System.in);
System.out.print("Enter your phrase: ");
String inputPlainText = input1.nextLine();
System.out.print("Enter your shift: ");
int shiftForPlainText = input1.nextInt();
String convertPlainText = encrypt(inputPlainText, shiftForPlainText);
System.out.println(convertPlainText);
System.out.print("Enter ciphertext: ");
String inputCipherText = input2.nextLine();
System.out.print("Enter shift: ");
int shiftForCipherText = input2.nextInt();
String convertCipherText = decrypt(inputCipherText, shiftForCipherText);
System.out.println(convertCipherText);
}
}
In decrypt method, for lower case you write:
char c = (char)(ch-shift);
and for upper case you write:
char c = (char)(ch+shift);
I'm pretty sure that both lines should have the same operator between ch and shift. If you don't want to make such mistakes, try to refactor your code so there are no duplicate lines.
I've created a wonderfully working program that encrypts the text a person enters with a keyword of their choice. The program can decrypt the encrypted message/text by going in decrypt mode and entering the correct key.
Now my problem is that when I enter a text in the Linux shell that's longer than approximately 5000 characters, it doesn't process all the text. I used this German dummy text that's 15954 characters long. If I enter the text in the Linux shell It cuts off my text at about 4025 characters. On the other hand, if I execute the program in IntelliJ everything works like a charm. If you need the code I got on git here.
Thanks in advance. I appreciate the help.
My Start class that starts everything
public class Start
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.print("Would you like to encrypt or decrypt a message? [d/e]\n>");
char de = scanner.nextLine().charAt(0);
boolean _Encrypt = true;
if (de == 'd')
_Encrypt = false;
else if (de == 'e')
;
else
{
System.out.println("Non valid input. Please try again later.");
System.exit(1);
}
char[] text = ch.wagner.root.viginere.Input.getText("Text:\n>");
char[] key = ch.wagner.root.viginere.Input.getKey("Key:\n>");
if (_Encrypt)
{
System.out.println(ch.wagner.root.viginere.Process.encrypt(text, key));
}
else
{
System.out.println(ch.wagner.root.viginere.Process.decrypt(text, key));
}
}
}
My Input class
public class Input
{
public static char[] getText (String requestMessage)
{
boolean _AllowedToContinue = false;
char[] text = null;
while (!_AllowedToContinue)
{
System.out.print(requestMessage);
text = ch.wagner.root.viginere.Input.getCharArray();
if (!Input.inputValid(new String(text), "[^`^]+$"))
System.out.println("Invalid input. Try again.");
else
_AllowedToContinue = true;
}
// System.err.println(new String(text).length());
// Created this to check the length of the String after input
return text;
}
public static char[] getKey (String requestMessage)
{
boolean _AllowedToContinue = false;
char[] key = null;
while (!_AllowedToContinue)
{
System.out.print(requestMessage);
key = ch.wagner.root.viginere.Input.getCharArray();
if (!Input.inputValid(new String(key), "^[A-Za-z]+$"))
System.out.println("Invalid input. Try again.");
else
_AllowedToContinue = true;
}
return key;
}
private static boolean inputValid (String input, String regex)
{
boolean returnValue = true;
final Pattern pattern = Pattern.compile(regex);
if (!pattern.matcher(input).matches()) {
returnValue = false;
}
return returnValue;
}
private static String getString ()
{
Scanner scanner = new Scanner(System.in);
return scanner.nextLine();
}
private static char[] getCharArray ()
{
return getString().toCharArray();
}
}
The Process class that encrypts/decrypts the text
public class Process
{
public static String decrypt(char[] text, char[] key)
{
int[] shift = new int[key.length];
key = new String(key).toUpperCase().toCharArray();
for (int i = 0; i < shift.length; i++)
shift[i] = key[i] - 65;
int ii = 0;
for (int i = 0; i < text.length; i++)
{
if (ii == shift.length)
ii = 0;
if (Character.isLetter(text[i]))
{
if (((((text[i] - 65) - shift[ii]) % 26) + 65) < 65)
text[i] = (char) (((((text[i] - 65) - shift[ii]) % 26) + 65) + 26);
else
text[i] = (char) ((((text[i] - 65) - shift[ii]) % 26) + 65);
}
ii++;
}
return new String(text);
}
public static String encrypt(char[] text, char[] key)
{
int[] shift = new int[key.length];
key = new String(key).toUpperCase().toCharArray();
for (int i = 0; i < shift.length; i++)
{
shift[i] = key[i] - 65;
}
text = new String(text).replaceAll("[^a-zA-Z0-9|/()*]+", "").toCharArray();
int ii = 0;
for (int i = 0; i < text.length; i++)
{
if (ii == shift.length)
ii = 0;
text[i] = Character.toUpperCase(text[i]);
if (Character.isLetter(text[i]))
text[i] = (char)((((text[i] - 65) + shift[ii]) % 26) + 65);
ii++;
}
return new String(text);
}
}
I have 2 java programs (ciphers), one is Playfair and second is Transposition.
Now i want to run Playfair code, then right after that compile Transposition using the result i got from Playfair code. How should i make this?(
Playfair code
import java.awt.Point;
import java.util.Scanner;
public class PlayfairCipher {
private static char[][] charTable;
private static Point[] positions;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String key = prompt("Enter an encryption key (min length 6): ", sc, 6);
String txt = prompt("Enter the message: ", sc, 1);
String jti = prompt("Replace J with I? y/n: ", sc, 1);
boolean changeJtoI = jti.equalsIgnoreCase("y");
createTable(key, changeJtoI);
String enc = encode(prepareText(txt, changeJtoI));
System.out.printf("%nEncoded message: %n%s%n", enc);
System.out.printf("%nDecoded message: %n%s%n", decode(enc));
}
private static String prompt(String promptText, Scanner sc, int minLen) {
String s;
do {
System.out.print(promptText);
s = sc.nextLine().trim();
} while (s.length() < minLen);
return s;
}
private static String prepareText(String s, boolean changeJtoI) {
s = s.toUpperCase().replaceAll("[^A-Z]", "");
return changeJtoI ? s.replace("J", "I") : s.replace("Q", "");
}
private static void createTable(String key, boolean changeJtoI) {
charTable = new char[5][5];
positions = new Point[26];
String s = prepareText(key + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", changeJtoI);
int len = s.length();
for (int i = 0, k = 0; i < len; i++) {
char c = s.charAt(i);
if (positions[c - 'A'] == null) {
charTable[k / 5][k % 5] = c;
positions[c - 'A'] = new Point(k % 5, k / 5);
k++;
}
}
}
private static String encode(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length(); i += 2) {
if (i == sb.length() - 1)
sb.append(sb.length() % 2 == 1 ? 'X' : "");
else if (sb.charAt(i) == sb.charAt(i + 1))
sb.insert(i + 1, 'X');
}
return codec(sb, 1);
}
private static String decode(String s) {
return codec(new StringBuilder(s), 4);
}
private static String codec(StringBuilder text, int direction) {
int len = text.length();
for (int i = 0; i < len; i += 2) {
char a = text.charAt(i);
char b = text.charAt(i + 1);
int row1 = positions[a - 'A'].y;
int row2 = positions[b - 'A'].y;
int col1 = positions[a - 'A'].x;
int col2 = positions[b - 'A'].x;
if (row1 == row2) {
col1 = (col1 + direction) % 5;
col2 = (col2 + direction) % 5;
} else if (col1 == col2) {
row1 = (row1 + direction) % 5;
row2 = (row2 + direction) % 5;
} else {
int tmp = col1;
col1 = col2;
col2 = tmp;
}
text.setCharAt(i, charTable[row1][col1]);
text.setCharAt(i + 1, charTable[row2][col2]);
}
return text.toString();
}
}
and Transposition
import java.util.*;
import java.util.Scanner; // needed for Scanner
public class transpositionCipher
{
public static void main(String args[])
{
String key;
String message;
String encryptedMessage;
// Letters in the x-axis
int x=0;
// Letters in the y-axis
int y=0;
// Prompt the user
System.out.print( "Type your Key : " );
// Read a line of text from the user.
Scanner scan = new Scanner(System.in);
key = scan.nextLine();
// Display the input back to the user.
System.out.println( "Your Key is " + key );
//Prompt the user
System.out.print( "Type your Message : " );
//Read a line of text from the user.
message = scan.nextLine();
//Display the input back to the user.
System.out.println( "Your Message is " + message );
int msgchar = message.length();
int keycahr = key.length();
if (!((msgchar % keycahr) == 0)){
do{
message = message + "x";
msgchar = message.length();
}while(!((msgchar % keycahr) == 0));
}
encryptedMessage = "";
// To set the temp as [x][y]
char temp[][]=new char [key.length()][message.length()];
char msg[] = message.toCharArray();
// To populate the array
x=0;
y=0;
// To convert the message into an array of char
for (int i=0; i< msg.length;i++)
{
temp[x][y]=msg[i];
if (x==(key.length()-1))
{
x=0;
y=y+1;
} // Close if
else
{
x++;
}
} // Close for loop
// To sort the key
char t[]=new char [key.length()];
t=key.toCharArray();
Arrays.sort(t);
for (int j=0;j<y;j++)
{
for (int i=0;i<key.length();i++)
{
System.out.print(temp[i][j]);
}
System.out.println();
}
System.out.println();
// To print out row by row (i.e. y)
for (int j=0;j<y;j++){
// To compare the the sorted Key with the key
// For char in the key
for (int i=0;i<key.length();i++){
int pos=0;
// To get the position of key.charAt(i) from sorted key
for (pos=0;pos<t.length;pos++){
if (key.charAt(i)==t[pos]){
// To break the for loop once the key is found
break;
}
}
System.out.print(temp[pos][j]);
encryptedMessage+=temp[pos][j];
}
System.out.println();
}
System.out.println(encryptedMessage);
System.exit(0);
}enter code here
}
Take the output of one operation (PlayfairCipher.encode), which is the cyphertext and input it to the second operation (your transpositionial code) as it's plaintext.
Scanner sc = new Scanner(System.in);
String key = prompt("Enter an encryption key (min length 6): ", sc, 6);
String txt = prompt("Enter the message: ", sc, 1);
String jti = prompt("Replace J with I? y/n: ", sc, 1);
boolean changeJtoI = jti.equalsIgnoreCase("y");
PlayfairCipher.createTable(key, changeJtoI);
String enc = PlayfairCipher.encode(prepareText(txt, changeJtoI));
//Now instead of using 'message' for the second encryption, you use the output of the first operation 'enc'
int x=0;
int y=0;
int msgchar = enc.length();
int keycahr = key.length();
if (!((msgchar % keycahr) == 0)){
do{
enc = enc + "x";
msgchar = enc.length();
}while(!((msgchar % keycahr) == 0));
}
...
Hello evrybody who reads this!
I need to realize Vigenere cipher on Java.
I have a .txt document, which I'm going to read, encode and decode. Here it is:
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
My problem is that I don't know how to shift chars correctly, According to this table latin letters have codes from 0061 to 007A. German ones that I need: 00C0 - 00FF, polish: 0100-017F, russian 0430-044F and I didn't gind chineese.
How can I specify unshiftChar and shiftChar to make it correst?
Now my input looks like this:
The original text from file is:
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
String that will be encoded is:
asciiabcdexyzgermanäöüäöüßpolishąęźżńłrussianабвгдежэюяcjk你好
The encrypted string is:
äckkwdfaqmzjökcbucäbdslhwfssjvåjoxfbsltfvwgnvboegbrnboeghxöb
The decrypted phrase is:
asciiab¥dexyzgrmanäöäöuupo○ibmjcåäldhtciwmtdåawmtddpw
Here is a Java code:
public class VigenereCipher
{
public static void main(String[] args) throws IOException
{
String key = "Unicode";
File file = new File("G:\\unicode.txt");
FileInputStream fis = new FileInputStream(file);
byte[] fileBArray = new byte[fis.available()];
fis.read(fileBArray);
String text = new String(fileBArray, "UTF-8");
//String text = "Some simple text to check the decoding algorythm";
System.out.println("The original text from file is: \n" + text);
String enc = encrypt(text, key);
System.out.println(enc + "\n");
System.out.println("The decrypted phrase is: ");
System.out.println(decrypt(enc, key));
}
// Encrypts a string
public static String encrypt(String message, String key)
{
message = StringToLowerCaseWithAllSymbols(message);
System.out.println("String that will be encoded is: \n" + message);
char messageChar, keyChar;
String encryptedMessage = "";
for (int i = 0; i < message.length(); i++)
{
messageChar = shiftChar(message.charAt(i));
keyChar = shiftChar(key.charAt(i % key.length()));
messageChar = (char) ((keyChar + messageChar) % 29);
messageChar = unshiftChar(messageChar);
encryptedMessage += messageChar;
}
System.out.println("\nThe encrypted string is: ");
return encryptedMessage;
}
// Decrypts a string
public static String decrypt(String cipher,String key)
{
char cipherChar, keyChar;
cipher = StringToLowerCaseWithAllSymbols(cipher);
String decryptedMessage = "";
cipher = cipher.toLowerCase();
for (int i = 0; i < cipher.length(); i++)
{
cipherChar = shiftChar(cipher.charAt(i));
keyChar = shiftChar(key.charAt(i % key.length()));
cipherChar = (char) ((29 + cipherChar - keyChar) % 29);
cipherChar = unshiftChar(cipherChar);
decryptedMessage += cipherChar;
}
return decryptedMessage;
}
// Prunes all characters not in the alphabet {A-Öa-ö} from a string and changes it to all lower case.
public static String StringToLowerCaseWithAllSymbols(String s)
{
//s = s.replaceAll("[^A-Za-zåäöÅÄÖ]", "");
// 's' contains all the symbols from my text
s = s.replaceAll("[^A-Za-zäöüÄÖÜßąęźżńłабвгдежэюя你好]", "");
return s.toLowerCase();
}
// Assigns characters a,b,c...å,ä,ö the values 1,2,3...,26,28,29.
private static char shiftChar(char c)
{
if (96 < c && c < 123)
{
c -= 97;
}
else if (c == 229)
{
c = 26;
}
else if (c == 228)
{
c = 27;
}
else if (c == 246)
{
c = 28;
}
return c;
}
// Undoes the assignment in shiftChar and gives the characters back their UTF-8 values.
private static char unshiftChar(char c)
{
if (0 <= c && c <= 25)
{
c += 97;
}
else if (c == 26)
{
c = 229;
}
else if (c == 27)
{
c = 228;
}
else if (c == 28)
{
c = 246;
}
return c;
}
}
First of all, you don't want to shift: You want to rotate. Suppose we're working with the English alphabet. If 'A'+2 is 'C', what's 'Z'+2? When you're implementing a Vigenere cipher, you want 'Z'+2=='B'.
I would would not use Unicode in a Vigenere cipher program: I would use my own encoding in which the first letter of the alphabet is represented by zero, the second letter is represented by one, and so on. So, for my English example, code('A')==>0, code('B')==>, ... code('Z')==>26.
Then my rotation function looks like this:
int rotate(Alphabet alphabet, int code, int amount) {
return (code + amount) % alphabet.getLength();
}
So:
rotate(english, code('A'), 2) ==> (0 + 2)%26 == 2, (the code for 'C'), and
rotate(english, code('Z'), 2) ==> (25 + 2)%26 == 1, (the code for 'B').