raf*_*raf 353 java hex byte dump
我正在寻找一种方法来转换长字符串(从转储),它表示十六进制值到一个字节数组.
但为了保持原创,我会用自己的方式来表达它:假设我有一个"00A0BF"
我想要解释为的字符串
byte[] {0x00,0xA0,0xBf}
Run Code Online (Sandbox Code Playgroud)
我该怎么办?
我是Java新手,最后使用BigInteger
并注意领先的十六进制零.但我觉得它很难看,我确信我错过了一些简单的东西.
Dav*_* L. 609
这是一个我认为比目前任何发布的解决方案更好的解决方案:
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;
}
Run Code Online (Sandbox Code Playgroud)
这是一个改进的原因:
带前导零的安全(与BigInteger不同)和负字节值(与Byte.parseByte不同)
不将String转换为a char[]
,或为每个字节创建StringBuilder和String对象.
没有可能不可用的库依赖项
assert
如果不知道参数是否安全,可以随意添加参数检查或异常.
Vla*_*sny 325
单行:
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);
}
Run Code Online (Sandbox Code Playgroud)
警告:
eckes
)Fabian
注意到这一点),但如果您的系统因某些原因缺乏,您可以获取源代码javax.xml
.感谢@ Bert Regelink
提取源代码.ska*_*man 75
commons-codec中的Hex类应该为你做.
http://commons.apache.org/codec/
import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF
Run Code Online (Sandbox Code Playgroud)
jon*_*tro 36
您现在可以使用BaseEncoding在guava
做到这一点.
BaseEncoding.base16().decode(string);
Run Code Online (Sandbox Code Playgroud)
扭转使用
BaseEncoding.base16().encode(bytes);
Run Code Online (Sandbox Code Playgroud)
Dav*_* L. 27
实际上,我认为BigInteger解决方案非常好:
new BigInteger("00A0BF", 16).toByteArray();
Run Code Online (Sandbox Code Playgroud)
编辑:正如海报所述,对于前导零不安全.
Grk*_*eer 24
该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;
}
Run Code Online (Sandbox Code Playgroud)
这只是我输入的一个例子......我实际上只是按原样使用它,不需要单独使用它.
Ber*_*ink 24
单行:
Run Code Online (Sandbox Code Playgroud)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); }
对于那些你感兴趣的背后的实际代码一行程序从FractalizeR(我需要的,因为javax.xml.bind中没有可用于Android(默认)),这个来自com.sun.xml.internal.bind. DatatypeConverterImpl.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();
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ers 14
这是一种实际工作的方法(基于以前的几个半正确答案):
private static byte[] fromHexString(final String encoded) {
if ((encoded.length() % 2) != 0)
throw new IllegalArgumentException("Input string must contain an even number of characters");
final byte result[] = new byte[encoded.length()/2];
final char enc[] = encoded.toCharArray();
for (int i = 0; i < enc.length; i += 2) {
StringBuilder curr = new StringBuilder(2);
curr.append(enc[i]).append(enc[i + 1]);
result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我能看到的唯一可能的问题是输入字符串是否非常长; 调用toCharArray()会生成字符串内部数组的副本.
编辑:哦,顺便说一句,字节用Java签名,所以你的输入字符串转换为[0,-96,-65]而不是[0,160,191].但你可能已经知道了.
Mia*_*007 11
在android中,如果你正在使用hex,你可以尝试okio.
简单用法:
byte[] bytes = ByteString.decodeHex("c000060000").toByteArray();
Run Code Online (Sandbox Code Playgroud)
结果将是
[-64, 0, 6, 0, 0]
Run Code Online (Sandbox Code Playgroud)
编辑:正如@mmyers所指出的,此方法不适用于包含与高位集(“80”-“FF”)的字节相对应的子字符串的输入。错误 ID:6259307 Byte.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;
}
Run Code Online (Sandbox Code Playgroud)
BigInteger()
来自java.math 的方法非常慢并且不值得推荐。
Integer.parseInt(HEXString, 16)
可能会导致某些字符出现问题而没有转换为数字/整数
运作良好的方法:
Integer.decode("0xXX") .byteValue()
Run Code Online (Sandbox Code Playgroud)
功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
玩得开心,祝你好运
无论如何,这里有另一个版本,它支持奇数长度字符串,而无需诉诸字符串连接。
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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
438198 次 |
最近记录: |