Convertire una rappresentazione in formato stringa di un dump esadecimale in un array di byte utilizzando Java?


372

Sto cercando un modo per convertire una stringa lunga (da un dump), che rappresenta valori esadecimali in una matrice di byte.

Non avrei potuto esprimerlo meglio della persona che ha pubblicato la stessa domanda qui .

Ma per mantenerlo originale, lo dirò a modo mio: supponiamo di avere una stringa "00A0BF"che vorrei interpretare come

byte[] {0x00,0xA0,0xBf}

cosa dovrei fare?

Sono un novizio di Java e ho finito per usare BigIntegere fare attenzione ai principali zeri esadecimali. Ma penso che sia brutto e sono sicuro che mi manca qualcosa di semplice.



Ho domato BigInteger qui .
John McClane,

FWIW String.getBytes()non funzionerà come pensi che potrebbe. Ho dovuto imparare questo nel modo più duro. if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
tir38,

Risposte:


636

Ecco una soluzione che penso sia migliore di qualsiasi post pubblicato finora:

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

Ragioni per cui è un miglioramento:

  • Sicuro con zeri iniziali (a differenza di BigInteger) e con valori di byte negativi (a differenza di Byte.parseByte)

  • Non converte String in a char[], né crea oggetti StringBuilder e String per ogni singolo byte.

  • Nessuna dipendenza dalla libreria che potrebbe non essere disponibile

Sentiti libero di aggiungere il controllo degli argomenti tramite asserto eccezioni se l'argomento non è noto per essere sicuro.


2
Puoi fare un esempio che è stato decodificato in modo errato o spiegare come è sbagliato?
Dave L.,

5
Non funziona per la stringa "0".
Genera

49
"0" non è un input valido. I byte richiedono due cifre esadecimali ciascuno. Come osserva la risposta, "Sentiti libero di aggiungere il controllo degli argomenti ... se l'argomento non è noto per essere sicuro."
Dave L.,

12
javax.xml.bind.DatatypeConverter.parseHexBinary (hexString) sembra essere circa il 20% più veloce della soluzione di cui sopra nei miei micro test (per quel poco che valgono), oltre a gettare correttamente eccezioni su input non validi (ad esempio "gg" non è un hexString valido ma restituirà -77 usando la soluzione come proposto).
Trevor Freeman

6
@DaedalusAlpha Dipende dal tuo contesto, ma di solito trovo che sia meglio fallire velocemente e rumorosamente con tali cose in modo da poter correggere i tuoi presupposti piuttosto che restituire silenziosamente dati errati.
Dave L.,

331

One-liner:

import javax.xml.bind.DatatypeConverter;

public static String toHexString(byte[] array) {
    return DatatypeConverter.printHexBinary(array);
}

public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
}

Avvertenze :

  • in Java 9 Jigsaw questo non fa più parte del set di root (predefinito) java.se, quindi si tradurrà in ClassNotFoundException a meno che non si specifichi --add-modules java.se.ee (grazie a @ eckes)
  • Non disponibile su Android (grazie Fabianper averlo notato), ma puoi semplicemente prendere il codice sorgente se il tuo sistema manca javax.xmlper qualche motivo. Grazie a @ Bert Regelinkper l'estrazione della fonte.

14
IMHO questa dovrebbe essere la risposta accettata / migliore poiché è breve e pulita (a differenza della risposta di @ DaveL) e non richiede librerie esterne (come la risposta di Skaffman). Inoltre, <Inserisci uno scherzo consumato sul reinventare la bicicletta> .
Priidu Neemre,

9
la classe datatypeconverter non è disponibile ad esempio in Android.
Fabian,

4
Avvertenza: in Java 9 Jigsaw questo non fa più parte del java.seset di root (predefinito) quindi si tradurrà in a ClassNotFoundExceptionmeno che non specifichi--add-modules java.se.ee
eckes

2
@dantebarba Penso che javax.xml.bind.DatatypeConvertergià fornisca un metodo per codificare / decodificare i dati Base64. Vedi parseBase64Binary()e printBase64Binary().
DragShot

2
Per aggiungere problemi DataTypeConverter, Java SE 11 ha rimosso completamente l'API JAXB ed è ora incluso solo con Java EE. Puoi anche aggiungerlo come dipendenza Maven, come suggerito qui: stackoverflow.com/a/43574427/7347751
David Mordigal

79

La classe Hex nel codec comune dovrebbe farlo per te.

http://commons.apache.org/codec/

import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF

6
Anche questo sembra buono. Vedi org.apache.commons.codec.binary.Hex.decodeHex ()
Dave L.,

Era interessante. Ma ho trovato la loro soluzione difficile da seguire. Ha qualche vantaggio rispetto a quello che hai proposto (oltre a controllare il numero pari di caratteri)?
rafraf,

38

È ora possibile utilizzare BaseEncoding in guavaper raggiungere questo obiettivo.

BaseEncoding.base16().decode(string);

Per invertire usare

BaseEncoding.base16().encode(bytes);

27

In realtà, penso che la soluzione BigInteger sia molto bella:

new BigInteger("00A0BF", 16).toByteArray();

Modifica: non sicuro per gli zeri iniziali , come indicato dal poster.


L'ho pensato anche inizialmente. E grazie per averlo documentato - stavo solo pensando che avrei dovuto ... ha fatto alcune cose strane che non capivo davvero - come omettere alcuni 0x00 iniziali e anche mescolare l'ordine di 1 byte in una stringa di 156 byte I stava giocando con.
rafraf,

2
Questo è un buon punto sui primi 0. Non sono sicuro di credere che potrebbe confondere l'ordine dei byte e sarei molto interessato a vederlo dimostrato.
Dave L.,

1
sì, non appena l'ho detto, non mi credevo neanche :) Ho eseguito un confronto dell'array di byte da BigInteger con mmyers'fromHexString e (senza 0x00) contro la stringa offensiva - erano identici. Il "mix up" è accaduto, ma potrebbe essere stato qualcos'altro. Domani guarderò più da vicino
rafraf,

3
Il problema con BigInteger è che ci deve essere un "bit di segno". Se il byte iniziale ha il bit alto impostato, l'array di byte risultante ha uno 0 in più nella 1a posizione. Ma ancora +1.
Grigio,

25

One-liner:

import javax.xml.bind.DatatypeConverter;

public static String toHexString(byte[] array) {
    return DatatypeConverter.printHexBinary(array);
}

public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
}

Per quelli di voi interessati al codice reale dietro One-liners di FractalizeR (avevo bisogno che dal momento che javax.xml.bind non è disponibile per Android (per impostazione predefinita)), questo proviene da com.sun.xml.internal.bind. DatatypeConverterImpl.java :

public byte[] parseHexBinary(String s) {
    final int len = s.length();

    // "111" is not a valid hex encoding.
    if( len%2 != 0 )
        throw new IllegalArgumentException("hexBinary needs to be even-length: "+s);

    byte[] out = new byte[len/2];

    for( int i=0; i<len; i+=2 ) {
        int h = hexToBin(s.charAt(i  ));
        int l = hexToBin(s.charAt(i+1));
        if( h==-1 || l==-1 )
            throw new IllegalArgumentException("contains illegal character for hexBinary: "+s);

        out[i/2] = (byte)(h*16+l);
    }

    return out;
}

private static int hexToBin( char ch ) {
    if( '0'<=ch && ch<='9' )    return ch-'0';
    if( 'A'<=ch && ch<='F' )    return ch-'A'+10;
    if( 'a'<=ch && ch<='f' )    return ch-'a'+10;
    return -1;
}

private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length*2);
    for ( byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}

3
DatatypeConverter non è inoltre disponibile in Java 9 per impostazione predefinita. La cosa pericolosa è che il codice che lo utilizza verrà compilato in Java 1.8 o precedenti (Java 9 con impostazioni di origine precedenti), ma ottiene un'eccezione di runtime in Java 9 senza "--add-modules java.se.ee".
Stephen M -on strike -

24

Il HexBinaryAdapterfornisce la capacità di maresciallo e non terrestre tra Stringe byte[].

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

public byte[] hexToBytes(String hexString) {
     HexBinaryAdapter adapter = new HexBinaryAdapter();
     byte[] bytes = adapter.unmarshal(hexString);
     return bytes;
}

Questo è solo un esempio che ho inserito ... In realtà lo uso così com'è e non ho bisogno di creare un metodo separato per usarlo.


5
Funziona solo se la stringa di input (hexString) ha un numero pari di caratteri. Altrimenti: eccezione nel thread "main" java.lang.IllegalArgumentException: hexBinary deve essere di lunghezza pari:
ovdsrn

3
Oh, grazie per averlo sottolineato. Un utente non dovrebbe davvero avere un numero dispari di caratteri perché l'array di byte è rappresentato come {0x00,0xA0,0xBf}. Ogni byte ha due cifre esadecimali o nibble. Quindi qualsiasi numero di byte dovrebbe sempre avere un numero pari di caratteri. Grazie per averlo menzionato.
GrkEngineer,

8
È possibile utilizzare java.xml.bind.DatatypeConverter.parseHexBinary (hexString) direttamente invece di utilizzare HexBinaryAdapter (che a sua volta chiama DatatypeConverter). In questo modo non è necessario creare un oggetto istanza dell'adattatore (poiché i metodi DatatypeConverter sono statici).
Trevor Freeman,

javax.xml.bind. * non è più disponibile in Java 9. La cosa pericolosa è che il codice che lo utilizza verrà compilato in Java 1.8 o precedente (Java 9 con impostazioni di origine precedenti), ma ottiene un'eccezione di runtime in esecuzione in Java 9.
Stephen M - sciopero -

15

Ecco un metodo che funziona effettivamente (basato su diverse risposte semi-corrette precedenti):

private static byte[] fromHexString(final String encoded) {
    if ((encoded.length() % 2) != 0)
        throw new IllegalArgumentException("Input string must contain an even number of characters");

    final byte result[] = new byte[encoded.length()/2];
    final char enc[] = encoded.toCharArray();
    for (int i = 0; i < enc.length; i += 2) {
        StringBuilder curr = new StringBuilder(2);
        curr.append(enc[i]).append(enc[i + 1]);
        result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
}

L'unico possibile problema che posso vedere è se la stringa di input è estremamente lunga; chiamando toCharArray () crea una copia dell'array interno della stringa.

EDIT: Oh, a proposito, i byte sono firmati in Java, quindi la stringa di input viene convertita in [0, -96, -65] anziché [0, 160, 191]. Ma probabilmente lo sapevi già.


1
Grazie Michael, sei un salvavita! Lavorando su un progetto BlackBerry e cercando di convertire una rappresentazione in stringa di un byte nel byte ... usando il metodo "Byte.parseByte (byteString, 16)" di RIM. Continua a lanciare un NumberFormatExcpetion. Ho passato ore a tirare per capire perché. Il tuo suggerimento di "Integer.praseInt ()" ha funzionato. Grazie ancora!!
BonanzaDriver,

12

In Android, se stai lavorando con hex, puoi provare okio .

utilizzo semplice:

byte[] bytes = ByteString.decodeHex("c000060000").toByteArray();

e il risultato sarà

[-64, 0, 6, 0, 0]

Ho testato molti metodi diversi ma questo è almeno due volte più veloce!
poby

5

Il BigInteger()metodo da java.math è molto lento e non raccomandabile.

Integer.parseInt(HEXString, 16)

può causare problemi con alcuni caratteri senza conversione in Cifra / Intero

un metodo ben funzionante:

Integer.decode("0xXX") .byteValue()

Funzione:

public static byte[] HexStringToByteArray(String s) {
    byte data[] = new byte[s.length()/2];
    for(int i=0;i < s.length();i+=2) {
        data[i/2] = (Integer.decode("0x"+s.charAt(i)+s.charAt(i+1))).byteValue();
    }
    return data;
}

Buon divertimento, buona fortuna


4

EDIT: come sottolineato da @mmyers, questo metodo non funziona su input che contengono sottostringhe corrispondenti a byte con il bit alto impostato ("80" - "FF"). La spiegazione è nell'ID bug: 6259307 Byte.parseByte non funziona come pubblicizzato nella documentazione SDK .

public static final byte[] fromHexString(final String s) {
    byte[] arr = new byte[s.length()/2];
    for ( int start = 0; start < s.length(); start += 2 )
    {
        String thisByte = s.substring(start, start+2);
        arr[start/2] = Byte.parseByte(thisByte, 16);
    }
    return arr;
}

1
Chiudi, ma questo metodo ha esito negativo sull'input specificato "00A0BBF". Vedi bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 .
Michael Myers

1
Stranamente, non si occupa di "9C"
rafraf,

1
@mmyers: whoa. Questo non è buono. Ci scusiamo per la confusione. @ravigad: 9C ha lo stesso problema perché in questo caso è impostato il bit alto.
Blair Conrad,

(byte) Short.parseShort (thisByte, 16) risolve il problema
Jamey Hicks,

3

Per quello che vale, ecco un'altra versione che supporta stringhe di lunghezza dispari, senza ricorrere alla concatenazione di stringhe.

public static byte[] hexStringToByteArray(String input) {
    int len = input.length();

    if (len == 0) {
        return new byte[] {};
    }

    byte[] data;
    int startIdx;
    if (len % 2 != 0) {
        data = new byte[(len / 2) + 1];
        data[0] = (byte) Character.digit(input.charAt(0), 16);
        startIdx = 1;
    } else {
        data = new byte[len / 2];
        startIdx = 0;
    }

    for (int i = startIdx; i < len; i += 2) {
        data[(i + 1) / 2] = (byte) ((Character.digit(input.charAt(i), 16) << 4)
                + Character.digit(input.charAt(i+1), 16));
    }
    return data;
}

2

Ho sempre usato un metodo simile

public static final byte[] fromHexString(final String s) {
    String[] v = s.split(" ");
    byte[] arr = new byte[v.length];
    int i = 0;
    for(String val: v) {
        arr[i++] =  Integer.decode("0x" + val).byteValue();

    }
    return arr;
}

questo metodo si divide su valori esadecimali delimitati da spazio, ma non sarebbe difficile dividerlo su qualsiasi altro criterio, ad esempio in raggruppamenti di due caratteri.


La concatenazione di stringhe non è necessaria. Basta usare Integer.valueOf (val, 16).
Michael Myers

Ho provato ad usare le conversioni di radix in quel modo e ho avuto risultati contrastanti
pfranza,

grazie - stranamente funziona bene con questa stringa: "9C001C" o "001C21" e fallisce con questo: "9C001C21" Eccezione nel thread "main" java.lang.NumberFormatException: per la stringa di input: "9C001C21" su java.lang. NumberFormatException.forInputString (sorgente sconosciuta)
rafraf,

(Non è più strano che nel caso Byte/ byte: bit più alto impostato senza inizio -)
greybeard

2

Mi piace la soluzione Character.digit, ma ecco come l'ho risolta

public byte[] hex2ByteArray( String hexString ) {
    String hexVal = "0123456789ABCDEF";
    byte[] out = new byte[hexString.length() / 2];

    int n = hexString.length();

    for( int i = 0; i < n; i += 2 ) {
        //make a bit representation in an int of the hex value 
        int hn = hexVal.indexOf( hexString.charAt( i ) );
        int ln = hexVal.indexOf( hexString.charAt( i + 1 ) );

        //now just shift the high order nibble and add them together
        out[i/2] = (byte)( ( hn << 4 ) | ln );
    }

    return out;
}

2

Il codice presentato da Bert Regelink semplicemente non funziona. Prova quanto segue:

import javax.xml.bind.DatatypeConverter;
import java.io.*;

public class Test
{  
    @Test
    public void testObjectStreams( ) throws IOException, ClassNotFoundException
    {     
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);

            String stringTest = "TEST";
            oos.writeObject( stringTest );

            oos.close();
            baos.close();

            byte[] bytes = baos.toByteArray();
            String hexString = DatatypeConverter.printHexBinary( bytes);
            byte[] reconvertedBytes = DatatypeConverter.parseHexBinary(hexString);

            assertArrayEquals( bytes, reconvertedBytes );

            ByteArrayInputStream bais = new ByteArrayInputStream(reconvertedBytes);
            ObjectInputStream ois = new ObjectInputStream(bais);

            String readString = (String) ois.readObject();

            assertEquals( stringTest, readString);
        }
    }

2
Questo è davvero un problema diverso e probabilmente appartiene a un altro thread.
Sean Coffey,

1

Ho trovato Kernel Panic la soluzione più utile per me, ma ho riscontrato problemi se la stringa esadecimale era un numero dispari. risolto in questo modo:

boolean isOdd(int value)
{
    return (value & 0x01) !=0;
}

private int hexToByte(byte[] out, int value)
{
    String hexVal = "0123456789ABCDEF"; 
    String hexValL = "0123456789abcdef";
    String st = Integer.toHexString(value);
    int len = st.length();
    if (isOdd(len))
        {
        len+=1; // need length to be an even number.
        st = ("0" + st);  // make it an even number of chars
        }
    out[0]=(byte)(len/2);
    for (int i =0;i<len;i+=2)
    {
        int hh = hexVal.indexOf(st.charAt(i));
            if (hh == -1)  hh = hexValL.indexOf(st.charAt(i));
        int lh = hexVal.indexOf(st.charAt(i+1));
            if (lh == -1)  lh = hexValL.indexOf(st.charAt(i+1));
        out[(i/2)+1] = (byte)((hh << 4)|lh);
    }
    return (len/2)+1;
}

Sto aggiungendo un numero di numeri esadecimali a un array, quindi passo il riferimento all'array che sto usando e l'int che ho bisogno di essere convertito e restituendo la posizione relativa del numero esadecimale successivo. Quindi l'array di byte finale ha [0] numero di coppie esadecimali, [1 ...] coppie esadecimali, quindi il numero di coppie ...


1

Sulla base della soluzione votata all'operazione, il seguente dovrebbe essere un po 'più efficiente:

  public static byte [] hexStringToByteArray (final String s) {
    if (s == null || (s.length () % 2) == 1)
      throw new IllegalArgumentException ();
    final char [] chars = s.toCharArray ();
    final int len = chars.length;
    final byte [] data = new byte [len / 2];
    for (int i = 0; i < len; i += 2) {
      data[i / 2] = (byte) ((Character.digit (chars[i], 16) << 4) + Character.digit (chars[i + 1], 16));
    }
    return data;
  }

Perché: la conversione iniziale in un array di caratteri risparmia i controlli di lunghezza in caratteri


1

Se hai una preferenza per i flussi Java 8 come stile di codifica, questo può essere ottenuto usando solo le primitive JDK.

String hex = "0001027f80fdfeff";

byte[] converted = IntStream.range(0, hex.length() / 2)
    .map(i -> Character.digit(hex.charAt(i * 2), 16) << 4 | Character.digit(hex.charAt((i * 2) + 1), 16))
    .collect(ByteArrayOutputStream::new,
             ByteArrayOutputStream::write,
             (s1, s2) -> s1.write(s2.toByteArray(), 0, s2.size()))
    .toByteArray();

I , 0, s2.size()parametri nella funzione di concatenazione del collector possono essere omessi se non ti dispiace catturare IOException.


0
public static byte[] hex2ba(String sHex) throws Hex2baException {
    if (1==sHex.length()%2) {
        throw(new Hex2baException("Hex string need even number of chars"));
    }

    byte[] ba = new byte[sHex.length()/2];
    for (int i=0;i<sHex.length()/2;i++) {
        ba[i] = (Integer.decode(
                "0x"+sHex.substring(i*2, (i+1)*2))).byteValue();
    }
    return ba;
}

0

La mia soluzione formale:

/**
 * Decodes a hexadecimally encoded binary string.
 * <p>
 * Note that this function does <em>NOT</em> convert a hexadecimal number to a
 * binary number.
 *
 * @param hex Hexadecimal representation of data.
 * @return The byte[] representation of the given data.
 * @throws NumberFormatException If the hexadecimal input string is of odd
 * length or invalid hexadecimal string.
 */
public static byte[] hex2bin(String hex) throws NumberFormatException {
    if (hex.length() % 2 > 0) {
        throw new NumberFormatException("Hexadecimal input string must have an even length.");
    }
    byte[] r = new byte[hex.length() / 2];
    for (int i = hex.length(); i > 0;) {
        r[i / 2 - 1] = (byte) (digit(hex.charAt(--i)) | (digit(hex.charAt(--i)) << 4));
    }
    return r;
}

private static int digit(char ch) {
    int r = Character.digit(ch, 16);
    if (r < 0) {
        throw new NumberFormatException("Invalid hexadecimal string: " + ch);
    }
    return r;
}

È come la funzione hex2bin () di PHP ma in stile Java.

Esempio:

String data = new String(hex2bin("6578616d706c65206865782064617461"));
// data value: "example hex data"

0

In ritardo alla festa, ma ho riunito la risposta di cui sopra DaveL in una classe con l'azione inversa - nel caso in cui sia di aiuto.

public final class HexString {
    private static final char[] digits = "0123456789ABCDEF".toCharArray();

    private HexString() {}

    public static final String fromBytes(final byte[] bytes) {
        final StringBuilder buf = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            buf.append(HexString.digits[(bytes[i] >> 4) & 0x0f]);
            buf.append(HexString.digits[bytes[i] & 0x0f]);
        }
        return buf.toString();
    }

    public static final byte[] toByteArray(final String hexString) {
        if ((hexString.length() % 2) != 0) {
            throw new IllegalArgumentException("Input string must contain an even number of characters");
        }
        final int len = hexString.length();
        final byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }
}

E classe di test JUnit:

public class TestHexString {

    @Test
    public void test() {
        String[] tests = {"0FA1056D73", "", "00", "0123456789ABCDEF", "FFFFFFFF"};

        for (int i = 0; i < tests.length; i++) {
            String in = tests[i];
            byte[] bytes = HexString.toByteArray(in);
            String out = HexString.fromBytes(bytes);
            System.out.println(in); //DEBUG
            System.out.println(out); //DEBUG
            Assert.assertEquals(in, out);

        }

    }

}

0

So che questo è un thread molto vecchio, ma mi piace ancora aggiungere il mio valore in penny.

Se ho davvero bisogno di codificare una semplice stringa esadecimale in convertitore binario, vorrei farlo come segue.

public static byte[] hexToBinary(String s){

  /*
   * skipped any input validation code
   */

  byte[] data = new byte[s.length()/2];

  for( int i=0, j=0; 
       i<s.length() && j<data.length; 
       i+=2, j++)
  {
     data[j] = (byte)Integer.parseInt(s.substring(i, i+2), 16);
  }

  return data;
}

0

Di gran lunga non la soluzione più pulita. Ma funziona per me ed è ben formattato:

private String createHexDump(byte[] msg, String description) {
    System.out.println();
    String result = "\n" + description;
    int currentIndex = 0;
    int printedIndex = 0;
    for(int i=0 ; i<msg.length ; i++){
        currentIndex++;
        if(i == 0){
            result += String.format("\n  %04x ", i);
        }
        if(i % 16 == 0 && i != 0){
            result += " | ";
            for(int j=(i-16) ; j<msg.length && j<i ; j++) {
                char characterToAdd = (char) msg[j];
                if (characterToAdd == '\n') {
                    characterToAdd = ' ';
                }
                result += characterToAdd;
                printedIndex++;
            }

            result += String.format("\n  %04x ", i);
        }

        result += String.format("%02x ", msg[i]);
    }

    if(currentIndex - printedIndex > 0){
        int leftOvers = currentIndex - printedIndex;
        for(int i=0 ; i<16-leftOvers ; i++){
            result += "   ";
        }

        result += " | ";

        for(int i=msg.length-leftOvers ; i<msg.length ; i++){
            char characterToAdd = (char) msg[i];
            if (characterToAdd == '\n') {
                characterToAdd = ' ';
            }
            result += characterToAdd;
        }
    }

    result += "\n";

    return result;
}

Il risultato:

  S -> C
    0000 0b 00 2e 06 4d 6f 72 69 74 7a 53 6f 6d 65 20 54  |  .Heyyy Some T
    0010 43 50 20 73 74 75 66 66 20 49 20 63 61 70 74 75  | CP stuff I captu
    0020 72 65 64 2e 2e 77 65 6c 6c 20 66 6f 72 6d 61 74  | red..well format
    0030 3f                                               | ?

-2

Penso che lo farà per te. L'ho messo insieme da una funzione simile che ha restituito i dati come una stringa:

private static byte[] decode(String encoded) {
    byte result[] = new byte[encoded/2];
    char enc[] = encoded.toUpperCase().toCharArray();
    StringBuffer curr;
    for (int i = 0; i < enc.length; i += 2) {
        curr = new StringBuffer("");
        curr.append(String.valueOf(enc[i]));
        curr.append(String.valueOf(enc[i + 1]));
        result[i] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
}

Innanzitutto, non è necessario convertire la stringa in maiuscolo. In secondo luogo, è possibile aggiungere caratteri direttamente a StringBuffer, che dovrebbe essere molto più efficiente.
Michael Myers

-2

Per me questa era la soluzione, HEX = "FF01" quindi divisa in FF (255) e 01 (01)

private static byte[] BytesEncode(String encoded) {
    //System.out.println(encoded.length());
    byte result[] = new byte[encoded.length() / 2];
    char enc[] = encoded.toUpperCase().toCharArray();
    String curr = "";
    for (int i = 0; i < encoded.length(); i=i+2) {
        curr = encoded.substring(i,i+2);
        System.out.println(curr);
        if(i==0){
            result[i]=((byte) Integer.parseInt(curr, 16));
        }else{
            result[i/2]=((byte) Integer.parseInt(curr, 16));
        }

    }
    return result;
}

Questa domanda ha avuto una risposta per un po 'e ha diverse buone alternative in atto; purtroppo, la tua risposta non fornisce alcun valore significativamente migliorato a questo punto.
rfornal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.