如何从指针读取字节序列C++一样长
How to read sequence of bytes from pointer in C++ as long?
我有一个指向char
数组的指针,我需要用一个 64 位掩码对每个字节进行 XOR 运算。我认为最简单的方法是将每 8 个字节读取为一个long long
或uint64_t
和 XOR,但我不确定如何。也许投射到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
等)都由编译器执行。但是,如果您尝试在代码中"聪明",则可能会无意中阻止编译器进行优化。所以试着写简单的代码。
附言您可能还应该使用 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 上,小端序,最低有效字节将掩码输入数组的第一个字节)
相关文章:
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- 堆栈和队列是否像C++中的数组一样传递?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 我如何在C++像在 Python 中一样实现 f 字符串?
- 自制的上衣:看起来一样,但不完全相同
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 像 CPP 中的控制台一样的应用程序
- 为什么C++中没有常量引用,就像常量指针一样?
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 有没有像给定的一样的 std::optional_function
- Java 是否像C++模板一样具有泛型推论?
- 记忆栅栏和记忆屏障是一样的吗
- 对象作为参数传递,就好像我们正在传递构造函数值一样
- 像自定义类一样构造的指针(内置类型)如何工作?
- JavaScript箭头函数:我们能否像C ++ lambdas一样捕获值