Encode String to UCS2 - java

I need to encode java string to UCS like 'h' to '0068'
eg. I have a test setup
#Test
public void testEncodeAsUCS2_string1() throws Exception {
String encoded = sendRequestTransformer.encodeAsUCS2("hello");
Assert.assertEquals("00680065006C006C006F", encoded);
}
so this test lets me know if the conversion was successful eg. hello should return 00680065006C006C006F
In my code I have the following conversion which I know is wrong as it prints [B#742cb491. (This toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object)
I need help with the conversion
String encodeAsUcx2(String messageContent){
try {
messageContent.getBytes("UTF-16LE");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return String.valueOf(messageContent.getBytes());
}
How would I go about this?

After you convert your message to a byte[], you just need to loop through and convert each byte to a hex representation, and build a new String as you go.
For instance, you could do something like this:
static String encodeAsUcs2(String messageContent) throws UnsupportedEncodingException {
byte[] bytes = messageContent.getBytes("UTF-16LE");
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
I should note, however, that this will return "680065006C006C006F00", not "00680065006C006C006F" when encoding "hello".
To get the output you're expecting, you would need to use big-endian encoding ("UTF-16BE").

Related

Convert a byte array from one encoding to another java

hi guys i should convert this code to C# in Java. Could you give me a hand?
private static String ConvertStringToHexStringByteArray(String input) {
Encoding ebcdic = Encoding.GetEncoding("IBM037");
Encoding utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(input);
byte[] isoBytes = Encoding.Convert(utf8, ebcdic, utfBytes);
StringBuilder hex = new StringBuilder(isoBytes.length * 2);
foreach( byte b in isoBytes)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
I tried to convert it to java like this. But the result is different:
private static String ConvertStringToHexStringByteArray(String input) throws UnsupportedEncodingException {
byte[] isoBytes = input.getBytes("IBM037");
StringBuilder hex = new StringBuilder(isoBytes.length * 2);
for (byte b : isoBytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
input = "X1GRUPPO 00000000726272772"
expected = "e7f1c7d9e4d7d7d64040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2"
result = "e7f1c7d9e4d7d7d640f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2"
what am I doing wrong?
Your code works but you are comparing the output for two different input strings.
When you write expected and result side by side:
e7f1c7d9e4d7d7d64040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2
e7f1c7d9e4d7d7d640f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2
you will notice that both start with the same sequence (e7f1c7d9e4d7d7d6) which seems to come from a common beginning X1GRUPPO
But then the two outputs differ:
4040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2
40f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2
Reasoning from the input that you provided, the remainder of first input string starts with 5 spaces followed by "00000000167353552"
This means the complete input for the C# code was "X1GRUPPO 00000000167353552", which is not the same input that you provided to the Java code and then clearly the output cannot match.

Decoding and Encoding issue. Different implementations of Base64 Class in android.util.* and java.util.*?

I am writing an App which does the following with a given String str:
encode(encrypt(encode(stringToBytearray(str))));
The Server receives the Base64 encoded String, which is then decoded -> decrypted -> decoded, to get the sent String str from the App.
Unfortunately it doesnt work for all Strings, long Strings lead to a long Base64 String and my Server throws the following Exception:
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 5b
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
at Main.decode(Main.java:113)
at Main.main(ain.java:33)
The String has the format "[string, string, ..., string]" without "s.
Like I mentioned above, for Strings which are not too long (sorry I cant quantify the length yet), this works. So I think I implemented it right.
Whats weird is, that if I dont send it, but decode(decrypt(decode(stringToBytearray(str)))); the String on the Device itself, it all works perfectly.
My Setup:
JDK 7, eclipse (adt-bundle, android development) (Windows 7)
JDK 8, eclipse ('normal' java) (Linux (xubuntu))
Is it because both Classes (Base64) are implemented diffrently? If so, how can I make it work?
Here are the Encoding/Decoding Methods:
Encoding (Device: on Windows 7, adt-bundle, Android-Dev, jdk 7):
import android.util.Base64
public byte[] encode(byte[] bytearrayToEncode){
return Base64.encode(bytearrayToEncode, Base64.NO_WRAP|Base64.URL_SAFE);
}
Decoding (Server: on Linux, jdk 8):
import java.util.Base64
public byte[] decode(byte[] bytearrayToEncode){
return Base64.getUrlDecoder().decode(bytearrayToDecode);
}
Strings are all De-/Encoded with the same charset (utf-8)!
Encoding/Decoding: Base64
Crypto: AES
If you need more Information, just ask, but I think I provided all neccessary informations.
Edit:
public String bytearrayToString(byte[] bytearray){
String str = null;
try {
str = new String(bytearray, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
public byte[] stringToBytearray(String str){
byte[] bytearray = null;
try {
bytearray = str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bytearray;
}
You must be using JSONObjects to send the Base64 String to the server. If so then the JSONObject will add " \ " escape characters to the string which are illegal Base64 characters. All you need to do is
String rectifiedString = Base64String.replace("\\","");
on the server end before using the acquired string.
Optional
Also on the server side use
import javax.xml.bind.DatatypeConverter;
and
String result = DatatypeConverter.printBase64Binary(bytearrayToDecode);
byte[] result = DatatypeConverter.parseBase64Binary(str);
instead.
It will not only get the job done but is much faster at encoding/decoding (as benchmarked here).
If you have a space in your encoded string, which is an illegal character in base64. If you remove it, it still generates the same image/data in the converter you linked to, and can be now decoded by your code as well.
UPDATE:
Some decoders (like the one you linked, or Base64.getMimeDecoder() in Java) ignore illegal characters, others (like Base64.getDecoder()) don't allow them.
Use for encode:
Base64.getEncoder().encodeToString(yourString.getBytes("UTF-8"));
and decode:
byte[] decodedBytes = Base64.getDecoder().decode(yourString);
String stringDecode = new String(decodedBytes, "UTF-8");

Java convert string bytes to readable string [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Byte Array to String to Byte Array
I have a method called READ() that accept a String parameter. This string is already have been converted into bytes. All I want is to convert into a readable string.
public static String READ(final String data) throws UnsupportedEncodingException{
char[] temp = data.toCharArray();
byte[] bytes = new byte[temp.length];
int i = 0;
for(char c : temp){
bytes[i++] = (byte)c;
}
return new String(bytes, "UTF-8");
}
public static String SEND(String data) throws UnsupportedEncodingException{
return data.getBytes()+"";
}
Testing:
String msg = "testing !";
String msgBytes = null;
try {
msgBytes = SEND(msg);
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
}
System.out.println( "SEND: " + msgBytes);
try {
System.out.println("RECEIVE: " + READ(msgBytes));
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
}
And the OUTPUT IS:
SEND: [B#452467ec
RECEIVE: [B#452467ec
String has a constructor that takes byte[] as an argument.
String(byte[] bytes) --
Constructs a new String by decoding the specified array of bytes using the platform's default charset.
String(byte[] bytes, Charset charset) --
Constructs a new String by decoding the specified array of bytes using the specified charset.
So print it like this:
System.out.println(new String(msgBytes, "UTF-8"));
What you currently see is a default Object.toString() which prints a memory reference to the byte array (all arrays extend from Object).
You print a byte[] which is an Object, so it just prints the reference into memory of that Object because that's what the default implementation of toString() does.
You should print the String directly. Don't print its byte[] representation.
What you do in your code is to transform a String into byte[] and then back to String in the wrong way.

Java base64 encoding output from Apache Common the "wrong" result

I am trying to use the Base64 encoding functionality from Apache Common. But I seem to get the "wrong" result. The doc is here.
My code is like this:
import org.apache.commons.codec.binary.Base64;
String data = "hi,all,how can this happen?";
byte[] databytes = Base64.encodeBase64(data.getBytes());
data = databytes.toString();
System.out.println(data);
//the result is:
//[B#121cc40
However I encode the same string using Python, the code is:
import base64
print base64.b64encode("hi,all,how can this happen?")
#The result is aGksYWxsLGhvdyBjYW4gdGhpcyBoYXBwZW4/
How can there be such difference?
That's not how you print a byte (or any other type of) array in Java, if you want to view its contents.
This is:
System.out.println(Arrays.toString(data));
import org.apache.commons.codec.binary.Base64;
public class Codec {
public static void main(String[] args) {
try {
String data = "hi,all,how can this happen?";
String encodedText;
// Base64
encodedText = new String(Base64.encodeBase64(data.getBytes()));
System.out.println("Encoded: " + encodedText);
System.out.println("Decoded:"
+ new String(Base64.decodeBase64(encodedText.getBytes())));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Now it will encode your String data
You are printing the address.
If you want to print the String data, you can use,
String password = new String(databytes);
System.out.println("Encoded String "+ password)

Comparing hash from string against hash of local file

What I am trying to do is read from a text file where each line has the path to a file and then space for a separator and a hash that accompanies it. So I call checkVersion() and loadStrings(File f_) returns a String[], one place for each line. When I try to check the hashes however I end up with something that isn't even hex and is twice as long as it should be, it's probably something obvious that my eyes are just overlooking. The idea behind this is an auto-update for my game to save bandwidth, thanks for your time.
The code is fixed, here is the final version if anyone else has this issue, thanks a lot everyone.
void checkVersion() {
String[] v = loadStrings("version.txt");
for(int i=0; i<v.length; i++) {
String[] piece = split(v[i], " "); //BREAKS INTO FILENAME, HASH
println("Checking "+piece[0]+"..."+piece[1]);
if(checkHash(piece[0], piece[1])) {
println("ok!");
} else {
println("NOT OKAY!");
//CONTINUE TO DOWNLOAD FILE AND THEN CALL CHECKVERSION AGAIN
}
}
}
boolean checkHash(String path_, String hash_) {
return createHash(path_).equals(hash_);
}
byte[] messageDigest(String message, String algorithm) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance(algorithm);
md.update(message.getBytes());
return md.digest();
} catch(java.security.NoSuchAlgorithmException e) {
println(e.getMessage());
return null;
}
}
String createHash(String path_) {
byte[] md5hash = messageDigest(new String(loadBytes(path_)),"MD5");
BigInteger bigInt = new BigInteger(1, md5hash);
return bigInt.toString(16);
}
The String.getBytes() method returns the bytes that represent the character encodings for the string. It doesn't parse it into bytes that represent a number in some arbitrary radix. For example "AA".getBytes() would yield you 0x41 0x41 on windows, not 10101010b, which is what it appears you were expecting? To get that you could, for example Byte.parseByte("AA", 16)
The library you're using to create hashes probably has a method for taking back in its own string representation. How to convert back depends on the representation, which you didn't give us.
use following code to convert hash bytes to string
//byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
String output = bigInt.toString(16);
System.out.println("MD5: " + output);
for more information

Categories

Resources