我正在寻找一种方法来转换一个长字符串(从转储),它表示十六进制值到字节数组。
我不可能比在这里发布同样问题的人表达得更好。
但是为了保持它的原创性,我将以自己的方式表达它:假设我有一个字符串“00A0BF”,我希望将其解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是一个Java新手,最后使用BigInteger并注意前导十六进制零。但我认为它很丑,我肯定我错过了一些简单的东西。
我正在寻找一种方法来转换一个长字符串(从转储),它表示十六进制值到字节数组。
我不可能比在这里发布同样问题的人表达得更好。
但是为了保持它的原创性,我将以自己的方式表达它:假设我有一个字符串“00A0BF”,我希望将其解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是一个Java新手,最后使用BigInteger并注意前导十六进制零。但我认为它很丑,我肯定我错过了一些简单的东西。
当前回答
我的正式解决方案:
/**
* 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;
}
类似于PHP的hex2bin()函数,但采用Java风格。
例子:
String data = new String(hex2bin("6578616d706c65206865782064617461"));
// data value: "example hex data"
其他回答
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;
}
玩得开心,好运
编辑:正如@mmyers所指出的那样,此方法不适用于包含与高位设置的字节对应的子字符串的输入("80" - "FF")。解释在Bug ID: 6259307字节。parseByte没有像SDK文档中宣传的那样工作。
public static final byte[] fromHexString(final String s) {
byte[] arr = new byte[s.length()/2];
for ( int start = 0; start < s.length(); start += 2 )
{
String thisByte = s.substring(start, start+2);
arr[start/2] = Byte.parseByte(thisByte, 16);
}
return arr;
}
对我来说,这是解决方案,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;
}
一行程序: 进口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();
}
一行程序:
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提取源代码。