¿Convertir una representación de cadena de un volcado hexadecimal en una matriz de bytes usando Java?

373

Estoy buscando una manera de convertir una cadena larga (de un volcado), que represente valores hexadecimales en una matriz de bytes.

No podría haberlo redactado mejor que la persona que publicó la misma pregunta aquí .

Pero para mantenerlo original, lo expresaré a mi manera: supongamos que tengo una cadena "00A0BF"que me gustaría interpretar como

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

¿Qué tengo que hacer?

Soy un novato en Java y terminé usando BigIntegery vigilando los ceros hexadecimales principales. Pero creo que es feo y estoy seguro de que me falta algo simple.

rafraf
fuente
Consulte también stackoverflow.com/questions/9655181/… .
flow2k el
He domesticado BigInteger aquí .
John McClane
FWIW String.getBytes()no funcionará como crees que podría funcionar. Tuve que aprender esto de la manera difícil. if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
tir38

Respuestas:

637

Aquí hay una solución que creo que es mejor que cualquiera publicada hasta ahora:

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

Razones por las que es una mejora:

  • Seguro con ceros a la izquierda (a diferencia de BigInteger) y con valores de bytes negativos (a diferencia de Byte.parseByte)

  • No convierte la cadena en a char[], ni crea objetos StringBuilder y String para cada byte.

  • No dependencias de la biblioteca que pueden no estar disponibles

Siéntase libre de agregar comprobación de argumentos mediante asserto excepciones si no se sabe que el argumento es seguro.

Dave L.
fuente
2
¿Puedes dar un ejemplo que esté decodificado incorrectamente o explicar cómo está mal?
Dave L.
55
No funciona para la cadena "0".
Lanza
49
"0" no es una entrada válida. Los bytes requieren dos dígitos hexadecimales cada uno. Como señala la respuesta, "siéntase libre de agregar comprobación de argumentos ... si no se sabe que el argumento es seguro".
Dave L.
12
javax.xml.bind.DatatypeConverter.parseHexBinary (hexString) parece ser aproximadamente un 20% más rápido que la solución anterior en mis micro pruebas (por lo poco que valen), así como lanzar correctamente excepciones en entradas no válidas (por ejemplo, "gg" no es un hexString válido pero devolverá -77 usando la solución propuesta).
Trevor Freeman
66
@DaedalusAlpha Depende de su contexto, pero por lo general creo que es mejor fallar rápido y fuerte con esas cosas para que pueda corregir sus suposiciones en lugar de devolver silenciosamente datos incorrectos.
Dave L.
331

One-liners:

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

Advertencias :

  • en Java 9 Jigsaw esto ya no es parte del conjunto raíz (predeterminado) java.se, por lo que dará como resultado una excepción ClassNotFoundException a menos que especifique --add-modules java.se.ee (gracias a @ eckes)
  • No está disponible en Android (gracias a Fabianeso), pero puede tomar el código fuente si su sistema carece javax.xmlpor alguna razón. Gracias a @ Bert Regelinkpor extraer la fuente.
Vladislav Rastrusny
fuente
14
En mi humilde opinión, esta debería ser la respuesta aceptada / superior ya que es corta y limpia (a diferencia de la respuesta de @ DaveL) y no requiere ninguna biblioteca externa (como la respuesta de skaffman). Además, <Escribe una broma gastada sobre reinventar la bicicleta> .
Priidu Neemre
99
la clase datatypeconverter no está disponible en Android, por ejemplo.
Fabian
44
Advertencia: en Java 9 Jigsaw esto ya no es parte del java.seconjunto raíz (predeterminado) , por lo que resultará en un ClassNotFoundExceptionmensaje a menos que especifique--add-modules java.se.ee
eckes el
2
@dantebarba Creo que javax.xml.bind.DatatypeConverterya proporciona un método para codificar / decodificar datos Base64. Ver parseBase64Binary()y printBase64Binary().
DragShot
2
Para agregar a los problemas DataTypeConverter, Java SE 11 ha eliminado por completo la API JAXB y ahora solo se incluye con Java EE. También puede agregarlo como una dependencia de Maven, como se sugiere aquí: stackoverflow.com/a/43574427/7347751
David Mordigal
79

La clase Hex en commons-codec debería hacerlo por usted.

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

import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF
skaffman
fuente
66
Esto también se ve bien. Ver org.apache.commons.codec.binary.Hex.decodeHex ()
Dave L.
Fue interesante Pero encontré su solución difícil de seguir. ¿Tiene alguna ventaja sobre lo que propuso (aparte de verificar un número par de caracteres)?
rafraf
38

Ahora puede utilizar BaseEncoding en guavalograr esto.

BaseEncoding.base16().decode(string);

Para revertirlo use

BaseEncoding.base16().encode(bytes);
jontro
fuente
27

En realidad, creo que la solución de BigInteger es muy buena:

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

Editar: No es seguro para los ceros a la izquierda , como lo señala el afiche.

Dave L.
fuente
También pensé eso inicialmente. Y gracias por documentarlo, solo pensaba que debería ... hizo algunas cosas extrañas que realmente no entendí, como omitir algunos 0x00 iniciales y también mezclar el orden de 1 byte en una cadena de 156 bytes I estaba jugando con
rafraf
2
Ese es un buen punto sobre liderar los ceros. No estoy seguro de creer que podría mezclar el orden de los bytes, y estaría muy interesado en verlo demostrado.
Dave L.
1
sí, tan pronto como lo dije, tampoco me creí :) Ejecuté una comparación de la matriz de bytes de BigInteger con mmyers'fromHexString y (sin 0x00) contra la cadena ofensiva: eran idénticos. La "confusión" sucedió, pero puede haber sido otra cosa. Mañana miraré más de cerca
rafraf
3
El problema con BigInteger es que debe haber un "bit de signo". Si el byte inicial tiene el bit alto establecido, entonces la matriz de bytes resultante tiene un 0 adicional en la primera posición. Pero aún así +1.
Gris
25

One-liners:

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

Para aquellos de ustedes interesados ​​en el código real detrás de One-liners de FractalizeR (necesitaba eso ya que javax.xml.bind no está disponible para Android (por defecto)), esto viene de 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();
}
Bert Regelink
fuente
3
DatatypeConverter tampoco está disponible en Java 9 de forma predeterminada. Lo peligroso es que el código que lo usa se compilará en Java 1.8 o anterior (Java 9 con configuración de origen a anterior), pero obtendrá una excepción de tiempo de ejecución en Java 9 sin "--add-modules java.se.ee".
Stephen M -en huelga-
24

El HexBinaryAdapterproporciona la capacidad de reunir y desmarcar entre Stringy byte[].

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

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

Ese es solo un ejemplo que escribí ... En realidad solo lo uso como está y no necesito hacer un método separado para usarlo.

GrkIngeniero
fuente
55
Solo funciona si la cadena de entrada (hexString) tiene un número par de caracteres. De lo contrario: Excepción en el hilo "main" java.lang.IllegalArgumentException: hexBinary debe ser de longitud par:
ovdsrn
3
Oh, gracias por señalar eso. Un usuario realmente no debería tener un número impar de caracteres porque la matriz de bytes se representa como {0x00,0xA0,0xBf}. Cada byte tiene dos dígitos hexadecimales o mordiscos. Por lo tanto, cualquier número de bytes siempre debe tener un número par de caracteres. Gracias por mencionar esto.
GrkEngineer
8
Puede usar java.xml.bind.DatatypeConverter.parseHexBinary (hexString) directamente en lugar de usar HexBinaryAdapter (que a su vez llama a DatatypeConverter). De esta manera, no tiene que crear un objeto de instancia de adaptador (ya que los métodos DatatypeConverter son estáticos).
Trevor Freeman
javax.xml.bind. * ya no está disponible en Java 9. Lo peligroso es que el código que lo usa se compilará en Java 1.8 o anterior (Java 9 con la configuración de origen a anterior), pero obtendrá una excepción de tiempo de ejecución en Java 9.
Stephen M -en huelga-
15

Aquí hay un método que realmente funciona (basado en varias respuestas semicorrectas anteriores):

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

El único problema posible que puedo ver es si la cadena de entrada es extremadamente larga; llamar a toCharArray () hace una copia de la matriz interna de la cadena.

EDITAR: Ah, y por cierto, los bytes están firmados en Java, por lo que su cadena de entrada se convierte a [0, -96, -65] en lugar de [0, 160, 191]. Pero probablemente ya lo sabías.

Michael Myers
fuente
1
Gracias Michael, ¡eres un salvavidas! Trabajando en un proyecto BlackBerry e intentando convertir una representación de cadena de un byte en el byte ... utilizando el método "Byte.parseByte (byteString, 16)" de RIM. Seguí lanzando un NumberFormatExcpetion. Pasé horas intentando averiguar por qué. Su sugerencia de "Integer.praseInt ()" hizo el truco. ¡¡Gracias de nuevo!!
BonanzaDriver
12

En Android, si está trabajando con hexadecimal, puede probar okio .

uso simple:

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

y el resultado será

[-64, 0, 6, 0, 0]
Miao1007
fuente
He probado muchos métodos diferentes, ¡pero este es al menos el doble de rápido!
Poby
5

El BigInteger()método de java.math es muy lento y no es recomendable.

Integer.parseInt(HEXString, 16)

puede causar problemas con algunos caracteres sin convertir a Digit / Integer

Un buen método de trabajo:

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

Función:

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

Diviértete, buena suerte

Francotirador
fuente
4

EDITAR: como señaló @mmyers, este método no funciona en la entrada que contiene subcadenas correspondientes a bytes con el conjunto de bits alto ("80" - "FF"). La explicación está en ID de error: 6259307 Byte.parseByte no funciona como se anuncia en la documentación del 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;
}
Blair Conrad
fuente
1
Cerrar, pero este método falla en la entrada dada "00A0BBF". Ver bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 .
Michael Myers
1
También extrañamente no trata con "9C"
rafraf
1
@mmyers: whoa. Eso no es bueno. Perdón por la confusión. @ravigad: 9C tiene el mismo problema porque en este caso se establece el bit alto.
Blair Conrad
(byte) Short.parseShort (thisByte, 16) resuelve ese problema
Jamey Hicks
3

Para lo que vale, aquí hay otra versión que admite cadenas de longitud impar, sin recurrir a la concatenación de cadenas.

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;
}
Conor Svensson
fuente
2

Siempre he usado un método como

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

Este método se divide en valores hexadecimales delimitados por espacios, pero no sería difícil dividir la cadena en ningún otro criterio, como en grupos de dos caracteres.

pfranza
fuente
La concatenación de cadenas es innecesaria. Simplemente use Integer.valueOf (val, 16).
Michael Myers
He intentado usar las conversiones de radix así antes y he tenido resultados mixtos
pfranza
gracias - extrañamente funciona bien con esta cadena: "9C001C" o "001C21" y falla con esta: "9C001C21" Excepción en el hilo "main" java.lang.NumberFormatException: Para la cadena de entrada: "9C001C21" en java.lang. NumberFormatException.forInputString (Fuente desconocida)
rafraf
(Eso no es más extraño que en el caso Byte/ byte: bit más alto establecido sin guía -)
greybeard
2

Me gusta la solución Character.digit, pero así es como la resolví

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;
}
Panico kernel
fuente
2

El Código presentado por Bert Regelink simplemente no funciona. Intenta lo siguiente:

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);
        }
    }
Sean Coffey
fuente
2
Este es un problema diferente realmente, y probablemente pertenece a otro hilo.
Sean Coffey
1

Encontré que Kernel Panic tenía la solución más útil para mí, pero tuve problemas si la cadena hexadecimal era un número impar. lo resolvió de esta manera:

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

Estoy agregando un número de números hexadecimales a una matriz, por lo que paso la referencia a la matriz que estoy usando, y el int que necesito convertido y devolviendo la posición relativa del siguiente número hexadecimal. Entonces, la matriz de bytes final tiene [0] número de pares hexadecimales, [1] pares hexadecimales, luego el número de pares ...

Clayton Balabanov
fuente
1

Basado en la solución votada, lo siguiente debería ser un poco más eficiente:

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

Porque: la conversión inicial a una matriz de caracteres ahorra las verificaciones de longitud en charAt

Philip Helger
fuente
1

Si tiene preferencia por las secuencias Java 8 como su estilo de codificación, esto se puede lograr utilizando solo primitivas 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();

Los , 0, s2.size()parámetros en la función de concatenación de colector se pueden omitir si no le importa atrapar IOException.

Andy Brown
fuente
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;
}
David V
fuente
0

Mi solución formal:

/**
 * 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;
}

Es como la función PHP hex2bin () pero en estilo Java.

Ejemplo:

String data = new String(hex2bin("6578616d706c65206865782064617461"));
// data value: "example hex data"
Daniel De León
fuente
0

Tarde a la fiesta, pero he amalgamado la respuesta anterior de DaveL en una clase con la acción inversa, por si acaso ayuda.

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

Y clase de prueba 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);

        }

    }

}
DrPhill
fuente
0

Sé que este es un hilo muy antiguo, pero todavía me gusta agregar el valor de mi centavo.

Si realmente necesito codificar un convertidor de cadena hexadecimal simple a binario, me gustaría hacerlo de la siguiente manera.

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;
}
tigger
fuente
0

De lejos, no es la solución más limpia. Pero funciona para mí y está bien formateado:

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

La salida:

  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                                               | ?
Moritz Schmidt
fuente
-2

Creo que lo hará por ti. Lo combiné a partir de una función similar que devolvió los datos como una cadena:

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;
}
Bob King
fuente
Primero, no debería necesitar convertir la cadena a mayúsculas. En segundo lugar, es posible agregar caracteres directamente a un StringBuffer, lo que debería ser mucho más eficiente.
Michael Myers
-2

Para mí, esta fue la solución, HEX = "FF01" y luego dividido en FF (255) y 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;
}
Alejandro
fuente
Esta pregunta ha sido respondida por un tiempo y tiene varias buenas alternativas en su lugar; desafortunadamente, su respuesta no proporciona ningún valor significativamente mejorado en este momento.
rfornal