java - 有人可以向我解释以下 Java 代码在做什么吗?

标签 java binary hex bit-manipulation

byte s[] = getByteArray()
for(.....)
Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);

我了解到您正在尝试将字节转换为十六进制字符串。我不明白的是这是如何完成的。例如,如果 s[i] 是 00000001(十进制 1),请解释一下:

  1. 为什么是 0x000000ff 和 00000001?为什么不直接使用 00000001?
  2. 为什么来自 #1 | 0xffffff00?
  3. 最后为什么要应用 substring(6)?

谢谢。

最佳答案

这基本上是因为字节是用 Java 签名的。如果将一个字节提升为一个 int,它会标记扩展,这意味着字节 0xf2 将变为 0xfffffff2。符号扩展是一种通过将最高有效(符号)位复制到所有高阶位来在加宽值时保持值相同的方法。以上两个值都是 -14 的二进制补码表示法。相反,如果您将 0xf2 扩大到 0x000000f2,它将是 242,可能不是您想要的。

所以 & 操作是剥离任何这些扩展位,只留下最低有效的 8 位。但是,由于无论如何您都将在下一步中将这些位强制为 1,因此这一步似乎有点浪费。

紧随其后的 | 操作将强制所有高位为 1,这样您就可以保证从 ffffff00 获得一个 8 字符的字符串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");
    }
}

您会看到这两个表达式是相同的 - 它只是吐出 Done 因为这两个表达式在所有情况下都产生相同的结果。

关于java - 有人可以向我解释以下 Java 代码在做什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4120790/

相关文章:

assembly - 如何使用十六进制编辑器更改指令?

java - Java中的十六进制转换错误

java - 如何从 HTML 表单调用 servlet

c++ - 如何创建属性存储二进制文件

java协议(protocol)实现头长度

c - c 中的补码 ~ 运算符不能正确翻转位?

c++ - 以十六进制或十进制打印到 stdout,一个 std::string 作为字节序列

java转换UTF-8字符(è)问题

Java - JCheckBox 针对列表进行过滤

java - 如何从一个 EAR 访问另一个 EAR 中定义的 EJB