dat*_*ser 4 java binary hex bit-manipulation
byte s[] = getByteArray()
for(.....)
Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);
Run Code Online (Sandbox Code Playgroud)
我知道您正在尝试将字节转换为十六进制字符串.我不明白的是如何做到这一点.例如,如果s [i]是00000001(十进制1),你可以解释一下:
谢谢.
pax*_*blo 11
这基本上是因为字节是用Java签名的.如果将一个字节提升为int,它将签名扩展,这意味着该字节0xf2将成为0xfffffff2.符号扩展是一种通过将最高有效(符号)位复制到所有高阶位来在加宽时保持值相同的方法.上述两个值均-14采用二进制补码表示法.如果相反,你已经扩大0xf2到了0x000000f2,那242可能不是你想要的.
因此,&操作是剥离任何那些扩展位,只留下最低有效8位.但是,因为无论如何你将在下一步将这些位强制为1,这一步似乎有点浪费.
该|操作之后的,这将迫使所有的高位为1,这样你保证,从获得的8个字符的字符串ffffff00,通过ffffffff包容性的(因为toHexString不给你前导零,这将转化7为"7",而不是"07"你想要的) .
在substring(6)随后进行涂布,使得您只能获得最后两个的这八个十六进制数字.
当你可以使用时,这似乎是一种非常复杂的方法,可以确保你得到一个双字符的十六进制字符串String.format ("%02x", s[i]).但是,这个特定的代码片段可能在String.format引入时可能早于Java 5 .
如果您运行以下程序:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
你会看到两个表达式是相同的 - 它只是吐出来,Done因为这两个表达式在所有情况下产生相同的结果.