byte s[] = getByteArray()
for(.....)
Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);
我知道您正在尝试将字节转换为十六进制字符串。我不明白的是如何做到这一点。例如,如果s [i]是00000001(十进制1),那么请解释一下:
感谢。
答案 0 :(得分:11)
这基本上是因为字节是用Java签名的。如果将字节提升为int,则它将签名扩展,这意味着字节0xf2
将变为0xfffffff2
。符号扩展是一种通过将最高有效(符号)位复制到所有高阶位来在加宽时保持值相同的方法。上述两个值都是-14
的二进制补码表示法。如果您将0xf2
扩展为0x000000f2
,则可能是242
,可能不是您想要的内容。
因此&
操作是剥离任何扩展位,只留下最低有效8位。但是,由于你无论如何都要在下一步将这些位强制为1,这一步似乎有点浪费。
此后的|
操作会强制所有高位为1,这样您就可以保证从ffffff00
到ffffffff
包含8个字符的字符串(从{到{ {1}}不会向您提供前导零,它会将toHexString
转换为7
而不是您想要的"7"
。
然后应用"07"
,以便您只获得这八个十六进制数字中的最后两个。
当您可以使用substring(6)
时,确保您获得双字符十六进制字符串似乎是一种非常复杂的方法。但是,当String.format ("%02x", s[i])
被引入时,这个特定的代码片段可能早于Java 5。
如果您运行以下程序:
String.format
你会看到两个表达式是相同的 - 它只是吐出public class testprog {
public static void compare (String s1, String s2) {
if (!s1.equals(s2))
System.out.println ("Different: " + s1 + " " + s2);
}
public static void main(String args[]) {
byte b = -128;
while (b < 127) {
compare (
Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
String.format("%02x", b, args));
b++;
}
compare (
Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
String.format("%02x", b, args));
System.out.println ("Done");
}
}
,因为这两个表达式在所有情况下都会产生相同的结果。