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

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

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

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

我该怎么办?

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


当前回答

一行程序:

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

警告:

在Java 9 Jigsaw中,这不再是(默认)Java的一部分。se根 设置,否则将导致ClassNotFoundException,除非您指定 ——添加模块java.se.ee(感谢@eckes) Android上不支持(感谢Fabian注意到这一点),但如果您的系统由于某种原因缺少javax.xml,您可以只使用源代码。感谢@Bert Regelink提取源代码。

其他回答

一行程序: 进口javax.xml.bind.DatatypeConverter; (字节[]数组) 返回DatatypeConverter.printHexBinary(数组); } public static byte[] toByteArray(String s) { 返回DatatypeConverter.parseHexBinary (s); }

对于那些对来自FractalizeR的一行代码背后的实际代码感兴趣的人(我需要它,因为javax.xml.bind不适用于Android(默认情况下)),这来自com.sun.xml.internal.bind. datatypeconverterimpll .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();
}

对我来说,这是解决方案,HEX="FF01"然后分裂到FF(255)和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;
}

在android中,如果你正在使用hex,你可以尝试okio。

简单的用法:

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

结果是

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

一行程序:

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

警告:

在Java 9 Jigsaw中,这不再是(默认)Java的一部分。se根 设置,否则将导致ClassNotFoundException,除非您指定 ——添加模块java.se.ee(感谢@eckes) Android上不支持(感谢Fabian注意到这一点),但如果您的系统由于某种原因缺少javax.xml,您可以只使用源代码。感谢@Bert Regelink提取源代码。

我喜欢这个角色。数位解,我是这样解的

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