Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AES实现中字节和整数的位移位会产生奇怪的结果_Java_Bytearray_Aes_Bit Shift - Fatal编程技术网

Java AES实现中字节和整数的位移位会产生奇怪的结果

Java AES实现中字节和整数的位移位会产生奇怪的结果,java,bytearray,aes,bit-shift,Java,Bytearray,Aes,Bit Shift,我很难理解Java如何通过逐位操作将字节提升为整数。我正在尝试实现AES,虽然我的输出作为2d字节数组是正确的,但我最终需要将其存储在1d int数组中。但是,以下代码更改了一些预期值 ciphertexts[0] = ((state[0][0] & 0xFF) << 24) ^ ((state[1][0] & 0xFF) << 16) ^ ((state[2][0] & 0xFF) <<

我很难理解Java如何通过逐位操作将字节提升为整数。我正在尝试实现AES,虽然我的输出作为2d字节数组是正确的,但我最终需要将其存储在1d int数组中。但是,以下代码更改了一些预期值

    ciphertexts[0] = ((state[0][0] & 0xFF) << 24) ^ ((state[1][0] & 0xFF) << 16)
                    ^ ((state[2][0] & 0xFF) << 8) ^ state[3][0];
    ciphertexts[1] = ((state[0][1] & 0xFF) << 24) ^ ((state[1][1] & 0xFF) << 16)
                    ^ ((state[2][1] & 0xFF) << 8) ^ state[3][1];
    ciphertexts[2] = ((state[0][2] & 0xFF) << 24) ^ ((state[1][2] & 0xFF) << 16)
                    ^ ((state[2][2] & 0xFF) << 8) ^ state[3][2];
    ciphertexts[3] = ((state[0][3] & 0xFF) << 24) ^ ((state[1][3] & 0xFF) << 16)
                    ^ ((state[2][3] & 0xFF) << 8) ^ state[3][3];    
这就是我试图用上面的代码做的。在没有屏蔽的情况下,以下代码给出以下输出:

69000000
006A0000
0000D800
00000070
696AD870
    int zero = (state[0][0] << 24);
    int one = (state[0][1] << 16);
    int two = (state[0][2] << 8);
    int three = state[0][3];
    int total = zero ^ one ^ two ^ three;

69000000
006A0000
FFFFD800
00000070
9695D870
而不是:

69C4E0D86A7B0430D8CDB78070B4C55A

所以我的问题是,如何将字节整齐地组合成整数,以及掩蔽和移位的实际情况。我看了其他答案,不明白为什么在这种情况下它们不起作用。谢谢

这就是缺少
无符号的
语言的残酷性
(如果他/她使用有符号字符,即有符号字节,则在C中可以得到相同的结果)
让我们忽略班次,只专注于作业和
&

此处的示例值0xfe而不是0xd8
(0x80和0xff之间的每个值都会出现问题)

问题是,java:

byte a = 0xfe;
int i = a;
有问题,C:

signed char a = 0xfe;
int i = a;
发生的情况:一个字节可以保存-128到+127之间的值。
0xfe映射到负数(2-补码):-2
…因此,我得到i中的值-2,i不是8位,而是32位长。
根据2-补码的规则,这将给出0xfffffffe
()

那么,什么会改变&因为先用0xff屏蔽0xfe
不应该更改该值吗?
是的,但是:正如
&
是一种类似
+-
的“计算”…
该值首先扩展到32位
(因为更适合处理器的ALU)

C/Asm程序员更可能知道这一点,
但正如您所看到的,它在Java中也是相关的。
(如果指定的变量小于32位,
计算后将再次缩短)

即,首先,-2=0xfe变为32位-2=0xFFFFFE,
然后掩蔽会再次产生0xfe(已经是32位)..

分配给i.

您的
状态[0][2]
的值是一个字节
0xD8
。这将最高有效位设置为1:二进制:
1101 1000
。在移位操作之前,为什么要使用xor(
^
)操作而不是简单的按位or(
|
)?真的没有理由。当我试图弄清楚发生了什么时,我曾在它们之间切换,这是我的代码处于的最后一个状态。状态[]是如何声明的?这个奇怪的值,以及使用0xFF进行anding有帮助的事实,让我怀疑它包含的值正在进行符号扩展。这就是我刚刚得出的结论。接得好。呵呵——活该:照顾好猫,把它放出来,回到电脑前,不要检查答案是否已经存在:-)
69C4E0D86A7B0430D8CDB78070B4C55A
byte a = 0xfe;
int i = a;
signed char a = 0xfe;
int i = a;