Base64 Failed to Decode String to Byte Array - java

I tried to decode a string to byte array using Base64. But it returned null. Here is the code:
LZW lzw = new LZW();
String enkripEmbedFileString = Base64.encode(byteFile);
List<Short> compressed = lzw.compress(enkripEmbedFileString);
String kompress = "";
Iterator<Short> compressIterator = compressed.iterator();
while (compressIterator.hasNext()) {
String sch = compressIterator.next().toString();
int in = Integer.parseInt(sch);
char ch = (char) in;
kompress = kompress + ch;
}
byteFile = Base64.decode(kompress);
I call "byteFile" variable at the last row in a code below this code and it throw NullPointerException.
I have check the "kompress" variable and it's not null. It contains a string.
All you need to know is, with that code I compress a string with LZW which require String for parameter and returns List<Short>. And, I convert the List<Short> to a String with a loop that you can see.
The problem is, why Base64 failed to convert String to byte[], after that String modified with LZW?
Whereas, if I decompress the String first and than return the decompressed String to be converted with Base64 to byte[], has no problem. It works. Here is the code which works:
//LZW Compress
LZW lzw = new LZW();
String enkripEmbedFileString = Base64.encode(byteFile);
List<Short> compressed = lzw.compress(enkripEmbedFileString);
String kompress = "";
Iterator<Short> compressIterator = compressed.iterator();
while (compressIterator.hasNext()) {
String sch = compressIterator.next().toString();
int in = Integer.parseInt(sch);
char ch = (char) in;
kompress = kompress + ch;
}
//Decompress
List<Short> kompressback = back(kompress);
String decompressed = decompress(kompressback);
byteFile = Base64.decode(decompressed);
Please, give me an explanation. Where is my fault?

Base64 decode can be applied only to strings that contain Base64 encoded data. Since you encode and then compress, the result is not Base64. You proved it yourself when you saw that uncompressing the data first allowed you to then decode the Base64 string.

Related

Byte Array, when converted to string, then concatenated, returns equal String but unequal byte array

I have a byte array. I need to concatenate a string with a delimiter to it. Then I want to get back the byte array. After all this logic, the output byte array is not equal to the input. In java:
This fails at the last line:
#Test
void test1() {
byte[] initialBytes = RandomUtils.nextBytes(64);
String initialString = new String(initialBytes, StandardCharsets.UTF_8);
String concatenatedString = String.join("\t", "Pre", initialString);
byte[] concatenatedStringToBytes = concatenatedString.getBytes(StandardCharsets.UTF_8);
String concatenatedBytesBackToString = new String(concatenatedStringToBytes, StandardCharsets.UTF_8);
int indexOfDelimeter = concatenatedBytesBackToString.indexOf("\t");
String finalString = concatenatedBytesBackToString.substring(indexOfDelimeter + 1);
byte[] finalBytes = finalString.getBytes(StandardCharsets.UTF_8);
assertEquals(initialString, finalString);
assertTrue(Arrays.equals(initialBytes, finalBytes));
}
In Java, String values use UTF_16.
Since UTF_16 and UTF_8 have different character coverage, conversions from UTF_8 to UTF_16 can result in loss of information (if those non-matching characters are used). So, when you convert back to UTF_8, you will not get the same byte array.
public static void tryCharsetEncodingForRandomBytes() {
byte[] initialBytes = getRandomBytes(64);
String initialString = new String(initialBytes, StandardCharsets.UTF_8);
byte[] finalBytes = initialString.getBytes(StandardCharsets.UTF_8);
String finalString = new String(finalBytes, StandardCharsets.UTF_8);
System.out.println(finalString.equals(initialString));
System.out.println(initialBytes.length);
System.out.println(finalBytes.length);
System.out.println(Arrays.equals(initialBytes, finalBytes));
}
Output :
true
64
103
false
You will not encounter this loss of information when dealing with more popular characrers like AlphaNumerics which are commons in both UTF_16 and UTF_8 charsets.
public static void tryCharsetEncodingForAlphanumeric() {
String alphaNumeric = "abcd1234";
byte[] initialBytes = alphaNumeric.getBytes(StandardCharsets.UTF_8);
String initialString = new String(initialBytes, StandardCharsets.UTF_8);
byte[] finalBytes = initialString.getBytes(StandardCharsets.UTF_8);
String finalString = new String(finalBytes, StandardCharsets.UTF_8);
System.out.println(finalString.equals(initialString));
System.out.println(initialBytes.length);
System.out.println(finalBytes.length);
System.out.println(Arrays.equals(initialBytes, finalBytes));
}
Output:
true
8
8
true
Which means that your tests will pass as long as you are dealing with common characters in UTF_8 and UTF_16.
public static void yourTestScenarioWithAlphaNumeric() {
String alphaNumeric = "abcdefghijklmop1234567890";
byte[] initialBytes = alphaNumeric.getBytes(StandardCharsets.UTF_8);
String initialString = new String(initialBytes, StandardCharsets.UTF_8);
String concatenatedString = String.join("\t", "Pre", initialString);
byte[] concatenatedStringToBytes = concatenatedString.getBytes(StandardCharsets.UTF_8);
String concatenatedBytesBackToString = new String(concatenatedStringToBytes, StandardCharsets.UTF_8);
int indexOfDelimiter = concatenatedBytesBackToString.indexOf("\t");
String finalString = concatenatedBytesBackToString.substring(indexOfDelimiter + 1);
byte[] finalBytes = finalString.getBytes(StandardCharsets.UTF_8);
System.out.println(finalString.equals(initialString));
System.out.println(Arrays.equals(initialBytes, finalBytes));
}
Output:
true
true

Converting byte array to String Java

I wish to convert a byte array to String but as I do so, my String has 00 before every digit got from the array.
I should have got the following result: 49443a3c3532333437342e313533373936313835323237382e303e
But I have the following:
Please help me, how can I get the nulls away?
I have tried the following ways to convert:
xxxxId is the byteArray
String xxxIdString = new String(Hex.encodeHex(xxxxId));
Thank you!
Try something like this:
String s = new String(bytes);
s = s.replace("\0", "")
It's also posible, that the string will end after the first '\0' received, if thats the case, first iterate through the array and replace '\0' with something like '\n' and do this:
String s = new String(bytes);
s = s.replace("\n", "")
EDIT:
use this for a BYTE-ARRAY:
String s = new String(bytes, StandardCharsets.UTF_8);
use this for a CHAR:
String s = new String(bytes);
Try below code:
byte[] bytes = {...}
String str = new String(bytes, "UTF-8"); // for UTF-8 encoding
please have a look here- How to convert byte array to string and vice versa?
In order to convert Byte array into String format correctly, we have to explicitly create a String object and assign the Byte array to it.
String example = "This is an example";
byte[] bytes = example.getBytes();
String s = new String(bytes);

Replace String in byte[]

Welcome,
I have a byte[] which is the binary representation of a String. And I wanted to replace a part of this String and get back the new byte[]!
I have tried:
String string = new String(array);
string = string.replace("#+#","SOME STRING");
array = string.getBytes();
The problem is that array is that the array afterwards is something different and not only because of the replacement.
The content of the array are serialized objects seperated with "#+#".
Be explicit about the character encoding you are using and use an encoding such as "Latin-1" where all byte sequences map to valid Unicode characters:
String string = new String(array, "Latin-1");
string = string.replace("#+#","SOME STRING");
array = string.getBytes("Latin-1");

MD5 encoded parameter in URL

I am using following code to encrypt my email id in Java and sending it as a parameter in url (Using URLEncoder.encode(encrypteInput("email"))):
public static String encrypteInput(String input) {
String output = null;
input = input + ((int) Math.random()) % 1000;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
output = new String(md5.digest(input.getBytes()));
} catch (Exception e) {
output = "";
}
return output;
}
but, when I am getting the same parameter from servlet, it is not giving me the same output as encrypteInput("email").
Whenever you have a byte array that you want to store in a string, you should be Hex- or Base64-encoding the byte array (hex-encoding is probably better in this particular case).
Apache commons-codec has a Hex class you can use for this:
byte[] bytes = ...
char[] encoded = Hex.encodeHex(bytes);
String encodedString = new String(encoded);

How can I optimize this String search/replace method?

I am implementing my own web server. The following method searches for server side includes and builds the html page appropriately.
public String getSSI(String content) throws IOException {
String beginString = "<!--#INCLUDE VIRTUAL=\"";
String endString = "\"-->";
int beginIndex = content.indexOf(beginString);
while (beginIndex != -1) {
int endIndex = content.indexOf(endString, beginIndex);
String includePath = content.substring(beginIndex+beginString.length(), endIndex);
File includeFile = new File(BASE_DIR+includePath);
byte[] bytes = new byte[(int) includeFile.length()];
FileInputStream in = new FileInputStream(includeFile);
in.read(bytes);
in.close();
String includeContent = new String(bytes);
includeContent = getSSI(includeContent);
content = content.replaceAll(beginString+includePath+endString, includeContent);
beginIndex = content.indexOf(beginString);
}
return content;
}
I know StringBuilder is faster than String, but is that all I can do to optimize this? The original data is read into a byte array and converted into a String, at which point it is passed into this method, and the output is converted back into a byte array and sent to the client.
I don't know how significant of an impact this will have, but instead of reading into a byte array and and converting to a String, you can use the IOUtils toString(InputStream) method to read directly to a String. Likewise, you can write the String directly to an OutputStream.

Categories