Konvertering mellem byte-arrays og hexadecimale strenge i Java

1. Oversigt

I denne vejledning ser vi på forskellige måder at konvertere en byte-array til en hexadecimal Snor, og omvendt.

Vi forstår også konverteringsmekanismen og skriver vores implementering for at opnå dette.

2. Konvertering mellem byte og hexadecimal

Lad os først se på konverteringslogikken mellem byte og hexadecimale tal.

2.1. Byte til hexadecimal

Bytes er 8 bit signerede heltal i Java. Derfor er vi nødt til det konvertere hvert 4-bit segment til hex separat og sammenkæde dem. Derfor får vi to hexadecimale tegn efter konvertering.

For eksempel kan vi skrive 45 som 0010 1101 i binær, og den hexadecimale ækvivalent vil være "2d":

0010 = 2 (base 10) = 2 (base 16) 1101 = 13 (base 10) = d (base 16) Derfor: 45 = 0010 1101 = 0x2d 

Lad os implementere denne enkle logik i Java:

public String byteToHex (byte num) {char [] hexDigits = new char [2]; hexDigits [0] = Character.forDigit ((num >> 4) & 0xF, 16); hexDigits [1] = Character.forDigit ((num & 0xF), 16); returner ny streng (hexDigits); }

Lad os nu forstå ovenstående kode ved at analysere hver operation. Først og fremmest oprettede vi et char-array af længde 2 til at gemme output:

char [] hexDigits = ny char [2];

Dernæst isolerede vi højere ordens bits ved at skifte 4 bits til højre. Og så anvendte vi en maske for at isolere 4 bit i lavere orden. Maskering er påkrævet, fordi negative tal er internt repræsenteret som to komplement af det positive tal:

hexDigits [0] = Character.forDigit ((num >> 4) & 0xF, 16);

Derefter konverterer vi de resterende 4 bits til hexadecimal:

hexDigits [1] = Character.forDigit ((num & 0xF), 16);

Endelig opretter vi en Snor objekt fra char array. Og returnerede derefter dette objekt som konverteret hexadecimal array.

Lad os nu forstå, hvordan dette vil fungere for en negativ byte -4:

hexDigits [0]: 1111 1100 >> 4 = 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1111 = 0xf hexDigits [1]: 1111 1100 & 0xF = 0000 1100 = 0xc Derfor: -4 (base 10) = 1111 1100 (base 2) = fc (base 16)

Det er også værd at bemærke, at Karakter.forDigit() metoden returnerer altid små bogstaver.

2.2. Hexadecimal til byte

Lad os nu konvertere et hexadecimalt ciffer til byte. Som vi ved, indeholder en byte 8 bits. Derfor, vi har brug for to hexadecimale cifre for at oprette en byte.

Først og fremmest konverterer vi hvert hexadecimalt ciffer til binærækvivalent separat.

Og så skal vi sammenkæde de to fire bit-segmenter for at få byteækvivalenten:

Hexadecimal: 2d 2 = 0010 (base 2) d = 1101 (base 2) Derfor: 2d = 0010 1101 (base 2) = 45

Lad os nu skrive operationen i Java:

offentlig byte hexToByte (String hexString) {int firstDigit = toDigit (hexString.charAt (0)); int secondDigit = toDigit (hexString.charAt (1)); return (byte) ((firstDigit << 4) + secondDigit); } privat int tilDigit (char hexChar) {int ciffer = Character.digit (hexChar, 16); hvis (ciffer == -1) {kast nyt IllegalArgumentException ("Ugyldig hexadecimal karakter:" + hexChar); } return ciffer; }

Lad os forstå dette, en operation ad gangen.

Først og fremmest konverterede vi hexadecimale tegn til heltal:

int firstDigit = toDigit (hexString.charAt (0)); int secondDigit = toDigit (hexString.charAt (1));

Så forlod vi det skiftende ciffer med 4 bits. Derfor har den binære repræsentation nuller på fire mindst signifikante bits.

Derefter tilføjede vi det mindst betydningsfulde ciffer til det:

return (byte) ((firstDigit << 4) + secondDigit);

Lad os nu undersøge toDigit () metode nøje. Vi bruger Character.digit () metode til konvertering. Hvis tegnværdien, der sendes til denne metode, ikke er et gyldigt ciffer i den angivne radix, returneres -1.

Vi validerer returværdien og kaster en undtagelse, hvis en ugyldig værdi blev videregivet.

3. Konvertering mellem byte-arrays og hexadecimal Strenge

På dette tidspunkt ved vi, hvordan man konverterer en byte til hexadecimalen og omvendt. Lad os skalere denne algoritme og konvertere byte-array til / fra hexadecimal Snor.

3.1. Byte Array til hexadecimal Snor

Vi skal løkke gennem arrayet og generere hexadecimalt par for hver byte:

public String encodeHexString (byte [] byteArray) {StringBuffer hexStringBuffer = new StringBuffer (); for (int i = 0; i <byteArray.length; i ++) {hexStringBuffer.append (byteToHex (byteArray [i])); } returner hexStringBuffer.toString (); }

Som vi allerede ved, vil output altid være med små bogstaver.

3.2. Hexadecimal streng til Byte Array

Først og fremmest skal vi kontrollere, om længden af ​​hexadecimalen Snor er et lige antal. Dette er fordi en hexadecimal Snor med ulige længde vil resultere i forkert byterepræsentation.

Nu gentager vi gennem arrayet og konverterer hvert hexadecimale par til en byte:

public byte [] decodeHexString (String hexString) {if (hexString.length ()% 2 == 1) {throw new IllegalArgumentException ("Ugyldig hexadecimal streng leveret."); } byte [] bytes = ny byte [hexString.length () / 2]; for (int i = 0; i <hexString.length (); i + = 2) {bytes [i / 2] = hexToByte (hexString.substring (i, i + 2)); } returnere bytes; }

4. Brug af BigInteger Klasse

Vi kan Opret et objekt af typen BigInteger ved at passere et signum og byte array.

Nu kan vi generere hexadecimalt Snor ved hjælp af formatet for statisk metode defineret i Snor klasse:

public String encodeUsingBigIntegerStringFormat (byte [] bytes) {BigInteger bigInteger = new BigInteger (1, bytes); returnere String.format ("% 0" + (bytes.length << 1) + "x", bigInteger); }

Det angivne format genererer en nul-polstret lille bogstav hexadecimal Snor. Vi kan også generere en stor bogstav ved at erstatte “x” med “X”.

Alternativt kunne vi have brugt toString () metode fra BigInteger. Den subtile forskellen ved at bruge toString () metoden er, at output ikke er polstret med førende nuller:

public String encodeUsingBigIntegerToString (byte [] bytes) {BigInteger bigInteger = new BigInteger (1, bytes); returner bigInteger.toString (16); }

Lad os nu se på hexadecimal Snor til byte Konvertering af matrix:

public byte [] decodeUsingBigInteger (String hexString) {byte [] byteArray = new BigInteger (hexString, 16) .toByteArray (); hvis (byteArray [0] == 0) {byte [] output = ny byte [byteArray.length - 1]; System.arraycopy (byteArray, 1, output, 0, output.length); returnere output; } returner byteArray; }

Det toByteArray () metode producerer en ekstra tegnbit. Vi har skrevet en specifik kode til håndtering af denne ekstra bit.

Derfor skal vi være opmærksomme på disse detaljer, inden vi bruger BigInteger klasse til konvertering.

5. Brug af DataTypeConverter Klasse

Det DataTypeConverter klasse leveres med JAXB-bibliotek. Dette er en del af standardbiblioteket indtil Java 8. Fra Java 9 skal vi tilføje java.xml.bind modul til runtime eksplicit.

Lad os se på implementering ved hjælp af DataTypeConverter klasse:

public String encodeUsingDataTypeConverter (byte [] bytes) {return DatatypeConverter.printHexBinary (bytes); } offentlig byte [] decodeUsingDataTypeConverter (String hexString) {return DatatypeConverter.parseHexBinary (hexString); }

Som vist ovenfor er det meget praktisk at bruge DataTypeConverter klasse. Det output af printHexBinary () metoden er altid med store bogstaver. Denne klasse leverer et sæt udskrivnings- og parsemetoder til datatypekonvertering.

Før vi vælger denne tilgang, skal vi sørge for, at klassen er tilgængelig under kørsel.

6. Brug af Apache's Commons-Codec Library

Vi kan bruge Hex klasse leveret med Apache commons-codec-biblioteket:

public String encodeUsingApacheCommons (byte [] bytes) kaster DecoderException {return Hex.encodeHexString (bytes); } offentlig byte [] decodeUsingApacheCommons (String hexString) kaster DecoderException {return Hex.decodeHex (hexString); }

Det output af encodeHexString er altid med små bogstaver.

7. Brug af Googles Guava-bibliotek

Lad os se på hvordan BaseEncoding klasse kan bruges til kodning og afkodning af byte-array til hexadecimalt Snor:

public String encodeUsingGuava (byte [] bytes) {return BaseEncoding.base16 (). encode (bytes); } offentlig byte [] decodeUsingGuava (String hexString) {return BaseEncoding.base16 () .decode (hexString.toUpperCase ()); } 

Det BaseEncoding koder og afkoder ved hjælp af store bogstaver som standard. Hvis vi har brug for små bogstaver, skal der oprettes en ny kodningsinstans ved hjælp af statiske metoder små bogstaver.

8. Konklusion

I denne artikel lærte vi konverteringsalgoritmen mellem byte-array til hexadecimal Snor. Vi diskuterede også forskellige metoder til at kode byte-array til hex-streng og omvendt.

Det tilrådes ikke at tilføje et bibliotek for kun at bruge et par hjælpemetoder. Derfor, hvis vi ikke allerede bruger de eksterne biblioteker, skal vi bruge den diskuterede algoritme. Det DataTypeConverter klasse er en anden måde at kode / afkode mellem forskellige datatyper.

Endelig er den komplette kildekode til denne vejledning tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found