I have a problem.
I sent some data over a socket in string form. With some substringing, I managed to get the byte[] in String form [B#58596d12. Now, my question is, this is a string. How do I convert it back to a byte array after which I can use String result = new String(byteArray);?
I tried casting the String to byte[], but that's not allowed.
Google only came up with the usual .getBytes() (which I can't use since they already are bytes) and new String(someByteArray)
This is what's being sent:
byte[] all = Files.readAllBytes(f.toPath());
this.out.println(destinationOfFile + "/" + file.getName() + "*" + all);
And this is what's being received:
private void writeToFile(String str) {
String file = str.substring(0, str.indexOf("*"));
String write = str.substring(str.indexOf("*")+1);
EDIT: I managed to do it in another way.
Instead of getting all the bytes from the file, I wen't through it line by line, sending each line over the socket. In the client, I store the data in a HashMap and when it receives "Done sending File" it writes all the strings to the file.
If you want to store raw bytes in a String, you should use an encoding designed for this purpose, such as Base64. Take a look at the Commons Codec library and Base64 class.
I'm using this code to convert String-Byte[], but I'm not sure if it will help you because I don't know if you have rawBytes as source or a Java-String. Could you clarify?
public static String byteToHexString(byte b) {
String result = "";
result += Integer.toHexString((int)(b >> 4) & 0xf);
result += Integer.toHexString((int)(b) & 0xf);
return result;
}
public static String bytesToHexString(final byte[] byteArray) {
if (byteArray == null) {
return null;
}
String result = "";
for (int i = 0; i < byteArray.length; ++i) {
result += byteToHexString(byteArray[i]);
}
return result;
}
public static byte[] hexStringToBytes(final String hexString) {
if (hexString == null) {
return null;
}
byte[] result = new byte[hexString.length() / 2];
for (int idx = 0; idx < result.length; ++idx) {
int strIdx = idx * 2;
result[idx] = (byte) ((Character.digit(hexString.charAt(strIdx), 16) << 4)
+ Character.digit(hexString.charAt(strIdx + 1), 16));
}
return result;
}
Edit:
If you are converting String-byte[] and byte[]-String I would recommend using the charset or charsetname parameter for String.getBytes() and for the String-constructor. For example:
byte[] bytes = "text".getBytes("UTF-8");
String text = new String(bytes, "UTF-8");
Remember not every platform or jvm may support the same charsets. For a list of charsets have a look here.
If you are reading bytes from a File and want to interpret them as String, you also have to care about using the right charset.
Related
How to convert hex string to ansi (window 1252) and ansi (window 1252)to hex string in Java.
python (Works perfectly)
q = "hex string value"
x = bytes.fromhex(q).decode('ANSI')
a = x.encode("ANSI")
a = a.hex()
if q==a:
print("Correct")
Java (This code has a problem)
String hexOri = "hex string value";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hexOri.length(); i+=2) {
String str = hexOri.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println("ANSI = " + output);
char [] chars = output.toString().toCharArray();
StringBuffer hexOutput = new StringBuffer();
for(int i = 0; i < chars.length; i++){
hexOutput.append(Integer.toHexString((int)chars[i]));
}
System.out.println("HexOutput = " + hexOutput.toString());
System.out.println(hexOri.equals(hexOutput.toString()));
Output from Python
Correct
Expected Output from Python
Correct
Output from Java
False
Expected Output from Java
Correct
In java the strings are encoded in UTF-16, so you can't read simply read/write the bytes of a string to get the encoding representation you desire.
You should use String#getBytes(String str, String charset) to get the string converted in the encoding you need and serialized to a byte array.
The same thing must be done to decode a byte array, using new String(buffer,encoding).
In both cases if you use the method without the charset it will use the default encoding for the JVM instance (which should be the system charset).
public static void main(String[] args) {
String str = "\tSome text [à]";
try {
System.out.println(str); // Some text [à]
String windowsLatin1 = "Cp1252";
String hexString = toHex(windowsLatin1, str);
System.out.println(hexString); // 09536f6d652074657874205be05d
String winString = toString(windowsLatin1, hexString);
System.out.println(winString); // Some text [à]
} catch (UnsupportedEncodingException e) {
// Should not happen.
}
}
public static String toString(String encoding, String hexString) throws UnsupportedEncodingException {
int length = hexString.length();
byte [] buffer = new byte[length/2];
for (int i = 0; i < length ; i+=2) {
String hexVal = hexString.substring(i,i+2);
byte code = (byte) Integer.parseInt(hexVal,16);
buffer[i/2]=code;
}
String winString = new String(buffer,encoding);
return winString;
}
public static String toHex(String encoding, String str) throws UnsupportedEncodingException {
byte[] bytes = str.getBytes(encoding);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
String hexChar = Integer.toHexString(b & 0xff);
if(hexChar.length()<2) {
builder.append('0');
}
builder.append(hexChar);
}
String hexString = builder.toString(); // 09536f6d652074657874205be05d
return hexString;
}
I have converted regional language word to hex value and saved to DB. But How can i decode that hexa value back to regional language word.
Here is my Kannada/Telugu word to Hex value conversion
public String toHex(String b){
String s="";
for (int i=0; i<b.length(); ++i) s+=String.format("%04X",b.charAt(i)&0xffff);
System.out.println("Converted value:::"+s); //0C1C0C3E0C350C3E
return s;
}
Word i have saved is జావా
Hex value saved in database is 0C1C0C3E0C350C3E
Decoded output am getting is : >5>
Is there any way to decode the hex value back to జావా
Code used to decode is
byte[] bytes = DatatypeConverter.parseHexBinary(itemName);
String s= new String(bytes, "UTF-8");
System.out.println("Utf..."+s);
Please help...
public String fromHex(String b) {
char[] cs = new char[b.length() / 4];
for (int i = 0; i < cs.length; ++i) {
int c = Integer.parseInt(b.substring(4 * i, 4 * i + 4), 16) & 0xFFFF;
cs[i] = (char) c;
}
return new String(cs);
}
This assumes that the conversion did not meddle with negative hex values.
Or exploiting that char is UTF-16BE:
byte[] bytes = DatatypeConverter.parseHexBinary(itemName);
return new String(bytes, StandardCharsets.UTF_16);
char[] data = hexData.toCharArray();
byte[] bytes = new byte[data.length/2];
for (int i = 0; i < data.length; i += 2) {
String val = new String(data, i, 2);
bytes[i/2] = Integer.valueOf(val, 16).byteValue();
}
String text = new String(bytes, "UTF8");
You might add sanity checks, e.g. that the length of the input-array is even, etc.
Following Code changes every byte of a string and creates a new string.
public static String convert(String s) {
byte[] bytes = s.getBytes();
byte[] convert = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
convert[i] = (byte) ~bytes[i];
}
return new String(convert);
}
Question: Why is convert() not bijective?
convert(convert("Test String")).equals("Test String") === false
when you use the constructor String(byte[]), it doesn't necesarily takes one letter per byte, it takes the default charset; if it is, say, UTF-8, then the constructor will try to decode some chars from two or three bytes rather than just one.
As you are using bit-complement to transform byte by byte, the result could be different when you apply the default charset.
If you are using only ASCII chars, you could try this version of your function:
// ONLY if you use ASCII as Charset
public static String convert(String s) {
Charset ASCII = Charset.forName("ASCII");
byte[] bytes = s.getBytes(ASCII);
byte[] convert = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
convert[i] = (byte) (~bytes[i] & 0x7F);
}
return new String(convert, ASCII);
}
Because information is lost when you converted the manipulated byte to String and vice versa
In this line below
for (int i = 0; i < bytes.length; i++) {
convert[i] = (byte) ~bytes[i];
}
return new String(convert);
If you go inside the implementation of String to byte conversion and viceversa you will find that CharSet and encoding are involved.
Read about them and you will get detailed explanation of this behavior.
String str = "9B7D2C34A366BF890C730641E6CECF6F";
I want to convert str into byte array, but str.getBytes() returns 32 bytes instead of 16.
I think what the questioner is after is converting the string representation of a hexadecimal value to a byte array representing that hexadecimal value.
The apache commons-codec has a class for that, Hex.
String s = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = Hex.decodeHex(s.toCharArray());
Java SE 6 or Java EE 5 provides a method to do this now so there is no need for extra libraries.
The method is DatatypeConverter.parseHexBinary
In this case it can be used as follows:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = DatatypeConverter.parseHexBinary(str);
The class also provides type conversions for many other formats that are generally used in XML.
Use:
str.getBytes("UTF-16LE");
I know it's late but hope it will help someone else...
This is my code: It takes two by two hex representations contained in String and add those into byte array.
It works perfectly for me.
public byte[] stringToByteArray (String s) {
byte[] byteArray = new byte[s.length()/2];
String[] strBytes = new String[s.length()/2];
int k = 0;
for (int i = 0; i < s.length(); i=i+2) {
int j = i+2;
strBytes[k] = s.substring(i,j);
byteArray[k] = (byte)Integer.parseInt(strBytes[k], 16);
k++;
}
return byteArray;
}
That should do the trick :
byte[] bytes = toByteArray(Str.toCharArray());
public static byte[] toByteArray(char[] array) {
return toByteArray(array, Charset.defaultCharset());
}
public static byte[] toByteArray(char[] array, Charset charset) {
CharBuffer cbuf = CharBuffer.wrap(array);
ByteBuffer bbuf = charset.encode(cbuf);
return bbuf.array();
}
try this:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
String[] temp = str.split(",");
bytesArray = new byte[temp.length];
int index = 0;
for (String item: temp) {
bytesArray[index] = Byte.parseByte(item);
index++;
}
I assume what you need is to convert a hex string into a byte array that equals that means the same thing as that hex string?
Adding this method should do it for you, without any extra library importing:
public static byte[] hexToByteArray(String s) {
String[] strBytes = s.split("(?<=\\G.{2})");
byte[] bytes = new byte[strBytes.length];
for(int i = 0; i < strBytes.length; i++)
bytes[i] = (byte)Integer.parseInt(strBytes[i], 16);
return bytes;
}
I am trying to pass a String value in socket to another server. The other server should receive the value in hex format.
i.e If my String is s = "600185838e" at the server it should receive as 60 01 85 83 8e, but these values what I sent are been converted to ASCII & is not in the desired format.
I am using socket connection
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
wr.write(messageBody);
wr.flush();
How can I send my String value similar as Hex value?
Thanking you all in advance
You should convert the hex string to byte array and then send it as byte array:
OutputStream out = this.socket.getOutputStream();
out.write(yourBytearray);
This is the method for converting the hex string to byte[] this is a copy from the link I gave, but I copied it here to make clear what I'm talking about:
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
You can also try splitting the string into 2-character long Strings and convert them to individual bytes via Byte.parseByte(my2CharString , 16) and then send them
Here's some code that will do what you want, just replace System.out.println() with write() <- must write only one byte:
String output = "ffee101";
while(output.length() > 0){
String byteToWrite;
if(output.length() <= 2){
byteToWrite = output;
output = "";
}
else{
byteToWrite = output.substring(0,2);
output = output.substring(2);
}
byte b = (byte)Short.parseShort(byteToWrite, 16);
System.out.println(b);
}