【问题标题】:Type casting in bitwise operations confuses me in C按位运算中的类型转换让我在 C 中感到困惑
【发布时间】:2023-03-22 14:25:01
【问题描述】:

我正在尝试制作密码加密的一部分。我正在尝试使用我获得的密钥流对数据进行加密。

数据格式为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

【问题讨论】:

  • “但它甚至没有达到预期的效果。” 预期什么?会发生什么?
  • 通过编辑帖子,您应该明确KSwo_data 最初包含哪些数据,您得到什么结果以及您期望什么结果。
  • "数据采用 uint8_t 格式" ..."数据初始化如下:7EC61272 ..." 这有什么意义?您不能在 uint8_t 中存储 32 位数字。
  • 您确定字节序吗?此外,&amp; 0xff 转换为 uint8_t 之后看起来是多余的。

标签: c char int bit-manipulation unsigned


【解决方案1】:

正如@Arkku 在 cmets 中所说,这是一个字节顺序问题。

例如,如果你在一个 little-endian 机器中,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 位版本可用于处理剩余字节(如果有)。

【讨论】:

  • 效率真的跟向量化无关。如果您关闭所有向量操作,您可以看到编译器为 32 位版本生成更高效的代码。这只是一个简单的结果,即一次处理 4 个字节比一次处理 1 个字节要快。 (我想这也许是最微不足道的意义上的“矢量化”,但这并不是该术语在优化上下文中通常的含义。)
  • 如您所说,标量 32 位版本比 8 位版本更有效(每条指令处理 4 个字节与 1 个字节)。但是矢量化 32 位版本可能比标量 32 位版本更快(对于 AVX,每条指令处理 32 字节与 8 字节)。 See assembly code for both scalar and vectorized versions.
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2019-08-21
  • 1970-01-01
  • 2021-09-21
相关资源
最近更新 更多