我正在寻找一种方法来转换一个长字符串(从转储),它表示十六进制值到字节数组。

我不可能比在这里发布同样问题的人表达得更好。

但是为了保持它的原创性,我将以自己的方式表达它:假设我有一个字符串“00A0BF”,我希望将其解释为

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

我该怎么办?

我是一个Java新手,最后使用BigInteger并注意前导十六进制零。但我认为它很丑,我肯定我错过了一些简单的东西。


当前回答

我一直用的方法是

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

此方法根据空格分隔的十六进制值进行分割,但根据任何其他条件(例如分成两个字符的组)将字符串分割并不困难。

其他回答

java中的BigInteger()方法。数学很慢,不值得推荐。

整数。parseInt (HEXString, 16)

可以导致问题与某些字符没有 转换为数字/整数

良好的工作方法:

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

功能:

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

玩得开心,好运

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

HexBinaryAdapter提供了在String和byte[]之间编组和反编组的能力。

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

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

这只是我输入的一个例子……实际上,我只是按原样使用它,不需要为使用它创建一个单独的方法。

Bert Regelink提出的准则根本不起作用。 试试下面的方法:

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

更新(2021年)- Java 17现在包括Java .util. hexformat(只花了25年):

HexFormat.of().parseHex(s)


For older versions of Java:

这里有一个解决方案,我认为比目前为止发布的任何解决方案都要好:

/* s must be an even-length string. */
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;
}

这是一种进步的原因:

前导零(与BigInteger不同)和负字节值(与byte . parsebyte不同)是安全的 不将String转换为char[],也不为每个字节创建StringBuilder和String对象。 没有可能不可用的库依赖项

如果不知道参数是否安全,可以通过assert或异常添加参数检查。