2

I have a class like this:

public class Fields implements java.io.Serializable{
    public short ID;
    public int SSN;
    public long Number;
}

and I have a hexadecimal string with the value like this which each 2 characters is representative of a byte:

String str="1000180018000540AC80D6487653E5000100D40B7900D4C3FFF2FAFF8985";

Now I want to cast this string to the above class object in a schema like this:

//ID has short type so we need 2 bytes
ID=4096; //(decimal value of 1000)

//SSN has integer type so we need 4 bytes
SSN=402659328; //(decimal value of 18001800)

//Number has long type so we need 8 bytes
Number=378492038049986131; //(decimal value of 0540AC80D6487653)

This casting can be implemented in c++ with <reinterpret_cast> so easily but as the Is there cast in Java similar to in C++ question is said, I can implement that with serialization in java. I think serialization can be used when we serialize a class object to the byte arrays at first and second we can de-serialize the obtained bytes to the primitive class object, which is different from my propose a little, because I have a string (like bytes) which I want to de-serialize that. So how can I do that?

  • Serialization won't help you. It have very specific format which doesn't match yours. You have to parse your string manually. – talex Jan 31 '19 at 10:14
  • @talex but C++ do that with `` easily. So there is no way like `` in java? Because speed is important to me and parsing manually with a high rate string data will be a bottleneck! – ahmadi morteza ali Jan 31 '19 at 10:17
  • 1
    No `` would not have done it easily. It wont even work. "1000" is 4 ASCII bytes, 0x31, 0x30, 0x30, 0x30, C++ won't magically convert it to 2 bytes 0x10, 0x00. – jbx Jan 31 '19 at 10:17
  • @ahmadimortezaali if you want to use `` you have to use `c++` :) Java doesn't have anything like it. – talex Jan 31 '19 at 10:19
  • https://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java – talex Jan 31 '19 at 10:21

3 Answers3

4

Java Serialization has a very specific data format and it doesn't help you parse data that you get with a different pre-defined format. But a ByteBuffer can be useful in parsing this kind of data.

First you need to transform your string into an actual byte[] array. I'll use a simple solution from this answer, feel free to pick another one that's more appropriate to your example:

byte[] data = DatatypeConverter.parseHexBinary(str);
ByteBuffer buffer = ByteBuffer.wrap(data);

buffer.order(ByteOrder.LITTLE_ENDIAN); // maybe!

short id = buffer.getShort();
int ssn = buffer.getInt();
long number = buffer.getLong();

Whether or not you need the order() call depends on what endianness your data is in. ByteBuffer defaults to BIG_ENDIAN, so you can just leave that call out if that's what you need.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
3

I don't think <reinterpret_cast> would have worked. The internal byte representation of "1000" is 4 ASCII bytes. One for character 1 (0x31) followed by 3 characters 0 (0x30) , not 0x10, 0x00 hexadecimal. The result you will get in id with <reinterpret_cast> would be hex 0x31303030 not 0x1000.

What you need to do is parse the different components of the string.

Something like this should do:

int id = Integer.parseInt(str.substring(0,4), 16);
jbx
  • 21,365
  • 18
  • 90
  • 144
2

You just need to split and parse

public Fields(String str) {
    ID = Short.parseShort(str.substring(0, 4), 16);
    SSN = Integer.parseInt(str.substring(4, 12), 16);
    Number = Long.parseLong(str.substring(12, 28), 16);
}
azro
  • 53,056
  • 7
  • 34
  • 70