Vigenere encryption,but keeping text file structure - java

public static void novelEncryption() throws Exception {
try {
fw = new FileWriter("H:/workspace/Exercise2/src/VigenèreCipherNovel.txt");
} catch (Exception e) {
}
String res = "";
for (int i = 0, j = 0; i < plaintext.length(); i++) {
char c = plaintext.charAt(i);
if(c < 'a'|| c > 'z'){
continue;
}
else if (c=='\n'){
ciphertext = ciphertext + "\n";
}
res += (char) ((c + getKey().charAt(j) - 2 * 'a') % 26 + 'a');
j = ++j % getKey().length();
}
ciphertext=res;
fw.write(ciphertext);
fw.close();
}
Basically I am doing an implementation of the Vigenere Cipher and I am trying to make an encryption method.Everything works fine,but I want to keep the structure of the String ciphertext the same as the String plaintext.In other words the plaintext String I am iterating through has paragraphs and white spaces. When the encryption is done the txt file has one big String(one word).I want to keep the paragraphs and white spaces between words after encryption,but I am not sure how to do this
P.S. The String plaintext looks like this.(has spaces between words and paragraphs)
Click to view the plain text
And I want to achieve something like this
Click to see what I want to achieve

Related

Cannot decode some passwords?

I added a password checker for my program, I thought it works fine since I could save the password in a file (encoded) and could enter the password in the password field and it let me into the main program without problems. However, today I was testing more and I found out that some passwords do not work and I have no idea why that is the case.
I included both my methods, one does encode the password, the other one does decode it. The verify method I included is the one that reads from the password file, decodes the password and checks if the entered password equals the saved one. I couldnt find out what types of passwords do not work, its not the length, more like the characters which were used.
Thanks in advance
public static char[] encode(int offset, char[] charArray) {
char[] arrEnc = new char[charArray.length];
for (int i = 0; i < charArray.length; i++) {
int verschiebung = (charArray[i] + offset) % 128;
arrEnc[i] = (char) (verschiebung);
}
return arrEnc;
}
public static char[] decode(int offset, char[] charArray) {
char[] arrEnc = new char[charArray.length];
int verschiebung;
for (int i = 0; i < charArray.length; i++) {
if (charArray[i] - offset < 0) {
verschiebung = charArray[i] - offset + 128;
} else {
verschiebung = (charArray[i] - offset) % 128;
arrEnc[i] = (char) (verschiebung);
}
}
return arrEnc;
}
private void verify() {
try {
FileReader fr = new FileReader(pws);
BufferedReader br = new BufferedReader(fr);
char[] arr = br.readLine().toCharArray();
char[] newArr = decode(arr.length, arr);
String pw = new String(newArr);
String masterPw = "Kassa";
if (passwordField.getText().equals(pw) ||
passwordField.getText().equals(masterPw)) {
setVisible(false);
starto.setVisible(true);
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Any password should be able to be saved and decoded
You have a mistake in the code.
if (charArray[i] - offset < 0) {
verschiebung = charArray[i] - offset + 128;
...
Here you forgot to put
arrEnc[i] = (char) (verschiebung);
So you should assign verschiebung to arrEnc[i] in the first condition block in the decode method.

xOr decryption replaces correct letter with wrong letter throughout the whole text file

Java: I'm encrypting and decrypting a text file using a key of any two ASCII characters on the keyboard. I have them working correctly, except when I read the encrypted file to a string for decryption. It replaces some specific letter with a different incorrect letter, but not all of correct letters are replaced. Some t's are replaced with s's for example. I've also seen some b's be replaced with e's when I use a different key.
I've already looked through my encrypted/decryption algorithm. I copy and pasted the encrypted text file into my code and ran the algorithm again, it came out perfect. The only time the letters are replaced is when the encrypted algorithm is read from a text file to be decrypted.
public static String readFileToString(string filePath) {
StringBuilder builder = new StringBuilder();
try (Stream<String> stream = Files.get(filePath), StandardCharsets.UTF_8)){
stream.forEach(s->builder.append(s).append("\n");
}
catch(IOException e){
e.printStackTrace();
}
return builder.toString();
}
public static void writeFile(String crypt) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("New file name: ");
String fileName = sc.nextLine();
String writtenString = crypt;
String userHome = System.getProperty("user.home");
File textFile = new File(userHome, fileName + ".txt");
BufferedWriter out = new BufferedWriter(new FileWriter(textFile));
out.write(writtenString);
out.close();
//Converts string and key into binary characters for 1-to-1 xOr to prevent any possible translation errors.
public static String crypt(String input, String key) throws UnsupportedEncodingException {
if (input.length() % 2 == 1) {
input = input + " ";
}
int n = input.length() / 2;
key = new String(new char[n]).replace("\0", key);
byte[] a = input.getBytes();
byte[] c = key.getBytes();
StringBuilder binaryBuilder = new StringBuilder();
StringBuilder binaryKeyBuilder = new StringBuilder();
//Creates a StringBuilder of bits using the file text
for(byte b: a) {
int value = b;
for(int i = 0; i < 8; i++) {
binaryBuilder.append((value & 128) == 0 ? 0 : 1);
value <<= 1;
}
binaryBuilder.append(' ');
}
//Converts binary StringBuilder to String
String binary = binaryBuilder.toString();
//Creates a StringBuilder of bits using the provided key
for(byte d: c) {
int keyValue = d;
for(int j = 0; j < 8; j++) {
binaryKeyBuilder.append((keyValue & 128) == 0 ? 0 : 1);
keyValue <<= 1;
}
binaryKeyBuilder.append(' ');
}
//Converts binaryKey StringBuilder to String
String binaryKey = binaryKeyBuilder.toString();
//Creates StringBuilder of bits using the provided key
StringBuilder xOr = new StringBuilder();
for(int q = 0; q < binary.length();q++) {
xOr.append(binary.charAt(q) ^ binaryKey.charAt(q));
}
String xOrResult = xOr.toString();
String cryptedString = "";
char next;
//Iterates through binary string to convert to ASCII characters 8 bits at a time.
for(int k = 0; k <= xOrResult.length()-8; k+=9) {
next = (char)Integer.parseInt(xOrResult.substring(k,k+8), 2);
cryptedString += next;
}
return cryptedString;
}
When I use the key "ty"
"Four score and seven years ago our fathers brought forth on this" is the correct phrasing.
However, I'm getting: "Four score and seven years ago our fashers broughs forth on this"
I would use binary file for encrypted text. It will save you from dealing with UTF-8 encoding/decoding some unusual code points. For example - when you xor 't' and 't' you get character with code 0.
You can also get unexpected new line characters. You actually replace all of them with '\n', but there are other options - '\r', or even two characters in sequence "\r\n". All of them will be replaced with '\n' in your code, and lead to mistakes after decryption.
What happened here:
Binary ASCII (or UTF-8) code for t is 01110100, and for y it is 01111001. When character y from key meets character t from text you get 01110100 xor 01111001 = 00001101 = 0x0D = '\r'. This character is written to file. When you read that file line by line, this '\r' is skipped as line separator. You replace it with '\n'=00001010 in line
stream.forEach(s->builder.append(s).append("\n");
When decrypting that text we get 00001010 (\n) xor 01111001 (y) = 01110011 (s).

Attempting to decrypt encrypted hexadecimal code, find key, and convert to english

Goal: Decode encrypted hex, which requires finding an unknown, single character key
I was purely trying to do the problem by XOR'ing each character in xOR with each of the ascii characters. I was expecting to get a String of hexes as one of my outputs. However, my catch statement says that every string it returns is not hex.
I then planned to take these converted hexvalues and just cast them as chars.
If you could offer me some guidance on how to fix this atrocity, it would be greatly appreicated.
Thanks a bunch!
//intention of this program is to decrypt this string of encoded hex, find the key, and decrpt the message
//however, its not really working. It doesnt print values prior to 112 even though those values arent blank
// as I checked in debugger
public static void main(String[] args) throws UnsupportedEncodingException
{
String xOr1 = ("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736");
String xOr = "z({zzz{{z-{z{z{{{}z*{y)~x~x~{{rzsz(";
String result = "";
System.out.println("xOr1 length is " + xOr1.length());
String output = "";
byte[] encoded = xOr1.getBytes();
byte[] decoded;
String sub;
String matches = "(.*)abdef0123456789(.*)";
int hexInt;
for(int k = 0; k< 256;k++)
{
decoded = new byte[encoded.length];
result = "";
System.out.println(k);
for(int j = 0; j<encoded.length; j++)
{
decoded[j] = (byte)((int)encoded[j] ^ k);
result = Arrays.toString(decoded);
}
output = new String(decoded,"UTF-8");
//System.out.println(output);
try
{
for(int i = 0; i< output.length() -2; i++)
{
hexInt = Integer.parseInt(output,16);
System.out.println("You aren't dumb... " + output);
}
}
catch(NumberFormatException nfe)
{
//System.out.println(output);
System.out.println("bad boy");
}
}
}

Keep Spaces, Punctuation, and char Cases in Java Caesar Cipher

I'm trying to encrypt a txt file, but when i send my chars to array I lose my spaces. I want to keep my spaces along with punctuation and cases of letters. I am so close but cannot seem to do anything that doesn't make A.) everything a null character or B.) loop capital letters. Thanks in advance.
public class Encryption {
CaesarCipher c= new CaesarCipher();
Scanner kb = new Scanner(System.in);
String end = "";
public void changeLetters(File file) {
System.out.println("How far would you like to shift?");
int shift = Integer.parseInt(kb.nextLine());
Scanner fileScanner;
try {
fileScanner = new Scanner(file);
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
shift(line, shift);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private void shift(String line, int shift) {
char[] og = line.toCharArray();
for (int i = 0; i < og.length; i++) {
char letter = og[i];
letter = (char) (letter + shift);
if (letter > 'z') {
letter = (char) (letter - 26);
} else if (letter < 'a') {
letter = (char) (letter + 26);
}
end = end + Character.toString(letter);
}
System.out.println(end);
File file = new File("Encrypted.txt");
FileWriter writer = null;
{
try {
writer = new FileWriter(file);
writer.write(end);
writer.close();
} catch (
IOException e)
{
e.printStackTrace();
}
System.out.println("Decryption Complete");
System.out.println("Q to quit, C to Continue");
String response = kb.next();
if (response.equals("q") || response.equals("Q")) {
System.out.println("Goodbye");
} else if (response.equals("c") || response.equals("C")) {
c.getInformation();
}
}
}
I believe the problem comes from the fact you are adding (+/-) 26 to your letter, for example letter = (char) (letter - 26);. This would only work within the alphabet [a-z]. However as you want to be able to handle capital letters, special characters and such you can't do this.
It would also be cleaner to use the modulo operator % in order to do this. Hence you won't have to make an explicit test, like you did if (letter > 'z').
Here is the shift procedure, which is really simple
private String shift(String str, int shift) {
String shifted = "";
for(int i = 0; i < str.length(); i++) {
char original = str.charAt(i);
char shiftedChar = (char) ((original + shift) % Integer.MAX_VALUE);
shifted += shiftedChar; // Append shifted character to the end of the string
}
return shifted;
}
However i'm not sure this is the modulus to use. But i did some tests and this seemed to work.
Here is how you can shift and unshift
String test = "This is a test!";
String encoded = shift(test, 3);
String decoded = shift(encoded, -3);
System.out.println("Encoded : " + encoded + "\n" + "Decoded : " + decoded);

Character higher than "s" cant be encrypted?

I made simple encryption and decryption methods by following this video: http://www.youtube.com/watch?v=8AID7DKhSoM&feature=g-hist
however when its implemented in my program any character higher than "s" is encrypted to a "?"
and then decrypted to a 3. It doesn't seem to happen in the tutorial however even though some of his characters get increased by large numbers. So why does this happen?
Btw here's the relevant part of my program:
public class crypt {
public String encrypt(String pass){
String cryppass_string="";
int l= pass.length();
char ch;
for (int i=0; i<l; i++){
ch= pass.charAt(i);
ch+= 12;
cryppass_string+= ch;
}
return cryppass_string;
}
public String decrypt (String cryppass_string){
String pass_string= "";
int l= cryppass_string.length();
char ch;
for (int i=0; i<l; i++){
ch= cryppass_string.charAt(i);
ch-= 12;
pass_string += ch;
}
return pass_string;
}
}
Here's an example :
a password ("astu") needs to be encrypted so its entered, this is done:
char[] newpass= newPassField.getPassword();
char[] repass= rePassField.getPassword();
if(Arrays.equals( newpass , repass ))
{
if(number==1)
{
Login_info.McIntosh_custom_pwd= fileob.string_to_char(cryptob.encrypt(fileob.char_to_string(newpass)));
fileob.evr_tofile();
}
In another class McIntoshcrypted is declared as:
McIntosh_custom_pwd= fileob.string_to_char(cryptob.decrypt(FileData[0]));
fileob is an object of class Files
cryptob is an object of class crypt
public class Files {
File f= new File("Eng Dept.txt");
public Formatter x;
public void openfile(){
try{
x= new Formatter ("Eng Dept.txt");
}
catch (Exception error){
System.out.println("error");
}
}
public void writing(String towrite){
try{
String filename= "Eng Dept.txt";
String newLine = System.getProperty("line.separator");
FileWriter fw = new FileWriter(filename,true);
fw.write(towrite);
fw.write(newLine);
fw.close();
}
catch (Exception eror){
System.out.println("error");
}
}
public String reading_string(int linenum){
String readline= "";
String filename= "Eng Dept.txt";
int lineno;
try{
FileReader fr= new FileReader(filename);
BufferedReader br= new BufferedReader(fr);
for (lineno=1; lineno<= 1000; lineno++){
if(lineno== linenum){
readline= br.readLine();
}
else
br.readLine();
}
br.close();
}
catch (Exception eror){
System.out.println("error");
}
return readline;
}
public String char_to_string(char[] toconv){
int l= toconv.length;
String converted= "";
for (int i=0; i<l; i++)
{
converted+= toconv[i];
}
return converted;
}
public char[] string_to_char(String toconv){
int l= toconv.length();
char[] converted = new char[l];
for (int i= 0; i<l; i++)
{
converted[i]=toconv.charAt(i);
}
return converted;
}
public void evr_tofile()
{
f.delete();
openfile();
writing(char_to_string(Login_info.McIntosh_custom_pwd));
}
In the txt file "as??" is seen, and the result of
System.out.print(Login_info.McIntosh_custom_pwd);
is "as33". Hope I explained this correctly...
edit: tried solution
public String encrypt(String pass){
String cryppass_string="";
int l= pass.length();
int x=0;
char ch;
for (int i=0; i<l; i++){
ch= pass.charAt(i);
x= ((ch - 32) + 12) % 126 + 32;
ch = (char)x;
cryppass_string+= ch;
}
return cryppass_string;
}
public String decrypt (String cryppass_string){
String pass_string= "";
int l= cryppass_string.length();
int x=0;
char ch;
for (int i=0; i<l; i++){
ch= cryppass_string.charAt(i);
x= ch-32;
ch= (char)x;
if (ch < 0)
x= ch+126;
ch= (char)x;
x= ch-12+32;
ch= (char)x;
pass_string += ch;
}
return pass_string;
}
I'm guessing that you output the values to a text file (web page?) using an operation that converts unprintable characters to ?, then the decryption problem happens when you read it back in. If you want to do something like that, you'll need to restrict your encryption to output only printable characters. One way to do that is to use modular arithmetic to ensure that your encrypted character is within the printable set (ASCII 32 to ASCII 126). The code you have will transform properly if you read/write binary, but not if you output it as ASCII text.
Encrypt
ch = (char)((ch - 32) + 12) % 126 + 32; // extended expression to show rebasing/modulus
Decrypt
ch = ch - 32;
if (ch < 0) ch = ch + 126;
ch = ch - 12 + 32;

Categories

Resources