Removing redundant letters then declaring string as charArr - java

I'm trying to encrypt and decrypt strings using cipher text with a random keyword. The random keyword will be in a file "keyword.txt":
TROYONLINE
The string(s) will be in a separate file "input.txt":
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG
more lines here....
The cipher should use the keyword and a reversed alphabet without redundant letters. The cipher for keyword "TROYONLINE" would be:
TROYNLIEZXWVUSQPMKJHGFDCBA
Using this cipher, the above string will be encrypted to this:
HEN MGZOW RKQDS LQC XGUPNY QFNK HEN VTAB YQI
So far, I have this code:
import java.util.*;
import java.io.*;
public class reverseString
{
public static void main(String [] args)
{
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String cipher = "";
String newCipher;
String encrypt = "";
String ouput = "";
BufferedReader readerKeyword = null;
String key = "";
try
{
readerKeyword = new BufferedReader(new FileReader("keyword.txt"));
}
catch (FileNotFoundException fnfex)
{
System.out.println(fnfex.getMessage() + " File not found.");
System.exit(0);
}
try
{
while ((key = readerKeyword.readLine()) !=null)
{
StringBuffer sb = new StringBuffer();
int len = abc.length();
for(int i = len -1;i>=0;i--)
cipher = cipher + abc.charAt(i);
newCipher = sb.append(key).append(cipher).toString();
System.out.println(key);
System.out.println(removeDuplicates(newCipher));
}
}
catch (IOException ioex)
{
System.out.println(ioex.getMessage() + " Unable to read file.");
System.exit(0);
}
BufferedReader readerInput = null;
String lineInput;
try
{
readerInput = new BufferedReader(new FileReader ("input.txt"));
}
catch (FileNotFoundException fnfex)
{
System.out.println(fnfex.getMessage() + " File not found.");
System.exit(0);
}
try
{
while ((lineInput = readerInput.readLine()) !=null)
{
char[] inputArray = lineInput.toCharArray();
System.out.println(inputArray);
}
}
catch (IOException ioex)
{
System.out.println(ioex.getMessage() + " Unable to read file.");
}
}
static String removeDuplicates(String newCipher)
{
char[] charArr = newCipher.toCharArray();
Set<Character> charSet = new LinkedHashSet<Character>();
for(char ch : charArr)
{
charSet.add(ch);
}
StringBuffer StrBuf = new StringBuffer();
for(char c : charSet)
{
StrBuf.append(c);
}
char[] cipherArray = removeDuplicates(newCipher).toCharArray();
System.out.println(cipherArray);
return StrBuf.toString();
}
}
But I'm getting the below error:
TROYONLINE
Exception in thread "main" java.lang.StackOverflowError
at java.util.HashMap.<init>(HashMap.java:456)
at java.util.LinkedHashMap.<init>(LinkedHashMap.java:347)
at java.util.HashSet.<init>(HashSet.java:161)
at java.util.LinkedHashSet.<init>(LinkedHashSet.java:154)
at reverseString.removeDuplicates(reverseString.java:83)
at reverseString.removeDuplicates(reverseString.java:94)
With a ton of repeats of the last line ...(reverseString.java:94)

EDIT
Belows is how I would do this in your situation. But keep this in mind:
It makes no sense to have your key and the input text in files. If you have a lot of input lines then you would pass the key as a command line argument and have only one while loop that reads the input file and uses the same key to encrypt and decrypt. If you do have multiple keys, then you need to read each key and then read the whole input file line by line, then read the next key and read the input file again, etc., etc.
I have all of the logic in the main method but you should break it down into separate methods.
Main class:
String defaultAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
BufferedReader keyInputLine;
String key;
String cipher = "";
BufferedReader inputLine;
String inputText;
StringBuilder encryptedText;
StringBuilder decryptedText;
try {
keyInputLine = new BufferedReader(new FileReader("keyword.txt"));
while ((key = keyInputLine.readLine()) != null) {
System.out.println("key: " + key);
StringBuilder stringBuilder = new StringBuilder();
// cipher is the key word plus the reverse of the alphabet
cipher = stringBuilder.append(key).append(new StringBuilder(defaultAlphabet).reverse().toString()).toString();
System.out.println("cipher: " + cipher);
// remove duplicates from cipher
cipher = removeDuplicates(cipher);
System.out.println("replaced cipher: " + cipher);
}
inputLine = new BufferedReader(new FileReader("input.txt"));
while ((inputText = inputLine.readLine()) != null) {
System.out.println("original: " + inputText);
encryptedText = new StringBuilder();
for (char c : inputText.toCharArray()) {
// find the input letter in the alphabet
if (defaultAlphabet.indexOf(c) != -1) {
// replace with same index from the cipher
encryptedText.append(cipher.toCharArray()[defaultAlphabet.indexOf(c)]);
} else {
// if not found, use default (ex: space)
encryptedText.append(c);
}
}
System.out.println("encrypted: " + encryptedText.toString());
decryptedText = new StringBuilder();
for (char c : encryptedText.toString().toCharArray()) {
// find the encrypted letter in the cipher
if (cipher.indexOf(c) != -1) {
// replace with same index from the cipher
decryptedText.append(defaultAlphabet.toCharArray()[cipher.indexOf(c)]);
} else {
// if not found, use default (ex: space)
decryptedText.append(c);
}
}
System.out.println("decrypted: " + decryptedText.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
The remove duplicates method:
static String removeDuplicates(String cipher) {
Set<Character> charSet = new LinkedHashSet<Character>();
for (char ch : cipher.toCharArray()) {
charSet.add(ch);
}
StringBuilder stringBuilder = new StringBuilder();
for (char c : charSet) {
stringBuilder.append(c);
}
return stringBuilder.toString();
}
Previous Answer
It's like the error says, the "lineKeyword" variable is not initialized before being used. Consider that it is possible that there is an exception in your second try/catch. The exception is caught and you print a message but "lineKeyword" is still uninitialized.
There is a good answer here: Uninitialized variables and members in Java
The language defines it this way.
Instance variables of object type default to being initialized to null. Local variables of object type are not initialized by default and it's a compile time error to access an undefined variable.
See section 4.5.5 in here http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#96595

I ended up putting my cipher code in a the while loop on the BufferedReader code and it cleared it up.
{
BufferedReader readerKeyword = null;
String key = "";
try
{
readerKeyword = new BufferedReader(new FileReader("keyword.txt"));
}
catch (FileNotFoundException fnfex)
{
System.out.println(fnfex.getMessage() + " File not found.");
System.exit(0);
}
try
{
while ((key = readerKeyword.readLine()) !=null)
{
StringBuffer sb = new StringBuffer();
int len = abc.length();
for(int i = len -1;i>=0;i--)
cipher = cipher + abc.charAt(i);
newCipher = sb.append(key).append(cipher).toString();
System.out.println(key);
System.out.println(removeDuplicates(newCipher));
}
}
catch (IOException ioex)
{
System.out.println(ioex.getMessage() + " Unable to read file.");
System.exit(0);
}

Related

can't figure out initialization error - java [duplicate]

This question already has answers here:
Variable might not have been initialized error
(12 answers)
Closed 5 years ago.
I can not for the life of me figure out why I'm getting a "variable key might not have been initialized" error. I've entered my entire code because if I remove the BufferedReader and set the string equal to I don't get the error. Also, if I leave the BufferedReader part in and remove the StringBuffer part, string key initializes just fine. Please help! New to java (and programming in general).
import java.util.*;
import java.io.*;
public class reverseString {
public static void main(String [] args) {
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String cipher = "";
String input = "";
String newCipher;
String ouput = "";
BufferedReader readerKeyword = null;
String key;
try {
readerKeyword = new BufferedReader(new FileReader("keyword.txt"));
} catch (FileNotFoundException fnfex) {
System.out.println(fnfex.getMessage() + " File not found.");
System.exit(0);
}
try {
while ((key = readerKeyword.readLine()) !=null) {
System.out.println(key);
}
} catch (IOException ioex) {
System.out.println(ioex.getMessage() + " Unable to read file.");
System.exit(0);
}
StringBuffer sb = new StringBuffer();
int len = abc.length();
for(int i = len -1;i>=0;i--)
cipher = cipher + abc.charAt(i);
System.out.println(abc);
System.out.println(cipher);
newCipher = sb.append(key + cipher).toString();
System.out.println(newCipher);
System.out.println(removeDuplicates(newCipher));
}
static String removeDuplicates(String newCipher) {
char[] charArr = newCipher.toCharArray();
Set<Character> charSet = new LinkedHashSet<Character>();
for(char ch : charArr) {
charSet.add(ch);
}
StringBuffer StrBuf = new StringBuffer();
for(char c : charSet) {
StrBuf.append(c);
}
return StrBuf.toString();
}
}
Was is not initialized in the while loop at line28?
IDE and Compiler shows it when it is not guaranteed initialization for safety/precaution. Do this and it should go away,
BufferedReader readerKeyword = null;
String key = null;
However, do make sure that it gets initialized.
It is not guaranteed initialization because it is inside a try-catch block and if you get an exception, you can get by without initialization because, you are handling it.

convert byte array to string in java

I try to convert byte array to string in java using new String( bytes, "UTF-8") method, but they only return the object. like this #AB4634bSbbfa
So, I searched some way to solve this problem.
I finally get valid string array, by converting hex-code to basic-character array.
like this. char[] chars = {"0", "1", ... "e", "f"};
This never happened before why do i have to convert hex-code to get valid string.
Here is method.
byte array which is hashed by Mac-sha-256 with specific key when i hashed.
public static String getHashString() {
String algorithm = "HmacSHA256";
String hashKey = "some_key";
String message = "abcdefg";
String hexed = "";
try {
Mac sha256_HMAC = Mac.getInstance(algorithm);
SecretKeySpec secret_key = new SecretKeySpec(hashKey.getBytes(), algorithm);
sha256_HMAC.init(secret_key);
byte[] hash = sha256_HMAC.doFinal(message.getBytes("UTF-8"));
// it doesn't work for me.
// hexed = new String(hash, "UTF-8");
// it works.
hexed = bytesToHex(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return hexed;
}
public static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
public static String bytesToHex(final byte[] data ) {
final int l = data.length;
final char[] hexChars = new char[l<<1];
for( int i=0, j =0; i < l; i++ ) {
hexChars[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
hexChars[j++] = HEX_DIGITS[0x0F & data[i]];
}
return new String(hexChars);
}
Thanks.
Following is a sample which shows Conversion of Byte array to String :-
public class TestByte
{
public static void main(String[] argv) {
String example = "This is an example";
byte[] bytes = example.getBytes();
System.out.println("Text : " + example);
System.out.println("Text [Byte Format] : " + bytes);
System.out.println("Text [Byte Format] : " + bytes.toString());
String s = new String(bytes);
System.out.println("Text Decryted : " + s);
}}
I'm not sure the string you get in the end is what you're after. I think a common scenario is to use
new BASE64Encoder().encode(hash)
which will return you the hashed message as String.
just do new String(byteArray);

Compare Strings read from txt file in java

I read a string from a txt file and I want compare this string with my reference. But it displays "not ok" and I don't know why.
public class ReadFile {
public static void main(String[] args) {
try {
File file = new File("nh.txt");
FileReader fileReader = new FileReader(file);
StringBuffer stringBuffer = new StringBuffer();
int numCharsRead;
//char[] charArray1 = new char[1024];
char[] charArray = new char[1024];
while ((numCharsRead = fileReader.read(charArray)) > 0) {
stringBuffer.append(charArray, 0, numCharsRead);
}
String resultat = new String(charArray);
String resultat1 = resultat.replaceAll("\\s", "");
System.out.println(resultat1);
String a="Nihao";
if(a.equals(resultat1)){System.out.println("ok");}
else System.out.println("not ok");
fileReader.close();
System.out.println("Contents of file:");
System.out.println(stringBuffer.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is because the string resultat1 is a 1024 char length, its possible to a java string to have \0, its in memory like this (if the file contains Niaho):
Nihao\0\0\0..
And because \0 is not a whitespace, this will not make any change:
resultat.replaceAll("\\s", "");
So you need to replace this char \0 with nothing:
resultat.replaceAll("\0", "");
or simply compare the reference string a to stringBuffer.toString() which is numCharsRead length:
if(a.equals(stringBuffer.toString())){System.out.println("ok");}
else System.out.println("not ok");

Reverse a string without using string functions [duplicate]

This question already has answers here:
Printing reverse of any String without using any predefined function?
(34 answers)
Closed 9 years ago.
How to write a java program to reverse a string without using string functions?
String a="Siva";
for(int i=0;i<=a.length()-1;i++)
{
System.out.print(a.charAt(i));
}
System.out.println("");
for(int i = a.length() - 1; i >= 0; --i)
{
System.out.print(a.charAt(i));
}
here charAt() and a.length() are string functions
This will help
public class StringReverse {
public static void main(String[] args){
String str = "Reverse";
StringBuilder sb = new StringBuilder(str);
str = sb.reverse().toString();
System.out.println("ReverseString : "+str);
}
}
There is no usage of String methods
String s = "abcdef";
char c[] = s.toCharArray();
for( int i = c.length -1; i>=0; i--)
System.out.print(c[i]);
Use StringBuilder class or StringBuffer class they have already a method reverse() for reversing the string
StringBuilder str = new StringBuilder("india");
System.out.println("string = " + str);
// reverse characters of the StringBuilder and prints it
System.out.println("reverse = " + str.reverse());
// reverse is equivalent to the actual
str = new StringBuilder("malayalam");
System.out.println("string = " + str);
// reverse characters of the StringBuilder and prints it
System.out.println("reverse = " + str.reverse());
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html
Below is ugly hack. It concept but it not invoke any String methods.
import java.io.*;
import java.util.*;
public class Hello {
public static String reverceWithoutStringMethods(String word){
String result = "";
//------ Write string to file -----------
BufferedWriter writer = null;
try {
writer = new BufferedWriter( new FileWriter("tempfile"));
writer.write(word);
}
catch ( IOException e) {}
finally {
try{
if ( writer != null) writer.close( );
}
catch ( IOException e){}
}
//------ read string from file -------------
RandomAccessFile f=null;
try {
f = new RandomAccessFile("tempfile", "r"); // Open file
int length = (int) f.length(); // Get length
// Read file
byte[] data = new byte[length];
f.readFully(data);
// Reverse data
for (int i=data.length; i>=0; i--){
result += (char)data[i-1];
}
} catch(Exception e){}
finally {
try{
f.close();
}
catch (Exception e){}
}
return result;
}
public static void main(String[] args) {
System.out.println(reverceWithoutStringMethods("Test"));
System.out.println(reverceWithoutStringMethods(""));
}
}
Output:
tseT

very long string as a response of web service

I am getting a really long string as the response of the web service I am collecting it in the using the StringBuilder but I am unable to obtain the full value I also used StringBuffer but had no success.
Here is the code I am using:
private static String read(InputStream in ) throws IOException {
//StringBuilder sb = new StringBuilder(1000);
StringBuffer sb = new StringBuffer();
String s = "";
BufferedReader r = new BufferedReader(new InputStreamReader( in ), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
s += line;
} in .close();
System.out.println("Response from Input Stream Reader >>>" + sb.toString());
System.out.println("Response from Input S >>>>>>>>>>>>" + s);
return sb.toString();
}
Any help is appreciated.
You can also split the string in array of strings in order to see all of them
String delimiter = "put a delimiter here e.g.: \n";
String[] datas=sb.toString().split(delimiter);
for(String string datas){
System.out.println("Response from Input S >>>>>>>>>>>>" + string);
}
The String may not print entirely to the console, but it is actually there. Save it to a file in order to see it.
I do not think that your input is too big for a String, but only not shown to the console because it doesn't accept too long lines. Anyways, here is the solution for a really huge input as characters:
private static String[] readHugeStream(InputStream in) throws IOException {
LinkedList<String> dataList = new LinkedList<>();
boolean finished = false;
//
BufferedReader r = new BufferedReader(new InputStreamReader(in), 0xFFFFFF);
String line = r.readLine();
while (!finished) {
int lengthRead = 0;
StringBuilder sb = new StringBuilder();
while (!finished) {
line = r.readLine();
if (line == null) {
finished = true;
} else {
lengthRead += line.length();
if (lengthRead == Integer.MAX_VALUE) {
break;
}
sb.append(line);
}
}
if (sb.length() != 0) {
dataList.add(sb.toString());
}
}
in.close();
String[] data = dataList.toArray(new String[]{});
///
return data;
}
public static void main(String[] args) {
try {
String[] data = readHugeStream(new FileInputStream("<big file>"));
} catch (IOException ex) {
Logger.getLogger(StackoverflowStringLong.class.getName()).log(Level.SEVERE, null, ex);
} catch (OutOfMemoryError ex) {
System.out.println("out of memory...");
}
}
System.out.println() does not print all the characters , it can display only limited number of characters in console. You can create a file in SD card and copy the string there as a text document to check your exact response.
try
{
File root = new File(Environment.getExternalStorageDirectory(), "Responsefromserver");
if (!root.exists())
{
root.mkdirs();
}
File gpxfile = new File(root, "response.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(totalResponse);
writer.flush();
writer.close();
}
catch(IOException e)
{
System.out.println("Error:::::::::::::"+e.getMessage());
throw e;
}

Categories