Get Byte from JSON - java

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);
}

Related

ByteArray String to ByteArray? [duplicate]

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.

int array to byte array with one integer per byte

All related questions I've found here on SO describe the conversion between a byte array and an int array where 4 bytes are converted to a single integer and vice versa.
What I am looking for instead is converting each integer to a single byte and vice versa, knowing that none of the values of the integer array exceeds the range of an unsigned byte.
Is there a library that does that (preferably Guava or Apache commons)? Essentially, I am looking for something like this:
int[] -> byte[]
for (int i = 0; i < intArray.length; i++){
byteArray[i] = (byte) intArray[i];
}
byte[] -> int[]
for (int i = 0; i < byteArray.length; i++){
intArray[i] = 0xff & byteArray[i];
}
You cannot cast arrays in Java in that way. AFAIK, the VM just does not let you reinterpret the bytes in an array as a different type. I assume that you could use some platform-dependent JNI magic to make it so, but that would be extremely hacky.
Edit (removed sample code; added following)
If you are going to reinterpret the same bytes as different primitive types, use a ByteBuffer.
Once declared, you get direct access operations to reinterpreted bytes, such as
myByteBuffer.getInt(1); // reads bytes 4, 5, 6, 7 as an int
myByteBuffer.getByte(5); // reads byte 5 as a byte
You can also extract primitive arrays from there, but there will be extra allocations involved.
Try:
int number = 54353, divisor = 256;
byte[] byteArray = new byte[4];
byteArray[3] = number%divisor;
number = number/divisor
byteArray[2] = number%divisor;
number = number/divisor
byteArray[1] = number%divisor;
number = number/divisor
byteArray[0] = number;

Converting ints and strings into byte array and the reverse

I would like to convert some ints and some strings into a single byte array and then back again. I've done a bit of research on how to do converting, but I'm not sure if its all correct.
Converting a string to a byte array is easy:
byte[] bytes = string.getBytes();
Converting it back again via Arrays.toString() because that just creates a string of the bytes.
Does this work: String s = new String(bytes);?
Converting ints to byte array is like this:
int[] data = { int1, int2, int3 };
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(data);
byte[] my_app_state = byteBuffer.array();
But I don't know how to convert it back again.
My aim is to have say 4 ints and 2 strings converted to a single byte array and then convert them back again.
For example. I have these objects and would like them to converted to the same byte array.
int int1 = 1;
int int2 = 2;
int int3 = 3;
int int4 = 4;
String s1 = "mystring1"
String s2 = "mystring2"
Update: Removed code where I thought there was a problem. There wasn't.
For each operation, you need to determine the reverse operation, not just any operation which returns the right type. for example, the reverse of n * 2 is m / 2 not m - 2 even though the type is right.
Arrays.toString("Hi".getBytes()) => "{ 72, 105 }"
So you can do
text.getBytes() => new String(bytes) // if the same character encoding is used.
a better option is
text.getBytes("UTF-8") => new String(bytes, "UTF-8");
The problem with an array is you have two pieces of information a length and some bytes If you just write the bytes, you no longer know the length and so you can't easily decode it (perhaps impossible)
In your case, the simplest option is to use a Data Stream
// buffer which grows as needed.
ByteArrayOutputStream boas = new ByteArrayOutputStream();
// supports basic data types
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(data.length);
for(int i: data) dow.writeInt(i);
// write the length of the string + the UTF-8 encoding of the text.
dos.writeUTF(s1);
dos.writeUTF(s2);
byte[] bytes = bytes.toByteArray();
To do the reverse, you use the InputStream and the readXxxx instead of writeXxxx methods.
Java makes it very simple to achieve this, as this is a very common use case. What you need looks very much like Serialization.
Serialization works like this: A single object can be converted to a set of bytes and stored in a byte array (usually for writing to a file or sending over a network).
The good things is that any object can become serializable by just implementing a marker interface (just 1 line of code). Also, all Wrapper datatypes and String and Collections objects like ArrayList are serializable.
Coming to your question: Put all your data in a single object and serialize that object. 3 options come to my mind:
1. An Object[] or ArrayList (if you know the order for sure, so that you can access based on position)
2. A HashMap, (if you can assign a name to each of them instead of relying on position)
3. Create your own data type with fields like int1, int2 or even more meaningful names. (Your class should implement Serializable).
Now, all your data is added into a single object. Convert this one object to a byte array and your job is done.
Check this link for how to convert a single object to byte array:
Java Serializable Object to Byte Array
Object[] payload = new Object[]{int1, int2, int3, int4, string1, string2};
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(payload);
byte[] result = out.toByteArray(); //Done
for store Strings as well you have to use some thing like
IntBuffer intBuffer = byteBuffer.asIntBuffer();
CharBuffer stringBuffer = byteBuffer.asCharBuffer();
then you have to traverse the loop on char[][] string = {s1.toCharArray(),s2.toCharArray()};
to put the each character in stringBuffer and more thing you have to do is you to make your byteBuffer to sufficient to hold these values my friend

Convert array of strings to array of bytes

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.

How can I access a byte array as shorts in Java

I have a an array of byte, size n, that really represents an array of short of size n/2. Before I write the array to a disk file I need to adjust the values by adding bias values stored in another array of short. In C++ I would just assign the address of the byte array to a pointer for a short array with a cast to short and use pointer arithmetic or use a union.
How may this be done in Java - I'm very new to Java BTW.
You could do the bit-twiddling yourself but I'd recommend taking a look at the ByteBuffer and ShortBuffer classes.
byte[] arr = ...
ByteBuffer bb = ByteBuffer.wrap(arr); // Wrapper around underlying byte[].
ShortBuffer sb = bb.asShortBuffer(); // Wrapper around ByteBuffer.
// Now traverse ShortBuffer to obtain each short.
short s1 = sb.get();
short s2 = sb.get(); // etc.
You can wrap your byte array with java.nio.ByteBuffer.
byte[] bytes = ...
ByteBuffer buffer = ByteBuffer.wrap( bytes );
// you may or may not need to do this
//buffer.order( ByteOrder.BIG/LITTLE_ENDIAN );
ShortBuffer shorts = buffer.asShortBuffer( );
for ( int i = 0, n=shorts.remaining( ); i < n; ++i ) {
final int index = shorts.position( ) + i;
// Perform your transformation
final short adjusted_val = shortAdjuster( shorts.get( index ) );
// Put value at the same index
shorts.put( index, adjusted_val );
}
// bytes now contains adjusted short values
The correct way to do this is using shifts. So
for (int i = 0; i < shorts.length; i++) {
shorts[i] = (short)((bytes[2*i] << 8) | bytes[2*i + 1]);
}
Also, it depends on the endian-ness of the stream in many respects. This may work better

Categories

Resources