Java 如何将字符串(表示十六进制值)转换为字节?

Java 如何将字符串(表示十六进制值)转换为字节?,java,string,hex,byte,Java,String,Hex,Byte,我在Java中有一个包含32个字符的字符串: String tempHash = "123456789ABCDEF123456789ABCDEF12"; 上面字符串中的每个字符表示一个十六进制值。我需要将其转换为另一个字符串,其中包含由上述字符串中的每个十六进制计算出的8个字节。因此,在上面的示例中,输出字符串为: "00000001 00000010 00000011 000001000 000001001 000001011 ..." 我该怎么做 我试着做: byte[] bytes1

我在
Java
中有一个包含32个字符的字符串:

String tempHash = "123456789ABCDEF123456789ABCDEF12"; 
上面字符串中的每个字符表示一个十六进制值。我需要将其转换为另一个字符串,其中包含由上述字符串中的每个十六进制计算出的8个字节。因此,在上面的示例中,输出字符串为:

"00000001 00000010 00000011 000001000 000001001 000001011 ..."
我该怎么做

我试着做:

byte[] bytes1 = toByteArray(tempHash);
在哪里

public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
}
但是当我迭代这个数组时:

for (byte singleByte: bytes1) {
    System.out.println(singleByte);
}
对于第一个字符,我得到的是
18
,而不是
00000001
。 我在这里有点迷路了。你能帮我一下吗?

公共字节hexToByte(字符串hextString){
public byte hexToByte(String hexString) {
    int firstDigit = toDigit(hexString.charAt(0));
    int secondDigit = toDigit(hexString.charAt(1));
    return (byte) ((firstDigit << 4) + secondDigit);
}

private int toDigit(char hexChar) {
    int digit = Character.digit(hexChar, 16);
    if(digit == -1) {
        throw new IllegalArgumentException(
          "Invalid Hexadecimal Character: "+ hexChar);
    }
    return digit;
}
int firstDigit=toDigit(hexString.charAt(0)); int secondDigit=toDigit(hexString.charAt(1));
返回(字节)((第一位数字您可以使用
Long.parseLong(字符串,16);

一旦有了
long
值,就可以通过执行

long val = ...;
ByteBuffer buf = new ByteBuffer();
buf.put(0, val);

如果字符串太长,则需要使用BigInteger。这基本上是一样的,但更复杂一点

一种解决方案是使用

String tempHash = "123456789ABCDEF123456789ABCDEF12";

String binary = tempHash.chars()              // Get stream of chars
    .map(c -> Character.digit(c, 16))         // Convert to hex digit
    .mapToObj(Integer::toBinaryString)        // Convert to binary
    .map(s -> "0".repeat(8 - s.length()) + s) // Pad left with zeros
    .collect(Collectors.joining(" "));        // Collect to String

System.out.println(binary);
输出:

00000001 00000010 00000011 00000100 00000101 ...

正如下文所指出的,Java 11之前的解决方案是替换对以下内容的调用:


Op要求将十六进制转换为字节值,但不要求将其转换为十六进制值。谢谢,它看起来干净而流畅,有一个问题-似乎我没有重复功能…没有重复功能,还有其他方法吗?@randomuser1
String#repeat
是在Java 11中添加的。我将修改我的答案以添加Java 11之前的解决方案。
new字符串(新字符[8-s.length()])。替换('\0',0')
是我在Java 11之前使用的。顺便说一句,答案不错,@JacobG。我正要自己写一个答案,但你的答案比我准备的非流式答案要好。@KevinCruijssen正要在我的答案中写下这一点;谢谢!非常感谢,它不仅有效,而且看起来很干净!内置方法根据2个字符(请参阅我提供的链接第358行的
parseHexBinary
方法循环中的
i+=2
)。这同样适用于大多数Java内置函数,如
new Java.math.biginger(str,16).toByteArray()
。我正要写一个建议对每个字符进行手动转换的答案,但是@JacobG已经提供了一个非常好的(Java 11+)流式回答。这不会像他的输出示例所示,将每个数字分成8位的部分。@VinceEmigh我回答的问题如标题所示。无论如何,这就像Integer.toBinaryString(val)一样简单
String binary = tempHash.chars()              // Get stream of chars
    .map(c -> Character.digit(c, 16))         // Convert to hex digit
    .mapToObj(Integer::toBinaryString)        // Convert to binary
    .map(s -> new String(new char[8 - s.length()]).replace('\0', '0') + s) // Pad left with zeros
    .collect(Collectors.joining(" "));        // Collect to String