C++中的异或加密,警告“使用带二进制位运算符的有符号整数操作数”

我正在学习 C++ 中的简单 XOR 加密算法。

下一个代码工作正常:

void test(int8_t* data, const int data_length) {
    const uint8_t key = 123;

    for (int index = 0; index < data_length; index++)
        data[index] = data[index] ^ key;
}

我得到的数据是有符号的,因此类型为int8_t

问题是编译器显示了下一个警告:

“使用带二进制位运算符的有符号整数操作数”

在执行 XOR 操作时,我可以通过使用uint8_t转换数据来发出警告,但我不知道其中的含义。我已经做了一些测试并且似乎没有问题,但是我很困惑,因为数据可以包含有符号值,所以我不确定通过转换它是否我弄乱了数据。

即使数据可以包含负值,转换为 uint8_t 是否正确?还是我应该忽略警告?

回答

编译器发出警告,因为不应该对有符号整数执行按位运算。在 C++20 之前的 C++ 中,允许有符号整数的不同表示,这意味着相同的数字可以在不同的机器和编译器上用不同的位模式表示。这使得对有符号整数进行位操作的结果不可移植。当然,intN_t总是要求使用二进制补码表示(并且 C++20 将该要求扩展到所有有符号整数),但仍然不建议将有符号整数用于按位运算。

在您的特定情况下,data[index]key都被提升为int执行 XOR 操作。然而,由于data[index]是一个有符号整数,它的值被符号扩展,而无符号key被零扩展。这意味着 XOR 只影响中间int值的低 8 位,结果可能不适合int8_t范围。当您将结果分配回 时data[index],可能会发生有符号溢出,这在 C++ 中是 UB(在 C++20 之前;从 C++20 开始,它被很好地定义为截断高位)。

在这种情况下,正确的做法是将您的数据视为原始字节数组,而不管这些字节代表什么值。这意味着,您应该使用std::bytestd::uint8_t来表示输入和输出数据。这样,您将在无符号整数上进行操作,并且没有可移植性或潜在的溢出问题。


以上是C++中的异或加密,警告“使用带二进制位运算符的有符号整数操作数”的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>