在java中将字符串转换为字节[重复]
Posted
技术标签:
【中文标题】在java中将字符串转换为字节[重复]【英文标题】:Converting String to bytes in java [duplicate] 【发布时间】:2012-11-22 23:25:48 【问题描述】:可能重复:Convert a string representation of a hex dump to a byte array using Java?
我想将 String "1B4322C2"
转换为字节,但问题是如果我使用 getBytes()
它会将其转换为字符串长度的两倍,我想将它们转换为字符串长度的一半。
例如以上字符串的输出应该是0x1B , 0x43, 0x22, 0xC2
谢谢
【问题讨论】:
字符串总是8个字符吗? 【参考方案1】:要将“1B4322C2”编码为字节,您可以使用
byte[] bytes = new BigInteger("FB4322C2", 16).toByteArray();
if (bytes.length > 1 && bytes[0] == 0)
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
System.out.println(Arrays.toString(bytes));
打印
[-5, 67, 34, -62]
【讨论】:
【参考方案2】:您不需要 String.getBytes() 方法。这会将字符串的字符转换为它们的字节表示形式。
要执行您想要执行的操作,您需要手动将字符串拆分为单独的字符串,每对一个字符串。然后,您将要解析它们。
不幸的是,Java 没有无符号字节,0xC2 会溢出。如果内存不是问题,您可能希望将这些值视为短裤或整数。
因此,您可以使用 Integer 类将字符串解析为数字。由于您的字符串是十六进制的,因此您必须使用可让您提供基数的 parse 方法。
String test = "1B4322C2";
for (int bnum = 0; bnum < test.length() / 2; bnum++)
String bstring = test.substring(bnum * 2, bnum * 2 + 2);
int bval = Integer.parseInt(bstring, 16);
System.out.println(bstring + " -> " + bval);
这将输出:
1B -> 27
43 -> 67
22 -> 34
C2 -> 194
如果您需要将它们放在数组中,您可以实例化一个宽度为字符串一半的数组,然后它们将每个值放在其bnum
索引下。
【讨论】:
Java doesn't have unsigned bytes, and 0xC2 is going to overflow.
绝对的废话。没有溢出。试试byte b = 0xC2;
它可以工作。【参考方案3】:
(我现在已经投票决定以重复的形式关闭,我应该先这样做......但是在问题被删除之前将这个答案留在这里是有意义的......)
对,所以你实际上想要做的是解析一个十六进制字符串。
您应该查看Apache Commons Codec,它有一个Hex
类正是为了这个目的。就我个人而言,我对 API 并不感兴趣,但这应该可行:
Hex hex = new Hex();
byte[] data = (byte[]) hex.decode(text);
或者:
byte[] data = Hex.decodeHex(text.toCharArray());
(我个人希望你可以使用byte[] data = Hex.decodeHexString(text);
,但我们开始了......如果你愿意,你可以随时编写自己的包装方法。)
如果您不想使用 3rd 方库,则 Stack Overflow 上的其他地方有很多实现,例如this one.
【讨论】:
你可以使用Byte.parseByte(str,16);
@Quoi:嗯,这需要为每个字节创建一个新的String
对象。我认为我们不需要那么低效。
我们为什么要向 Apache Commons 发送 Java 开头?这可以使用基本数字原始包装类来处理。编辑:哦等等,这家伙不是java初学者。本来可以骗我的。继续。
@JonSkeet - 类似if ((str.length() % 2) == 1) str = "0" + str; for(int i=0;i<str.length()-1;) String str1 = str.substring(i, i+2); System.out.print(Byte.parseByte(str1,16)); i+=2;
@Chris:即使对于初学者来说,很多事情当然可以在没有第三方库的情况下实现,但不应该——为什么要重新发明一个已经在其他地方有效发明的***?我认为寻找解决问题的现有库是我们应该积极教给初学者的东西。 (Guava 和 Joda Time 是我首先引导人们访问的图书馆 :)【参考方案4】:
如果您不想使用外部库,这应该通过一些调整来解决问题(添加 0x 和 )
public static String byteArrayToHexadecimal(byte[] raw)
final BigInteger bi = new BigInteger(1, raw);
final String result = bi.toString(16);
if (result.length() % 2 != 0)
return "0" + result;
return result;
抱歉,换个方式(没有优化,因为对我来说根本不是瓶颈):
public static byte[] hexadecimalToByteArray(String hex)
if (hex.length() % 2 != 0)
hex = "0" + hex;
final byte[] result = new byte[hex.length() / 2];
for (int i = 0; i < hex.length(); i += 2)
String sub = "0x" + hex.substring(i, i + 2);
result[i / 2] = (byte) ((int) Integer.decode(sub));
return result;
不过,我建议按照 J. Skeet 的建议选择 Apache Commons Codec
【讨论】:
OP 想要反过来,但我承认BigInteger
的使用很巧妙。
请注意,这与 OP 想要的方向相反,我个人不会使用 BigInteger
进行十六进制转换 - 这不是它的设计目的,它通常会削减前导0。 (例如,使用上面的代码, 0, 0, 0 应该给出“000000”,但我相信它只会给出“00”。)【参考方案5】:
您可以使用 String Tokenizer 或 String Builder 并分离字符串,然后将其从十六进制转换为字符串...
此链接可能对您有所帮助..Convert Hex to ASCII
希望这会有所帮助..
【讨论】:
【参考方案6】:getBytes
将每个字符转换为字节形式的字符代码;它不会从字符串本身解析出字节值。为此,您可能需要编写自己的解析函数。
【讨论】:
以上是关于在java中将字符串转换为字节[重复]的主要内容,如果未能解决你的问题,请参考以下文章