我正在寻找一种方法来转换长字符串(从转储),它表示十六进制值到一个字节数组 .
我不能比发布the same question here的人更好地措辞 .
但为了保持原创,我会用自己的方式来表达它:假设我有一个字符串 "00A0BF"
,我想把它解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是Java新手,最后使用 BigInteger
并注意领先的十六进制零 . 但我觉得它很难看,我确信我错过了一些简单的东西 .
我正在寻找一种方法来转换长字符串(从转储),它表示十六进制值到一个字节数组 .
我不能比发布the same question here的人更好地措辞 .
但为了保持原创,我会用自己的方式来表达它:假设我有一个字符串 "00A0BF"
,我想把它解释为
byte[] {0x00,0xA0,0xBf}
我该怎么办?
我是Java新手,最后使用 BigInteger
并注意领先的十六进制零 . 但我觉得它很难看,我确信我错过了一些简单的东西 .
25 回答
编辑:正如@mmyers所指出的,此方法不适用于包含与高位设置的字节对应的子串的输入("80" - "FF") . 解释是在Bug ID: 6259307 Byte.parseByte not working as advertised in the SDK Documentation .
对于它的 Value ,这是另一个支持奇数长度字符串的版本,而不需要求助于字符串连接 .
Bert Regelink提出的守则根本行不通 . 请尝试以下方法:
实际上,我认为BigInteger解决方案非常好:
编辑: Not safe for leading zeros ,如海报所述 .
我知道这是一个非常古老的线程,但仍然喜欢添加我的便士 Value .
如果我真的需要将简单的十六进制字符串编码为二进制转换器,我想按如下方式进行 .
commons-codec中的Hex类应该为你做 .
http://commons.apache.org/codec/
到目前为止还不是最干净的解决方案 . 但它适用于我,格式很好:
输出:
HexBinaryAdapter
提供了在String
和byte[]
之间编组和解组的功能 .这只是我输入的一个例子......我实际上只是按原样使用它,不需要单独使用它 .
您现在可以在
guava
中使用BaseEncoding来完成此操作 .扭转它的使用
我总是使用像这样的方法
此方法在空格分隔的十六进制值上进行拆分,但要将字符串拆分为任何其他条件(如两个字符的分组)并不困难 .
public static String toHexString(byte [] array){
return DatatypeConverter.printHexBinary(array);
}
public static byte [] toByteArray(String s){
return datatypeConverter.parseHexBinary(s);
}
对于那些对FractalizeR背后的实际代码感兴趣的人FractalizeR(我需要,因为javax.xml.bind不适用于Android(默认情况下)),这来自com.sun.xml.internal.bind.DatatypeConverterImpl.java:
java.math中的
BigInteger()
方法非常慢,无法推荐 .Integer.parseInt(HEXString, 16)
某些字符可能会导致问题,而无需转换为数字/整数
一个好的工作方法:
功能:
玩得开心,祝你好运
我的正式解决方案
就像PHP hex2bin() Function而是Java风格 .
Example:
One-liners:
Warnings :
_999_在Java 9 Jigsaw中这不再是(默认)java.se根集的一部分,因此它将导致ClassNotFoundException,除非你指定--add-modules java.se.ee(感谢@
eckes
)Fabian
注意到这一点),但如果您的系统由于某种原因缺少javax.xml
,则可以take the source code . 感谢@Bert Regelink
提取源代码 .迟到了,但是我把DaveL上面的答案合并到一个反向行动的课堂上 - 以防它有所帮助 .
和JUnit测试类:
这是一种实际工作的方法(基于以前的几个半正确答案):
我能看到的唯一可能的问题是输入字符串是否非常长;调用toCharArray()会生成字符串内部数组的副本 .
编辑:哦,顺便说一句,字节用Java签名,所以你的输入字符串转换为[0,-96,-65]而不是[0,160,191] . 但你可能已经知道了 .
我想会为你做的 . 我从一个类似的函数拼凑它,将数据作为字符串返回:
这是一个我认为比目前发布的任何一个更好的解决方案:
这是一个改进的原因:
带前导零的安全(与BigInteger不同)和负字节值(与Byte.parseByte不同)
不将String转换为
char[]
,或为每个字节创建StringBuilder和String对象 .没有可能不可用的库依赖项
如果不知道参数是否安全,可以通过
assert
或异常添加参数检查 .我喜欢Character.digit解决方案,但这是我如何解决它
对我来说这是解决方案,HEX =“FF01”然后拆分为FF(255)和01(01)
在android中,如果你正在使用十六进制,你可以尝试okio .
简单用法:
结果将是
我发现Kernel Panic让解决方案对我最有用,但如果十六进制字符串是一个奇数,则会遇到问题 . 这样解决了:
我在数组中添加了一些十六进制数,所以我将引用传递给我正在使用的数组,并且我需要转换的int并返回下一个十六进制数的相对位置 . 所以最后的字节数组有[0]个十六进制对,[1 ...]十六进制对,然后对数...
基于操作选择的解决方案,以下应该更有效:
因为:初始转换为char数组会使charAt中的长度检查失效
如果您偏好Java 8流作为编码风格,那么只需使用JDK原语即可实现 .
如果您不介意捕获
IOException
,则可以省略收集器连接函数中的, 0, s2.size()
参数 .