I have a String array, each array element is a hex string that consist of 2 chars.
For example the array could be:
String a = {"aa","ff","00",.....}
How can I convert this array of strings to an array of bytes in Java?
If you want to parse unsigned byte hex-strings, use
byte[] b = new byte[a.length()];
for (int i=0; i<a.length(); i++) {
b[i] = (byte) Short.parseShort(a[i], 16);
}
"ff" will be parsed to -1, as per two's compliment.
If you want "ff" to parse to 255 (higher than a java byte can hold) you will need to use shorts
short[] b = new short[a.length()];
for (int i=0; i<a.length(); i++) {
b[i] = Short.parseShort(a[i], 16);
}
Loop through the array, and convert each String to a byte using
byte b = (byte) (Integer.parseInt(theHexaString, 16));
Byte.parseByte() parses signed bytes only, and doesn't consider the sign bit as a sign bit.
If I understand correctly, you need the byte representation of the concatenated strings? Something like:
public byte[] getBytes(String[] array) {
StringBuilder builder = new StringBuilder();
for(String s: array) {
builder.append(s);
}
return builder.toString().getBytes();
}
You should take a look at the ByteArrayOutputStream.
You can then iterate through each string you have and use the Byte.parseByte() method. You can than add it to the ByteArrayOutputStream by using the write method.
Once you will have converted all the Strings, you can use the ByteArrayOutputStream's toByteArray() method.
Related
I am working on a compression algorithm and for that i need to write strings of bits to a binary file and retrieve back exactly the same to a String again!
say, i have a string "10100100100....." and i will write them in a file as bits
(not chars '0' '1')
. and read back as bits and convert to string...
and this is for a large amount of data (>100 megabytes).
is there any neat and fast way of doing this?
So far i tried (and failed) writing them to bytes by sub-stringing into 8 bits and then as ASCII characters to a string and finally to a .txt file.
{
String Bits="10001010100000000000"; // a lot larger in actual program
String nCoded="";
char nextChar;
int i = 0;
for(i=0; i < Bits.length()-8; i += 8){
nextChar = (char)Integer.parseInt( Bits.substring(i, i+8), 2 );
nCoded += nextChar;
}
// for the remainding bits, padding
if(newBits.length()%8 != 0){
nCoded+=(char)Integer.parseInt(Bits.substring(i), 2);
}
nCoded+=(char)Bits.length()%8; //to track the remainder of Bits that was padded
writeToTextFile( nCoded, "file.txt"); //write the nCoded string to file
}
but this seems to corrupt information and inefficient.
again for clarification, i dont want the String to be written, its just a representation of the actual data. So, i want to
convert each 0 and 1 from the string representation to its binary form
and write that to file.
Here is a method you can use to convert the String to a series of bits, ready for output to file:
private byte[] toByteArray(String input){
//to charArray
char[] preBitChars = input.toCharArray();
int bitShortage = (8 - (preBitChars.length%8));
char[] bitChars = new char[preBitChars.length + bitShortage];
System.arraycopy(preBitChars, 0, bitChars, 0, preBitChars.length);
for (int i= 0; i < bitShortage; i++) {
bitChars[preBitChars.length + i]='0';
}
//to bytearray
byte[] byteArray = new byte[bitChars.length/8];
for(int i=0; i<bitChars.length; i++) {
if (bitChars[i]=='1'){
byteArray[byteArray.length - (i/8) - 1] |= 1<<(i%8);
}
}
return byteArray;
}
Passing the String "01010101" will return the result [85] as a byte[].
It turns out there is an easier way. There is a static Byte.parseByte(String) that returns Byte object. Calling:
Byte aByte = Byte.parseByte("01010101");
System.out.println(aByte);
Displays the same value: 85.
So you may ask a couple of questions here.
Why are we passing a String that is 8 characters in length. Well, you can prefix the String with an 9th character, that would represent a sign bit. I don't think you have this case, but if you needed to, the documentation for Byte.parseByte() states it should be:
An ASCII minus sign '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value.
So from this information, you would need to break up your String manually into 8 bit Strings and call Byte.parseByte() to get a Byte object for each.
2) What about writing bits to a file? No, file writing is done in bytes. If you need to write the file, then read it back in and convert back to a String, you will need to reverse the process and read the file in as a byte[] then convert that to it's String representation.
A Hint on how to convert a byte to a nice String format can be found here:
Convert byte (java data type) value to bits (a string containing only 8 bits)
You can get an InputStream from a String, read each byte and write it to a file (byte is a smallest unit that you can read/write). Once everything is written, you can read the data in a similar way (i.e. InputStream) and use it. Below is an example:
String hugeSting = "10101010010101010110101001010101";
InputStream in = new ByteArrayInputStream(hugeSting.getBytes());
OutputStream out = new FileOutputStream("Test.txt");
byte b;
while((b = (byte) in.read()) != -1){
out.write(b);
}
in.close();
in = new FileInputStream("Test.txt");
//Read data
This question already has answers here:
Convert a string representation of a hex dump to a byte array using Java?
(25 answers)
Closed 8 years ago.
I have a string which I want to cast to a byte array, however, my string is the actually representation of an image byte array (eg. String x = "00123589504e47..."). So, I'm stuck because doing x.getBytes(); doesn't do the job.. I need a way to cast the string to byte array and then save that byte array to an image in a specific directory. How can I cast it?
doing x.getBytes(); doesn't do the job
Yes, that's normal...
A char and a byte have no relationship to one another; you cannot seamlessly cast from one to the other and expect to obtain a sane result. Read about character codings.
From what you want, it appears that the String is in fact a "hex dump" of the image. You therefore need to read two chars by two chars and convert that to a byte array.
How? Well, you have hints. First, the length of the resulting byte array will always be that of the string divided by 2, so you can do that to start with:
// input is the string
final int arrayLen = input.length() / 2;
final byte[] result = new byte[arrayLen];
Then you need to walk through the string's characters and parse those two characters into a byte, and add that to the array:
int strIndex;
char[] chars = new char[2];
for (int arrayIndex = 0; arrayIndex < arrayLen; arrayIndex++) {
strIndex = 2 * arrayIndex;
chars[0] = input.charAt(strIndex);
chars[1] = input.charAt(strIndex + 1);
result[arrayIndex] = Byte.parseByte(new String(chars), 16);
}
// Done
return result;
I always use this one liner:
byte[] data = DatatypeConverter.parseHexBinary(x);
You can then instantiate a FileOutputStream for the image and write the bytes onto that.
I have a Byte array being returned in my JSON.
JSON
[{"template":167,255,1,30,179,0,218,0,2,88,1,184,0],
"template2":null,
"template3":null,
"Client_Id":1160739}]
In Java, how can I recover this byte array ?
I try return a String in JSON instead the byte array, but when I convert to byte, it will change the value that I need. Example, 167 is the value that I need because this is already the byte value, but if I try to convert 167 to byte, it will return another value, so I need recover it as byte value.
JAVA
ArrayList<JSONObject> vetor = ArrayJson(client);
byte[] template = (byte[])vetor.get(0).get("template");
I'm using the json.org/java repository to construct the json helper class.
The byte data type is good for 256 different numbers - yet, in java, when you use bytes, they are interpreted as signed two's complement numbers. This is most likely what happens to you. Note that the bit pattern is not changed, only the output changes.
You can recover the unsigned value in byte b with (b & 0xff)
JSON has no concept of bytes, so what you have is an array of numbers.
You can just iterate over them and build up a byte array by casting each of the numbers to byte.
Suppose you got your array of numbers into a int[] array using a JSON library of choice, simply do this:
int[] numbers = ...
byte[] bytes = new byte[numbers.length];
for (int i=0; i<numbers.length;i++) {
bytes[i] = (byte)numbers[i];
}
Here is the code:
The Classes are present in org.json package.
String jsonString = "{'template':[167,255,1,30,17,1,204,0,1,237,0,128,0] }";
JSONObject jObject = new JSONObject(jsonString);
JSONArray jArray = jObject.getJSONArray("template");
byte[] array = new byte[jArray.length()];
for(int i = 0; i < jArray.length(); i++) {
array[i] = (byte)jArray.getInt(i);
}
I would like to transform a Java String str into byte[] b with the following characteristics:
b is a valid C string (ie it has b.length = str.length() + 1 and b[str.length()] == 0.
the characters in b are obtained by converting the characters in str to 8-bit ASCII characters.
What is the most efficient way to do this — preferably an existing library function? Sadly, str.getBytes("ISO-8859-1") doesn't meet my first requirement...
// do this once to setup
CharsetEncoder enc = Charset.forName("ISO-8859-1").newEncoder();
// for each string
int len = str.length();
byte b[] = new byte[len + 1];
ByteBuffer bbuf = ByteBuffer.wrap(b);
enc.encode(CharBuffer.wrap(str), bbuf, true);
// you might want to ensure that bbuf.position() == len
b[len] = 0;
This requires allocating a couple of wrapper objects, but does not copy the string characters twice.
You can use str.getBytes("ISO-8859-1") with a little trick at the end:
byte[] stringBytes=str.getBytes("ISO-8859-1");
byte[] ntBytes=new byte[stringBytes.length+1];
System.arraycopy(stringBytes, 0, ntBytes, 0, stringBytes.length);
arraycopy is relatively fast as it can use native tricks and optimizations in many cases. The new array is filled with null bytes everywhere we didn't overwrite it(basically just the last byte).
ntBytes is the array you need.
I am receiving data from a hardware device. I receive it as an array of bytes. I want to build and store a String that can show me the data of the array of bytes. This is what I have:
byte[] buffer = new byte[BUFFER_SIZE];
bytes = mmInStream.read(buffer);
String[] str = new String[bytes];
StringBuffer readMessage = new StringBuffer();
for(int i=0; i<bytes; ++i){
str[i] = Integer.toHexString(buffer[i]);
while (str[i].length() < 8){ //standarize size
str[i] = '0' + str[i];
}
readMessage.append(str[i]);
}
The main problem that I have is that I am receiving unexpected bytes when I transform the bytes to String. I am receiving pure bytes so I am expecting the values to range from 0x00 to 0xFF. However, some of the bytes are transformed to bytes like 0xFFFFFF09. Why is this happening??
You should convert byte to int this way:
int byteAsInt = ((int)buffer[i]) & 0x000000FF;
str[i] = Integer.toHexString(byteAsInt);
byte is a signed data type, so 0xFF is -1. When converting to a larger integral type it will still be -1, i.e. 0xFFFF or 0xFFFFFFFF for 16 and 32 bit integer values.
Edit:
If you want to get the unsigned value, do a bitwise AND (&) with 0xFF when assigning to a larger variable.
Without running your code I suppose that your problem is in your inner loop.
while (str[i].length() < 8){ //standarize size
str[i] = '0' + str[i];
}
What would you like to achieve? Print 0xFF instead of FF? In this case just modify one line as following:
str[i] = "0x" + Integer.toHexString(buffer[i]);
and remove the inner loop.