[java] Java를 사용하여 16 진 덤프의 문자열 표시를 바이트 배열로 변환 하시겠습니까?

16 진수 값을 바이트 배열로 나타내는 긴 문자열 (덤프에서)을 변환하는 방법을 찾고 있습니다.

나는 같은 질문을 여기에 올린 사람보다 더 잘 표현할 수 없었 습니다 .

그러나 그것을 독창적으로 유지하기 위해, 나는 그것을 내 자신의 방식으로 표현할 "00A0BF"것입니다.

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

어떻게해야합니까?

나는 Java 초보자이며 BigInteger16 진수 0을 사용 하고 감시했습니다. 그러나 나는 그것이 추악하다고 생각하고 간단한 것을 놓치고 있다고 확신합니다.



답변

여기에 지금까지 게시 된 것보다 낫다고 생각하는 솔루션이 있습니다.

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

그것이 개선 이유 :

  • 선행 0 (BigInteger와 달리)과 음의 바이트 값 (Byte.parseByte와는 다름)으로 안전합니다.

  • String을로 변환하지 않거나 char[]모든 단일 바이트에 대해 StringBuilder 및 String 객체를 만듭니다.

  • 사용 불가능한 라이브러리 종속성이 없습니다.

assert인수가 안전한 것으로 알려진 경우 인수 검사를 통해 또는 예외 를 추가하십시오 .


답변

원 라이너 :

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 루트 세트의 일부가 아니므로 –add-modules java.se.ee를 지정하지 않으면 ClassNotFoundException이 발생합니다 (@ 덕분에 eckes)
  • 안드로이드에서는 사용할 수 Fabian없지만 (그렇기 때문에) 시스템 에 어떤 이유로 부족한 경우 소스 코드를 가져올 수 있습니다 javax.xml. Bert Regelink소스를 추출한 @ 에게 감사합니다 .

답변

commons-codec의 Hex 클래스가 그렇게해야합니다.

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

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


답변

이제 BaseEncoding 을 사용 guava하여이를 수행 할 수 있습니다 .

BaseEncoding.base16().decode(string);

그것을 반대로 사용하려면

BaseEncoding.base16().encode(bytes);


답변

실제로 BigInteger가 솔루션이라고 생각합니다.

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

편집 : 포스터에서 언급했듯이 선행 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);
}

뒤에서 실제 코드에 관심이있는 당신의 그것들을 위해 한 – 라이너 에서 FractalizeR 이 출처 (나는 javax.xml.bind의 기본적으로 안드로이드 ()를 사용할 수 없습니다 때문에 것을 필요) 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();
}


답변

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

그것은 내가 입력 한 예제 일뿐입니다 … 실제로 그대로 사용하므로 별도의 방법을 사용할 필요가 없습니다.