Konvertere mellom byte-arrays og heksadesimale strenger i Java

1. Oversikt

I denne opplæringen tar vi en titt på forskjellige måter å konvertere en byte-matrise til en heksadesimal Streng, og vice versa.

Vi vil også forstå konverteringsmekanismen og skrive implementeringen for å oppnå dette.

2. Konvertering mellom byte og heksadesimal

La oss først ta en titt på konverteringslogikken mellom byte og heksadesimale tall.

2.1. Byte til heksadesimal

Byte er 8 bit signerte heltall i Java. Derfor må vi konvertere hvert 4-bits segment til hex separat og sammenkoble dem. Derfor får vi to heksadesimale tegn etter konvertering.

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

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

La oss implementere denne enkle logikken 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); }

La oss nå forstå koden ovenfor ved å analysere hver operasjon. Først av alt opprettet vi en char-array med lengde 2 for å lagre utdataene:

char [] hexDigits = new char [2];

Deretter isolerte vi høyere ordensbiter ved å høyre skifte 4 bits. Og så brukte vi en maske for å isolere 4 biters orden. Maskering er nødvendig fordi negative tall er internt representert som to komplement til det positive tallet:

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

Deretter konverterer vi de resterende 4 bitene til heksadesimale:

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

Til slutt lager vi en String objekt fra røyeoppstillingen. Og returnerte deretter dette objektet som konvertert heksadesimal matrise.

La oss nå 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å verdt å merke seg at Karakter.forDigit() metoden returnerer alltid små bokstaver.

2.2. Hexadecimal til Byte

La oss nå konvertere et heksadesimalt siffer til byte. Som vi vet inneholder en byte 8 biter. Derfor, vi trenger to heksadesimale sifre for å lage en byte.

Først og fremst konverterer vi hvert heksadesimale siffer til binær ekvivalent hver for seg.

Og så må vi sammenkoble de to fire bit-segmentene for å få byteekvivalenten:

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

La oss nå skrive operasjonen i Java:

offentlig byte hexToByte (String hexString) {int firstDigit = toDigit (hexString.charAt (0)); int secondDigit = toDigit (hexString.charAt (1)); return (byte) ((firstDigit << 4) + secondDigit); } private int toDigit (char hexChar) {int digit = Character.digit (hexChar, 16); if (digit == -1) {throw new IllegalArgumentException ("Invalid Hexadecimal Character:" + hexChar); } retur siffer; }

La oss forstå dette, en operasjon om gangen.

Først av alt konverterte vi heksadesimale tegn til heltall:

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

Så forlot vi det viktigste tallet med 4 bits. Følgelig har den binære representasjonen nuller på fire minst signifikante biter.

Deretter la vi til det minst betydningsfulle sifferet til det:

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

La oss nå undersøke toDigit () metode tett. Vi bruker Character.digit () metode for konvertering. Hvis tegnverdien som sendes til denne metoden ikke er et gyldig siffer i den angitte radiksen, returneres -1.

Vi validerer returverdien og kaster et unntak hvis en ugyldig verdi ble overført.

3. Konvertering mellom byte-arrays og heksadesimal Strenger

På dette tidspunktet vet vi hvordan vi konverterer en byte til heksadesimale, og omvendt. La oss skalere denne algoritmen og konvertere byte-array til / fra heksadesimal String.

3.1. Byte Array til heksadesimal String

Vi må løpe gjennom matrisen og generere heksadesimalt 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 vet, vil produksjonen alltid være med små bokstaver.

3.2. Heksadesimal streng til Byte Array

Først og fremst må vi sjekke om lengden på heksadesimale String er et partall. Dette er fordi en heksadesimal String med ulik lengde vil resultere i feil byte-representasjon.

Nå vil vi iterere gjennom matrisen og konvertere hvert heksadesimale par til en byte:

offentlig byte [] decodeHexString (String hexString) {if (hexString.length ()% 2 == 1) {kast ny IllegalArgumentException ("Ugyldig heksadesimal streng leveres."); } byte [] byte = ny byte [hexString.length () / 2]; for (int i = 0; i <hexString.length (); i + = 2) {bytes [i / 2] = hexToByte (hexString.substring (i, i + 2)); } returner byte; }

4. Bruke BigInteger Klasse

Vi kan lage et objekt av typen BigInteger ved å passere et signum og byte-array.

Nå kan vi generere heksadesimale String ved hjelp av statisk metode format definert i String klasse:

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

Formatet som gis vil generere en heksadesimal med liten bokstav String. Vi kan også generere en stor bokstav ved å erstatte “x” med “X”.

Alternativt kunne vi ha brukt toString () metode fra BigInteger. Det subtile forskjellen mellom å bruke toString () metoden er at utdataene ikke er polstret med ledende nuller:

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

La oss nå se på heksadesimal String til byte Konvertering av matrisen:

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

De toByteArray () metoden produserer en ekstra tegnbit. Vi har skrevet spesifikk kode for håndtering av denne ekstra biten.

Derfor bør vi være klar over disse detaljene før vi bruker BigInteger klasse for konvertering.

5. Bruke DataTypeConverter Klasse

De DataTypeConverter klasse leveres med JAXB bibliotek. Dette er en del av standardbiblioteket frem til Java 8. Fra og med Java 9, må vi legge til java.xml.bind modul til kjøretiden eksplisitt.

La oss ta en titt på implementering ved hjelp av 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 veldig praktisk å bruke DataTypeConverter klasse. De utdata fra printHexBinary () metoden er alltid med store bokstaver. Denne klassen leverer et sett med utskrifts- og analyseringsmetoder for datatypekonvertering.

Før vi velger denne tilnærmingen, må vi sørge for at klassen vil være tilgjengelig i løpetid.

6. Bruke Apache's Commons-Codec Library

Vi kan bruke Hex klasse som følger 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); }

De produksjon av encodeHexString er alltid med små bokstaver.

7. Bruke Googles Guava-bibliotek

La oss ta en titt på hvordan BaseEncoding klasse kan brukes til koding og dekoding av byte-array til heksadesimale Streng:

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

De BaseEncoding koder og dekoder ved hjelp av store bokstaver som standard. Hvis vi trenger å bruke små bokstaver, bør en ny kodingsforekomst opprettes ved hjelp av statiske metoden små bokstaver.

8. Konklusjon

I denne artikkelen lærte vi konverteringsalgoritmen mellom byte-array til heksadesimal String. Vi diskuterte også forskjellige metoder for å kode byte-array til hex-streng og omvendt.

Det anbefales ikke å legge til et bibliotek for kun å bruke et par verktøy. Derfor, hvis vi ikke allerede bruker de eksterne bibliotekene, bør vi bruke algoritmen som er diskutert. De DataTypeConverter klasse er en annen måte å kode / dekode mellom forskjellige datatyper.

Til slutt er den komplette kildekoden til denne opplæringen tilgjengelig på GitHub.


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