我正在寻找一种方法来转换一个长字符串(从转储),它表示十六进制值到字节数组。
我不可能比在这里发布同样问题的人表达得更好。
但是为了保持它的原创性,我将以自己的方式表达它:假设我有一个字符串“00A0BF”,我希望将其解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是一个Java新手,最后使用BigInteger并注意前导十六进制零。但我认为它很丑,我肯定我错过了一些简单的东西。
我正在寻找一种方法来转换一个长字符串(从转储),它表示十六进制值到字节数组。
我不可能比在这里发布同样问题的人表达得更好。
但是为了保持它的原创性,我将以自己的方式表达它:假设我有一个字符串“00A0BF”,我希望将其解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是一个Java新手,最后使用BigInteger并注意前导十六进制零。但我认为它很丑,我肯定我错过了一些简单的东西。
当前回答
我想我会帮你的。我用一个类似的函数把它拼凑在一起,该函数以字符串形式返回数据:
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;
}
其他回答
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;
}
这只是我输入的一个例子……实际上,我只是按原样使用它,不需要为使用它创建一个单独的方法。
迟到了,但我已经把DaveL上面的答案合并到一个具有反向操作的类中——以防它有所帮助。
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;
}
}
和JUnit测试类:
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);
}
}
}
Bert Regelink提出的准则根本不起作用。 试试下面的方法:
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);
}
}
我一直用的方法是
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;
}
此方法根据空格分隔的十六进制值进行分割,但根据任何其他条件(例如分成两个字符的组)将字符串分割并不困难。
这里有另一个版本,它支持奇数长度的字符串,而不诉诸字符串连接。
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;
}