如何从C ++中的指针读取字节序列?

How to read sequence of bytes from pointer in C++ as long?

我有一个指向 char 数组的指针,我需要使用 64 位掩码对每个字节进行异或运算。我认为最简单的方法是将每 8 个字节读取为一个 long longuint64_t 并与之进行异或,但我不确定如何。也许转换为 long long* 并取消引用?一般来说,我仍然不太确定指针,因此任何示例代码也将不胜感激。谢谢!

编辑:示例代码(只是为了展示我想要的,我知道它不起作用):

void encrypt(char* in, uint64_t len, uint64_t key) {
        for (int i = 0; i < (len>>3); i++) {
            (uint64_t*)in ^= key;
            in += 8;
        }
    }
}

进行异或屏蔽的直接方法是按字节:

void encrypt(uint8_t* in, size_t len, const uint8_t key[8])
{
    for (size_t i = 0; i < len; i++) {
        in[i] ^= key[i % 8];
    }
}

注意:这里的key是一个8字节的数组,不是64位的数。这段代码很简单——不需要任何技巧,易于调试。衡量它的性能,如果性能足够好,就完成它。

一些(大多数?)编译器通过矢量化 优化此类简单代码。也就是说,所有细节(转换为 uint64_t 等)都由编译器执行。但是,如果您尝试在代码中使用 "clever",您可能会无意中阻止编译器进行优化。所以尽量写简单的代码。

P.S。您可能还应该使用 restrict 关键字,该关键字当前是非标准的,但可能是获得最佳性能所必需的。我没有使用它的经验,所以没有将它添加到我的示例中。


如果你的编译器不好,无法启用矢量化选项,或者只是想玩玩,你可以使用这个带有转换的版本:

void encrypt(uint8_t* in, size_t len, uint64_t key)
{
    uint64_t* in64 = reinterpret_cast<uint64_t*>(in);
    for (size_t i = 0; i < len / 8; i++) {
        in64[i] ^= key;
    }
}

它有一些限制:

  • 要求长度能被8整除
  • 要求处理器支持未对齐的指针(不确定 x86 - 可能会工作)
  • 编译器可能会拒绝对其进行矢量化,从而导致性能下降
  • 正如 Hurkyl 指出的那样,掩码中 8 个字节的顺序不明确(在 x86 上,小端字节序,最低有效字节将掩码输入数组的第一个字节)