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);
Related
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.
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
I am trying to code a letter frequency program that counts the alphabetic characters from a .txt file and presents the frequency data in a 2 column table. I am struggling to call the function char2int from the function processFile. I am not sure if I need to use an if statement or not as well. Also I am summing up all the alphabetic characters and other characters. If someone can help explain what I am doing wrong I'd be grateful.
Here is my code:
final static int AlphabetSize = 26;
final static Scanner cin = new Scanner(System.in);
final static PrintStream cout = System.out;
final static int MaxBarLength = 50;
public static void main(String[] args) {
String fileName;
// get the file name
cout.print("Enter the file name: ");
fileName = cin.nextLine();
// process the file
try {
processFile(fileName);
}
catch (IOException e) {
e.printStackTrace();
} // end try
} // end main
static void processFile(final String fileName)
throws FileNotFoundException, IOException
{
FileInputStream inFile = new FileInputStream(fileName);
int inputValue;
// declare other variables you need
int counters [] = new int [26];
int alpha = 0;
int num = 0;
int ticker = 0;
// get the first character from file
inputValue = inFile.read();
while (inputValue != -1) {
char ch = (char) inputValue;
// add code to process this character
if (){
counters[char2int(ch)]++;
alpha++;
}else{
num++;
}
// read next input character
inputValue = inFile.read();
} // end loop
inFile.close();
System.out.println("\nThe data file has " + alpha + " alphabetic, and " + num + " other characters.\n");
// generate appropriate output
display(counters);
} // end function
static void display(final int [] counters) {
// write code for this function
System.out.println("Letter" + " " + "Count" + " " + "Bar");
System.out.println("------" + " " + "-----" + " " + "---");
printChars(counters);
} // end function
// char2int is complete
static int char2int(final char arg) {
if (!Character.isLetter(arg))
return -1;
else
return (int) Character.toUpperCase(arg) - (int) 'A';
} // end function
// function printChars writes n copies of the character c to the
// standard output device
static void printChars (final int[] counters) {
// write the code
for (int i = 0; i < 26; i++){
System.out.printf("%c%7d\n", i + 'A', counters[i]);
}
// end printChars
} // end function
I would personally do it this way William:
int c = char2int(ch);
if (c >= 0) {
counters[c]++;
alpha++;
}
else { num++; }
You should also consider taking care of non-alphabetic characters should there be any within the text file. This can also be handled within the char2int() method.
I'm trying to get this to print how many letter "a" there are.
It keeps giving me 0...any help?
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
File myfile = chooser.getSelectedFile();
try {
Scanner in = new Scanner(myfile);
String word = in.nextLine();
int counter = 0;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == 'a') {
counter++;
}
}
System.out.println("# of chars: " + counter);
} catch (IOException e) {
System.err.println("A reading error occured");
}
}
A simpler (one line) way of counting occurrences of a char is:
int count = word.replaceAll("[^a]", "").length();
This replaces every character that's not an "a" with a blank - effectively deleting it - leaving you with a string containing just the "a" characters of the original string, then you get the length of that.
Beyond any issues reading the file, also try using the StringUtils countMatches. It's already in the common lang, mind as well use that instead.
For example
int count = StringUtils.countMatches(word, "a");
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
File myfile = chooser.getSelectedFile();
try {
Scanner in = new Scanner(myfile);
int counter = 0;
while(in.hasNextLine()){
String word = in.nextLine();
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == 'a') {
counter++;
}
}
}
System.out.println("# of chars: " + counter);
} catch (IOException e) {
System.err.println("A reading error occured");
}
}
I try to read a File char by char. Unfortunately Java ignores EOF while reading chars from file.
FileReader fileReader = new FileReader(fileText);
char c;
String word = "";
List<String> words = new ArrayList<String>();
while ((c = (char) fileReader.read()) != -1) {
System.out.println(c);
if (c != ' ') {
word = word + c;
}
else {
words.add(word + " ");
word = "";
}
}
It should break up after the file is read, but instead it never stops running....
In Java, char is unsigned and cannot equal -1. You should do the comparison before you do the cast.
int ch;
while ((ch = fileReader.read()) != -1) {
char c = (char)ch;
System.out.println(c);
...
}
This happens because char cannot be equal to -1, even if you assign -1 to it:
char c = (char)-1;
System.out.println(c == -1); // prints false
Make c an int, and cast it to char only when you concatenate:
word = word + (char)c;
Better yet, use StringBuilder to build strings at runtime: otherwise, you create lots of temporary string objects in a loop, and these objects get thrown away.
StringBuilder word = new StringBuilder();
List<String> words = new ArrayList<String>();
int c;
while ((c = fileReader.read()) != -1) {
System.out.println((char)c);
word.append((char)c);
if (c == ' ') {
words.add(word.toString());
word = new StringBuilder();
}
}
You should try the below code
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader(fileLocation);
int c;
String word = "";
List<String> words = new ArrayList<String>();
while ((c = (int) fileReader.read()) != -1) {
System.out.println((char)c);
char ch = (char)c;
if (ch != ' ') {
word = word + ch;
} else {
words.add(word + " ");
word = "";
}
}
System.out.println(word);
}