【问题标题】:XOR Encryption in C++C++ 中的异或加密
【发布时间】:2019-12-01 01:13:09
【问题描述】:

我正在尝试使用long 类型的数字来实现简单的异或加密。不幸的是,一些数字返回一些符号,解密它们会得到与输入的完全不同的文本。

例如,使用密钥 '5105105105' 加密文本 'hello world' 会返回此 '�????�'。要使用相同的密钥解密它,它会返回这个'>nl wor>nl'。我不确定它为什么要这样做。

这是我的代码:

string encDec(string str, long key) {
    string output = str;

    for (int i = 0; i < str.size(); i++)
        output[i] = str[i] ^ key;

    return output;
}

我在这里做错了什么?

【问题讨论】:

  • 请创建一个minimal reproducible example
  • 为什么不做一些调试并打印出循环中的中间值呢?也许通过查看整数值,它会告诉您错误是什么。在字符串中看到一堆哔哔声并不会给您(或我们)任何信息。
  • 与您的问题有关,我看到的最大问题是键和值元素承载相同值的机会。问问自己,“a ^ a 总是会产生什么结果,以及它在看起来是字符串的情况下的效果如何?这种“加密”的结果至少应该是字节向量;而不是字符串。跨度>
  • @WhozCraig 是的,结果不是字符串,但它可以放入 std::string 中,这只是 char 元素的特殊向量类型。

标签: c++ encryption xor


【解决方案1】:

我们看看:output[i] = str[i] ^ key;

它的作用是首先从索引i 的字符串str 中检索一个字符。 std::string 中的一个字符相当于一个 8 位字节。

然后这个字节被哄骗成一个long,使用一个隐式加宽转换来匹配左边的key

之后,所有位都与密钥进行异或运算,执行“加密”。我把它放在引号中是因为重复使用带有 XOR 密码的密钥当然是不安全的。

最后使用隐式窄化转换再次将这个 long 值赋给 char 数组。

换句话说,如果您明确转换,您可以将其视为执行:output[i] = (char) ((long) str[i] ^ key;。请注意,许多位首先被异或,然后在窄化转换期间被丢弃;可能不是您想要的,因为这些关键位基本上被忽略了。


当然,如果您与随机位进行异或运算,那么您得到的回报是随机二进制模式。这种模式可能不包含可打印的字符。您要么必须将它们作为二进制值存储或发送,要么必须首先将它们转换回可打印的文本。通常我们使用字节的十六进制或base 64编码来做到这一点。

现代密码学对位和字节进行操作。凯撒密码和维吉尼密码等经典密码确实对文本进行操作,并将文本作为输出。最后,XOR 是对位的操作,而不是对文本字符的操作。

【讨论】:

  • 感谢@Maarten 对整个过程的全面解释。
猜你喜欢
  • 2020-08-12
  • 2021-05-16
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 2011-01-03
相关资源
最近更新 更多