2
votes

Convertir une chaîne hexadécimale en objet de classe

J'ai une classe comme celle-ci:

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

et j'ai une chaîne hexadécimale avec la valeur comme celle-ci dont chaque 2 caractères est représentatif d'un octet:

String str="1000180018000540AC80D6487653E5000100D40B7900D4C3FFF2FAFF8985";

Maintenant, je veux convertir cette chaîne en objet de classe ci-dessus dans un schéma comme celui-ci:

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

Ce casting peut être implémenté en c ++ avec si facilement mais comme le Y at-il un cast en Java similaire à la question C ++ est dit, je peux l'implémenter avec la sérialisation en java. Je pense que la sérialisation peut être utilisée lorsque nous sérialisons un objet de classe dans les tableaux d'octets au premier et au deuxième, nous pouvons désérialiser les octets obtenus en l'objet de classe primitif, ce qui est un peu différent de ce que je propose, car j'ai une chaîne (comme bytes) que je souhaite désérialiser. Alors, comment puis-je faire ça?


5 commentaires

La sérialisation ne vous aidera pas. Il a un format très spécifique qui ne correspond pas au vôtre. Vous devez analyser votre chaîne manuellement.


@talex mais C ++ le font avec facilement. Il n'y a donc aucun moyen comme en java? Parce que la vitesse est importante pour moi et que l'analyse manuelle avec une chaîne de données à haut débit sera un goulot d'étranglement!


Non ne l'aurait pas fait facilement. Cela ne fonctionnera même pas. "1000" correspond à 4 octets ASCII, 0x31, 0x30, 0x30, 0x30, C ++ ne le convertira pas comme par magie en 2 octets 0x10, 0x00.


@ahmadimortezaali si vous voulez utiliser , vous devez utiliser c ++ :) Java n'a rien de tel.


stackoverflow.com/questions/140131/...


3 Réponses :


2
votes

Il vous suffit de fractionner et analyser

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


0 commentaires

4
votes

La sérialisation Java a un format de données très spécifique et ne vous aide pas à analyser les données que vous obtenez avec un format prédéfini différent. Mais un ByteBuffer a> peut être utile pour analyser ce type de données.

Vous devez d'abord transformer votre chaîne en un tableau byte [] réel. J'utiliserai une solution simple de cette réponse , n'hésitez pas à en choisir une autre plus appropriée à votre exemple:

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

Que vous ayez besoin ou non de la commande ( ) dépend de la finalité de vos données. ByteBuffer est défini par défaut sur BIG_ENDIAN , vous pouvez donc simplement laisser cet appel si c'est ce dont vous avez besoin. p>


3 commentaires

C'est une bonne utilisation de NIO ByteBuffer .


Merci beaucoup! En changeant buffer.order (ByteOrder.LITTLE_ENDIAN); en buffer.order (ByteOrder.BIG_ENDIAN); le résultat que je veux a été parfaitement atteint!


@ahmadimortezaali: notez que BIG_ENDIAN est la valeur par défaut, donc dans ce cas, vous pouvez également l'omettre entièrement.



3
votes

Je ne pense pas que aurait fonctionné. La représentation octet interne de "1000" est de 4 octets ASCII. Un pour le caractère 1 ( 0x31 ) suivi de 3 caractères 0 ( 0x30 ), et non de 0x10, 0x00 hexadécimal. Le résultat que vous obtiendrez dans id avec serait hexadécimal 0x31303030 et non 0x1000 .

Quoi vous devez analyser les différents composants de la chaîne.

Quelque chose comme ça devrait faire:

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


2 commentaires

Vous vouliez probablement dire int id = ... ?


Oui, j'allais le faire en 2 lignes mais j'ai changé d'avis et j'ai oublié de changer de type.