[java] Java를 사용하여 16 진 덤프의 문자열 표시를 바이트 배열로 변환 하시겠습니까?
16 진수 값을 바이트 배열로 나타내는 긴 문자열 (덤프에서)을 변환하는 방법을 찾고 있습니다.
나는 같은 질문을 여기에 올린 사람보다 더 잘 표현할 수 없었 습니다 .
그러나 그것을 독창적으로 유지하기 위해, 나는 그것을 내 자신의 방식으로 표현할 "00A0BF"
것입니다.
byte[] {0x00,0xA0,0xBf}
어떻게해야합니까?
나는 Java 초보자이며 BigInteger
16 진수 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;
}
그것은 내가 입력 한 예제 일뿐입니다 … 실제로 그대로 사용하므로 별도의 방법을 사용할 필요가 없습니다.