按位运算中的类型转换让我在 C 中感到困惑
Type casting in bitwise operations confuses me in C
我正在尝试制作密码加密的一部分。我正在尝试用我得到的密钥流加密数据。
数据格式为uint8_t,密钥流KS为uint32_t。
变量 n 是数据的长度(显然是 32 位块)
我有这个代码:
for (i=0; i<n; i++)
{
wo_data[4*i+0] ^= (uint8_t)(KS[i] >> 24) & 0xff;
wo_data[4*i+1] ^= (uint8_t)(KS[i] >> 16) & 0xff;
wo_data[4*i+2] ^= (uint8_t)(KS[i] >> 8) & 0xff;
wo_data[4*i+3] ^= (uint8_t)(KS[i] ) & 0xff;
}
但它并没有达到预期的效果。
现在,如果我将数据转换为 32 位长度:
uint32_t* data2 = (uint32_t *)wo_data;
for(i=0; i < n; i++)
{
data2[i] ^= KS[i];
}
它开始工作了。有人可以向我解释为什么吗?我更喜欢使用 8 位长度,因为如果输入数据不是字节对齐的,它更容易对齐结尾。
数据初始化如下:
7EC61272 743BF161 4726446A 6C38CED1
66F6CA76 EB543004 4286346C EF130F92
KS 初始化如下:
F22DB45B 37E71C5B 4EB6F404 CD886C15
9DCA27B1 F062AF46 F8E2F587 8976E8B8
我期待以下(显然):
8CEBA629 43DCED3A 0990B06E A1B0A2C4
FB3CEDC7 1B369F42 BA64C1EB 6665E72A
正如@Arkku 在评论中所述,这是一个字节顺序问题。
例如,如果您在小端机器上,K[0]=0xF22DB45B 将按以下方式存储:
@K+0: 5B
@K+1: B4
@K+2: 2D
@K+3: F2
因此,每个 KS 字的最低有效字节 (LSB) 必须与 wo_data[4*i+0]
进行异或,依此类推。
这段代码给出了期望值:
for (int i=0; i < N; i++)
{
wo_data[4*i+0] ^= ((KS[i] ) & 0xff);
wo_data[4*i+1] ^= ((KS[i] >> 8) & 0xff);
wo_data[4*i+2] ^= ((KS[i] >> 16) & 0xff);
wo_data[4*i+3] ^= ((KS[i] >> 24) & 0xff);
}
32 位版本可能更快,因为它每条指令处理更多字节。此外,它可以被矢量化并以更有效的方式执行。参见generated assembly for the 8- and 32-bit versions。 8位版本可用于处理剩余的字节,如果有的话。
我正在尝试制作密码加密的一部分。我正在尝试用我得到的密钥流加密数据。
数据格式为uint8_t,密钥流KS为uint32_t。
变量 n 是数据的长度(显然是 32 位块)
我有这个代码:
for (i=0; i<n; i++)
{
wo_data[4*i+0] ^= (uint8_t)(KS[i] >> 24) & 0xff;
wo_data[4*i+1] ^= (uint8_t)(KS[i] >> 16) & 0xff;
wo_data[4*i+2] ^= (uint8_t)(KS[i] >> 8) & 0xff;
wo_data[4*i+3] ^= (uint8_t)(KS[i] ) & 0xff;
}
但它并没有达到预期的效果。
现在,如果我将数据转换为 32 位长度:
uint32_t* data2 = (uint32_t *)wo_data;
for(i=0; i < n; i++)
{
data2[i] ^= KS[i];
}
它开始工作了。有人可以向我解释为什么吗?我更喜欢使用 8 位长度,因为如果输入数据不是字节对齐的,它更容易对齐结尾。
数据初始化如下:
7EC61272 743BF161 4726446A 6C38CED1
66F6CA76 EB543004 4286346C EF130F92
KS 初始化如下:
F22DB45B 37E71C5B 4EB6F404 CD886C15
9DCA27B1 F062AF46 F8E2F587 8976E8B8
我期待以下(显然):
8CEBA629 43DCED3A 0990B06E A1B0A2C4
FB3CEDC7 1B369F42 BA64C1EB 6665E72A
正如@Arkku 在评论中所述,这是一个字节顺序问题。
例如,如果您在小端机器上,K[0]=0xF22DB45B 将按以下方式存储:
@K+0: 5B
@K+1: B4
@K+2: 2D
@K+3: F2
因此,每个 KS 字的最低有效字节 (LSB) 必须与 wo_data[4*i+0]
进行异或,依此类推。
这段代码给出了期望值:
for (int i=0; i < N; i++)
{
wo_data[4*i+0] ^= ((KS[i] ) & 0xff);
wo_data[4*i+1] ^= ((KS[i] >> 8) & 0xff);
wo_data[4*i+2] ^= ((KS[i] >> 16) & 0xff);
wo_data[4*i+3] ^= ((KS[i] >> 24) & 0xff);
}
32 位版本可能更快,因为它每条指令处理更多字节。此外,它可以被矢量化并以更有效的方式执行。参见generated assembly for the 8- and 32-bit versions。 8位版本可用于处理剩余的字节,如果有的话。