Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java将十六进制转储的字符串表示形式转换为字节数组?_Java_Byte_Hex_Dump - Fatal编程技术网

使用Java将十六进制转储的字符串表示形式转换为字节数组?

使用Java将十六进制转储的字符串表示形式转换为字节数组?,java,byte,hex,dump,Java,Byte,Hex,Dump,我正在寻找一种将表示十六进制值的长字符串(从转储)转换为字节数组的方法 我的措辞再好不过了 但是为了保持它的原始性,我将用我自己的方式来表达它:假设我有一个字符串“00A0BF”,我希望它被解释为 byte[] {0x00,0xA0,0xBf} 我该怎么办 我是一名Java新手,最终使用了biginger,并注意前导的十六进制零。但我认为这是丑陋的,我相信我错过了一些简单的东西 commons编解码器中的Hex类应该可以为您做到这一点 我一直使用这样的方法 public static fin

我正在寻找一种将表示十六进制值的长字符串(从转储)转换为字节数组的方法

我的措辞再好不过了

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

byte[] {0x00,0xA0,0xBf}
我该怎么办


我是一名Java新手,最终使用了
biginger
,并注意前导的十六进制零。但我认为这是丑陋的,我相信我错过了一些简单的东西

commons编解码器中的Hex类应该可以为您做到这一点


我一直使用这样的方法

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

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

我想我会帮你的。我从一个类似的函数拼凑而成,该函数以字符串形式返回数据:

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;
}
私有静态字节[]解码(字符串编码){
字节结果[]=新字节[编码/2];
char enc[]=encoded.toUpperCase().toCharArray();
字符串缓冲货币;
对于(int i=0;i
编辑:正如@mmyers所指出的,这种方法不适用于包含对应于高位字节集(“80”-“FF”)的子字符串的输入。解释在下面

公共静态最终字节[]fromHexString(最终字符串s){
字节[]arr=新字节[s.length()/2];
对于(int start=0;start
以下是一个实际可行的方法(基于前面几个半正确的答案):

私有静态字节[]fromHexString(最终字符串编码){
如果((encoded.length()%2)!=0)
抛出新的IllegalArgumentException(“输入字符串必须包含偶数个字符”);
最终字节结果[]=新字节[encoded.length()/2];
final char enc[]=encoded.toCharArray();
对于(int i=0;i
我能看到的唯一可能的问题是输入字符串是否非常长;调用toCharArray()生成字符串内部数组的副本


编辑:噢,顺便说一句,字节是用Java签名的,所以您的输入字符串将转换为[0,-96,-65],而不是[0,160,191]。但是你可能已经知道了。

事实上,我认为BigInteger是一个非常好的解决方案:

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

编辑:如海报所述,前导零不安全。

我认为这是一个比目前发布的任何解决方案都好的解决方案:

/* 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;
}
/*s必须是偶数长度的字符串*/
公共静态字节[]hexStringToByteArray(字符串s){
int len=s.length();
字节[]数据=新字节[len/2];
对于(int i=0;ibiginger()
方法非常慢,不推荐使用

Integer.parseInt(十六进制字符串,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;
}
公共静态字节[]HexStringToByteArray(字符串s){
字节数据[]=新字节[s.length()/2];
对于(int i=0;i
祝你玩得开心,好运

公共静态字节[]hex2ba(字符串sHex)抛出Hex2baException{
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;
}
如果(1==sHex.length()%2){ 抛出(新的Hex2baException(“十六进制字符串需要偶数个字符”); } byte[]ba=新字节[sHex.length()/2];
对于(inti=0;i我喜欢Character.digit的解决方案,但下面是我如何解决它的

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;
}
public byte[]hex2ByteArray(字符串hexString){
字符串hexVal=“0123456789ABCDEF”;
byte[]out=新字节[hexString.length()/2];
int n=hexString.length();
对于(int i=0;iout[i/2]=(byte)((hnHexBinaryAdapter
提供了在
字符串
字节[]之间封送和解封的功能

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

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

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

一行代码:

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);
}
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);
}
String data = new String(hex2bin("6578616d706c65206865782064617461"));
// data value: "example hex data"
警告

  • 在Java9Jigsaw中,这不再是(默认)Java.se根目录的一部分 设置为它将导致ClassNotFoundException,除非您指定 --添加模块java.se.ee(感谢@code>eckes
  • Android上不可用(感谢Fabian
  • 注意到这一点),但如果您的系统由于某种原因缺少
    javax.xml
    ,您就可以使用。感谢@code>Bert Regelink
    提取源代码
    我发现Kernel Panic有一个对我最有用的解决方案,但是如果十六进制字符串是奇数,就会遇到问题。解决方法如下:

    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;
    }
    
    布尔isOdd(int值)
    {
    返回值(值&0x01)!=0;
    }
    专用整数十六进制字节(字节[]输出,整数值)
    {
    字符串hexVal=“0123456789ABCDEF”;
    字符串hexValL=“0123456789abcdef”;
    字符串st=整数。toHexString(值);
    int len=标准长度();
    if(isOdd(len))
    {
    
    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;
    }
    
    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);
    }
    
    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();
    }
    
    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);
            }
        }
    
    BaseEncoding.base16().decode(string);
    
    BaseEncoding.base16().encode(bytes);
    
      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;
      }
    
    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;
    }
    
    byte[] bytes = ByteString.decodeHex("c000060000").toByteArray();
    
    [-64, 0, 6, 0, 0]
    
    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;
    }
    
    /**
     * 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;
    }
    
    String data = new String(hex2bin("6578616d706c65206865782064617461"));
    // data value: "example hex data"
    
    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();
    
    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;
        }
    }
    
    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);
    
            }
    
        }
    
    }
    
    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;
    }