【问题标题】:In Java, how do I convert a hex string to a byte[]? [duplicate]在 Java 中,如何将十六进制字符串转换为字节 []? [复制]
【发布时间】:2012-02-11 23:51:35
【问题描述】:

我在 Java 中使用以下函数将加密的字符串转换为十六进制格式:

public static String toHex(byte [] buf) {
    StringBuffer strbuf = new StringBuffer(buf.length * 2);
    int i;
    for (i = 0; i < buf.length; i++) {
        if (((int) buf[i] & 0xff) < 0x10) {
            strbuf.append("0");
        }
        strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
    }
    return strbuf.toString();
}

现在我想将该十六进制字符串转换回字节数组。我该怎么做?

例如,

(1) Plain Text = 123
(2) Encrypted Text = «h>kq*«¬Mí“~èåZ  \}?
(3) Encrypted Text in Hex = f263575e7b00a977a8e9a37e08b9c215feb9bfb2f992b2b8f11e

我可以从(2) 转到(3),但我如何从(3) 转到(2)

【问题讨论】:

标签: java hex


【解决方案1】:
 String s="f263575e7b00a977a8e9a37e08b9c215feb9bfb2f992b2b8f11e";
 byte[] b = new BigInteger(s,16).toByteArray();

【讨论】:

  • 这并没有给我想要的结果,但是 dARKpRINCE 响应中的简单单线方法可以。
  • cs.setBytes(1,new BigInteger(regReportId,16).toByteArray()); 这在我必须将 RAW 数据类型传递给 Oracle sproc 时起作用
  • new BigInteger(s,16).toByteArray(); 不正确。我输入一个 34 长度的十六进制字符串,并输出一个 18 长度的字节。我想要的是一个 17 长度的字节
  • 我认为这有时会给出错误的结果。例如,它为 A85565ED63B893F5A3EF85D88819D484 提供 17 个字节。但应该是 16 个字节
  • 这给出了错误的结果; DarkPrince“实用方法”对我来说可以正常工作。
【解决方案2】:

接受的答案不考虑可能导致问题的前导零

This question 回答它。取决于您是想看看它是如何完成的,还是只使用 java 内置方法。以下是分别从提到的 SO 问题的thisthis 答案复制的解决方案。

选项 1:Util 方法

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

选项 2:单线内置

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

【讨论】:

  • 你的回答帮助我stackoverflow.com/a/25790612/173149,谢谢+1
  • +1 表示使用 Java 已提供的类的单线选项。
  • 对于字符串56276BE1,它给了我86, 39, 107, -31 的字节。但是另一个用 C# 编写的应用程序给了我86, 39, 107, 225 相同的十六进制字符串。哪一个是真的?
  • 两者都是正确的。 C# 处理字节的方式与 Java 不同。在 Java 中字节值介于 -127 和 127 之间,而 C# 有 0 到 255。
  • 在 Java 9 上,单行内置似乎不再是内置的,因为简单地导入 javax.xml.bind.DatatypeConverter 不起作用。
【解决方案3】:

我发现 DatatypeConverter.parseHexBinary 比: 更昂贵(两倍):

org.apache.commons.codec.binary.Hex(str.toCharArray())

【讨论】:

  • 这比 DatatypeConverter 成本更高,因为 Apache commons 是一个附加库(依赖关系、大小等) - 而 DatatypeConverter 是 JDK 的一部分。
猜你喜欢
  • 2017-08-23
  • 1970-01-01
  • 2015-01-20
  • 2019-07-27
  • 2014-03-10
  • 2013-08-09
  • 1970-01-01
  • 2012-01-28
  • 2013-02-07
相关资源
最近更新 更多