将十六进制字符串强制转换为类对象

时间:2019-01-31 10:09:58

标签: java arrays serialization deserialization hexdump

我有一个这样的班级:

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

,我有一个十六进制字符串,其值像这样,每个2个字符代表一个字节:

String str="1000180018000540AC80D6487653E5000100D40B7900D4C3FFF2FAFF8985";

现在,我想以这种模式将此字符串转换为上述类对象:

//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)

可以使用<reinterpret_cast>在c ++中轻松实现这种转换,但是正如所说的Is there cast in Java similar to in C++问题,我可以在Java中使用序列化来实现。我认为,当我们首先将一个类对象序列化为字节数组时,可以使用序列化,然后我们可以将获得的字节反序列化为原始类对象,这与我的建议有点不同,因为我有一个字符串(例如字节),我想对此进行反序列化。那我该怎么办呢?

3 个答案:

答案 0 :(得分:4)

Java序列化具有非常特殊的数据格式,它不能帮助您解析使用其他预定义格式获得的数据。但是a ByteBuffer在解析此类数据时可能很有用。

首先,您需要将字符串转换为实际的byte[]数组。我将使用this answer中的一个简单解决方案,随时选择另一个更适合您的示例的解决方案:

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

是否需要进行order()调用取决于数据所在的字节序。ByteBuffer默认为BIG_ENDIAN,因此如果需要,可以将其省略

答案 1 :(得分:3)

我认为<reinterpret_cast>不会奏效。 "1000"的内部字节表示是4个ASCII字节。一个用于字符10x31),然后是3个字符00x30),而不是十六进制的0x10, 0x00。您将在id<reinterpret_cast>中得到的结果将是十六进制0x31303030而不是0x1000

您需要做的是解析字符串的不同组成部分。

类似的事情应该做:

int id = Integer.parseInt(str.substring(0,4), 16);

答案 2 :(得分:2)

您只需要splitparse

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