Bájt tömbök és hexadecimális karakterláncok közötti konvertálás a Java-ban
1. Áttekintés
Ebben az oktatóanyagban megvizsgáljuk a bájt tömb hexadecimálissá alakításának különböző módjait Húr, és fordítva.
Megértjük a konverziós mechanizmust és meg fogjuk írni a megvalósításunkat ennek elérése érdekében.
2. Konvertálás bájt és hexadecimális között
Először vessünk egy pillantást a bájt és a hexadecimális számok közötti konverziós logikára.
2.1. Bájttól hexadecimálisig
A bájtok 8 bites előjelű egész számok a Java-ban. Ezért kell mindegyik 4 bites szegmenst külön-külön hexává konvertálja és összefűzi. Következésképpen az átalakítás után két hexadecimális karaktert kapunk.
Például a 45-et 0010 1101-nek írhatjuk bináris formában, és a hexadecimális egyenérték „2d” lesz:
0010 = 2 (10. alap) = 2 (16. alap) 1101 = 13 (10. alap) = d (16. alap) Ezért: 45 = 0010 1101 = 0x2d
Vezessük be ezt az egyszerű logikát a Java-ban:
public String byteToHex (bájt száma) {char [] hexDigits = új char [2]; hexDigits [0] = Character.forDigit ((szám >> 4) & 0xF, 16); hexDigits [1] = Character.forDigit ((szám & 0xF), 16); return new String (hexDigits); }
Most értsük meg a fenti kódot az egyes műveletek elemzésével. Először is létrehoztunk egy 2 hosszúságú char tömböt a kimenet tárolására:
char [] hexDigits = új char [2];
Ezután magasabb rendű biteket izoláltunk 4 bit jobbra tolásával. Ezután maszkot alkalmaztunk az alacsonyabb rendű 4 bit elkülönítésére. A maszkolásra azért van szükség, mert a negatív számok belsőleg képviselik a pozitív szám kettő kiegészítését:
hexDigits [0] = Character.forDigit ((szám >> 4) & 0xF, 16);
Ezután a fennmaradó 4 bitet hexadecimálissá konvertáljuk:
hexDigits [1] = Character.forDigit ((szám & 0xF), 16);
Végül létrehozunk egy Húr objektum a char tömbből. Ezután visszaadta ezt az objektumot konvertált hexadecimális tömbként.
Most pedig értsük meg, hogyan fog működni ez egy negatív bájt -4 esetén:
hexDigits [0]: 1111 1100 >> 4 = 1111 1111 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 Ezért: -4 (10. alap) = 1111 1100 (2. alap) = fc (16. alap)
Azt is érdemes megjegyezni, hogy a Karakter.forDigit() A metódus mindig kisbetűket ad vissza.
2.2. Hexadecimális bájtig
Most konvertáljuk a hexadecimális számjegyet bájttá. Mint tudjuk, egy bájt 8 bitet tartalmaz. Ebből kifolyólag, egy bájt létrehozásához két hexadecimális számjegyre van szükségünk.
Először minden hexadecimális számjegyet külön alakítunk át bináris egyenértékre.
Ezután össze kell összefűznünk a két négy bites szegmenst, hogy megkapjuk a bájtegyenértéket:
Hexadecimális: 2d 2 = 0010 (2. alap) d = 1101 (2. alap) Ezért: 2d = 0010 1101 (2. alap) = 45
Most írjuk meg a műveletet Java-ban:
public byte hexToByte (String hexString) {int firstDigit = toDigit (hexString.charAt (0)); int secondDigit = toDigit (hexString.charAt (1)); return (byte) ((elsőDigit << 4) + másodikDigit); } private int toDigit (char hexChar) {int digit = Karakter.digit (hexChar, 16); if (digit == -1) {dobjon új IllegalArgumentException ("Érvénytelen hexadecimális karakter:" + hexChar); } visszatérő számjegy; }
Értsük meg ezt, egy-egy műveletet.
Mindenekelőtt a hexadecimális karaktereket egész számokká alakítottuk át:
int firstDigit = toDigit (hexString.charAt (0)); int secondDigit = toDigit (hexString.charAt (1));
Ezután a legjelentősebb számjegyet eltoltuk 4 bittel. Következésképpen a bináris ábrázolásnak négy legkevésbé jelentős bitje van.
Ezután hozzáadtuk a legkevésbé jelentős számjegyet:
return (byte) ((elsőDigit << 4) + másodikDigit);
Most vizsgáljuk meg a toDigit () módszer szorosan. A Karakter.digit () módszer az átalakításra. Ha az erre a módszerre továbbított karakterérték nem érvényes számjegy a megadott tartományban, akkor a -1 érték jelenik meg.
Érvényesítjük a visszatérési értéket és kivételt vetünk, ha érvénytelen értéket adtunk át.
3. Konvertálás a bájt tömbök és a hexadecimális között Húrok
Ezen a ponton tudjuk, hogyan lehet egy bájtot hexadecimálissá konvertálni, és fordítva. Méretezzük ezt az algoritmust, és konvertáljuk a bájtömböt hexadecimális értékre / számra Húr.
3.1. Bájtömb hexadecimálisra Húr
Végig kell lépnünk a tömbön, és minden bájthoz hexadecimális párokat kell létrehoznunk:
public String encodeHexString (byte [] byteArray) {StringBuffer hexStringBuffer = új StringBuffer (); for (int i = 0; i <byteArray.length; i ++) {hexStringBuffer.append (byteToHex (byteArray [i])); } return hexStringBuffer.toString (); }
Mint már tudjuk, a kimenet mindig kisbetűs lesz.
3.2. Hexadecimális karakterlánc-byte tömb
Először meg kell vizsgálnunk, hogy a hexadecimális hossza megvan-e Húr páros szám. Ez azért van, mert egy hexadecimális Húr páratlan hosszúsággal helytelen bájt ábrázolást eredményez.
Most iteráljuk a tömböt, és minden hexadecimális párt átalakítunk bájttá:
public byte [] decodeHexString (String hexString) {if (hexString.length ()% 2 == 1) {dobjon új IllegalArgumentException-t ("Érvénytelen hexadecimális karakterláncot tartalmaz."); } bájt [] bájt = új bájt [hexString.length () / 2]; for (int i = 0; i <hexString.length (); i + = 2) {byte [i / 2] = hexToByte (hexString.substring (i, i + 2)); } visszatérési bájtok; }
4. A BigInteger Osztály
Tudunk típusú objektum létrehozása BigInteger aláírás és bájt tömb átadásával.
Most előállíthatjuk a hexadecimális értéket Húr alatt definiált statikus módszerformátum segítségével Húr osztály:
public String encodeUsingBigIntegerStringFormat (byte [] byte) {BigInteger bigInteger = új BigInteger (1, bájt); return String.format ("% 0" + (bájtok.hossz << 1) + "x", bigInteger); }
A megadott formátum nulla betétű kisbetűket generál Húr. Nagybetűs karakterláncot is létrehozhatunk, ha az „x” -et „X” -re cseréljük.
Alternatív megoldásként használhatnánk a toString () módszer től BigInteger. A finom különbség a toString () A módszer az, hogy a kimenet nincs kitöltve vezető nullákkal:
public String encodeUsingBigIntegerToString (byte [] byte) {BigInteger bigInteger = új BigInteger (1, bájt); return bigInteger.toString (16); }
Most vessünk egy pillantást a hexadecimálisra Húr nak nek byte Tömb konverzió:
public byte [] decodeUsingBigInteger (String hexString) {byte [] byteArray = new BigInteger (hexString, 16) .toByteArray (); if (byteArray [0] == 0) {byte [] output = új byte [byteArray.length - 1]; System.arraycopy (byteArray, 1, output, 0, output.length); visszatérő kimenet; } return byteArray; }
A toByteArray () metódus további előjel bitet állít elő. Külön kódot írtunk ennek a további bitnek a kezelésére.
Ennélfogva tudnunk kell ezeket a részleteket, mielőtt a BigInteger osztály az átalakításhoz.
5. A DataTypeConverter Osztály
A DataTypeConverter osztály JAXB könyvtárral van ellátva. Ez a Java 8-ig terjedő standard könyvtár része. A Java 9-től kezdve hozzá kell adnunk java.xml.bind modult a futásidőhöz kifejezetten.
Vessünk egy pillantást a megvalósításra a DataTypeConverter osztály:
public String encodeUsingDataTypeConverter (byte [] byte) {return DatatypeConverter.printHexBinary (byte); } public byte [] decodeUsingDataTypeConverter (String hexString) {return DatatypeConverter.parseHexBinary (hexString); }
Amint fent látható, nagyon kényelmes használni DataTypeConverter osztály. A kimenete printHexBinary () módszer mindig nagybetűvel van. Ez az osztály nyomtatási és elemzési módszereket kínál az adattípus-átalakításhoz.
Mielőtt ezt a megközelítést választanánk, meg kell győződnünk arról, hogy az osztály futás közben elérhető lesz-e.
6. Az Apache Commons-Codec Library használata
Használhatjuk a Hex osztály az Apache commons-codec könyvtárral szállítva:
public String encodeUsingApacheCommons (byte [] byte) dobja a DecoderException {return Hex.encodeHexString (byte); } public byte [] decodeUsingApacheCommons (String hexString) dobja a DecoderException {return Hex.decodeHex (hexString); }
A kimenete encodeHexString mindig kisbetûs.
7. A Google Guava könyvtárának használata
Vessünk egy pillantást arra, hogyan BaseEncoding osztály használható a bájt tömb kódolására és dekódolására a hexadecimális értékig Húr:
public String encodeUsingGuava (byte [] byte) {return BaseEncoding.base16 (). encode (byte); } public byte [] decodeUsingGuava (String hexString) {return BaseEncoding.base16 () .decode (hexString.toUpperCase ()); }
A BaseEncoding alapértelmezés szerint nagybetűk használatával kódol és dekódol. Ha kisbetűket kell használnunk, új kódolási példányt kell létrehozni a statikus metódus kisbetűivel.
8. Következtetés
Ebben a cikkben megtanultuk a bájt tömb hexadecimális közötti konverziós algoritmusát Húr. Megvitattuk a bájt tömb hex sztringbe történő kódolásának különféle módszereit is és fordítva.
Nem ajánlott könyvtárat hozzáadni csak néhány segédprogram használatához. Ezért, ha még nem használjuk a külső könyvtárakat, akkor a tárgyalt algoritmust kell használnunk. A DataTypeConverter osztály egy másik módja a különféle adattípusok közötti kódolásnak / dekódolásnak.
Végül az oktatóanyag teljes forráskódja elérhető a GitHubon.