UTF-8 字符串的按位异或运算给出非 UTF-8 输出
Bitwise XOR operation on UTF-8 string gives non UTF-8 output
我已经构建了一个基本的 XOR 加密程序,它使用密钥加密 .txt 文件。它工作正常,但我希望文件即使在加密后也只包含 UTF-8 字符。目前,在文本编辑器中查看时,我得到这样的输出:
1GCh!/39hpj1GCCh
hpj1GjjCCCh!/3hpj~yGCC7fGGCChhpj1GjjCCCh!/3hpj~xGCC7fGGCChhpj1GjjCCCh!/3hpj~{GCC7fGGCChhpj1GjjCCCh!/3hpjyrGCC7fGGCChhpj1GjjCCCh!/3hpjyGCC7fGGCChhpj1GjjCCCh!/3hpjy|GCC7fGGCCh
hpj1GjjCCCh!/3hpjy}GCC7fGGCCh
hpj1GjjCCCh!/3hpj~zGCC7fGGCChhpj1GjjCCCh!/3hpjysGCC7fGGCChhpj1GjjCCCh!/3hpj{~GCC7fGGCChhpj1GjjCCCh!/3hpj{GCC7fGGCCh
hpj1GjjCCCh!/3hpj{|GCC7fGGCChhpj1GjjCCCh!/3hpj{}GCC7fGGCChhpj1GjjCCCh!/3hpjh=hGCC7fGGCChhpj1GjjCCCh!/3hpjh+hGCC7fGGCChhpj1GjjCCCh!/3hpjh9hGCC7fGGCCh
hpj1GjjCCCh!/3hpjh.hGCC7GC7G7G
这里有很多我认为是非 UTF 字符的结果。
是否可以执行按位异或运算以仅生成 UTF 字符?
作为参考,这是我的加密函数:
static std::string XORCrypt(std::string key, std::string data) {
for (size_t i = 0; i != data.size(); i++) {
data[i] ^= key[i % key.size()];
}
return data;
}
不,你不能。 UTF-8 序列中的每个字节都有一些固定的位和一些取决于字符的位。如果字节的高位为 0,则它是一个 ASCII 字符,您可以想象只对低 7 位 (*) 进行异或运算,但这会揭示哪些字符在原始字符中是 ASCII,这并不好。如果更改高位,则会完全破坏 UTF-8 编码。
此外,如果您可以发送一个已知的纯文本,那么简单的异或加密就会被破坏。
简单的建议是不要自己加密。
(*) 同理,高位设置更复杂
UTF8 具有可变字符长度,这意味着它将某些字节序列(1、2 或更多字节)定义为一些特定字符。有许多可能的字节组合,但只有其中的一个子集是有效的,例如可以看到这个子集 here。这里发生的是您一次只更改该序列中的一个字节。这可能不仅会改变单个字符,而且会随着序列现在变得不对齐而改变后面的更多字符。除此之外,您可能会生成一些根本不存在于 table 中的东西。因此,如果您想加密 UTF8 文本并且密码必须是 UTF8 可读的,您需要有适当的逻辑来识别 UTF 字符并以某种谓词 table 方式更改它们。
当然可以,只需将更改的位限制为最低 3 位即可。这是 UTF-8 中唯一对所有有效 UTF-8 代码单元都是任意的位区域。
您可以 运行 您的密钥通过扩展函数来延长它以满足该要求。
而且,如果您将措辞从 "encryption" 更改为 "obfuscation."
,我想我们都会感觉更舒服
我已经构建了一个基本的 XOR 加密程序,它使用密钥加密 .txt 文件。它工作正常,但我希望文件即使在加密后也只包含 UTF-8 字符。目前,在文本编辑器中查看时,我得到这样的输出:
1GCh!/39hpj1GCCh
hpj1GjjCCCh!/3hpj~yGCC7fGGCChhpj1GjjCCCh!/3hpj~xGCC7fGGCChhpj1GjjCCCh!/3hpj~{GCC7fGGCChhpj1GjjCCCh!/3hpjyrGCC7fGGCChhpj1GjjCCCh!/3hpjyGCC7fGGCChhpj1GjjCCCh!/3hpjy|GCC7fGGCCh
hpj1GjjCCCh!/3hpjy}GCC7fGGCCh
hpj1GjjCCCh!/3hpj~zGCC7fGGCChhpj1GjjCCCh!/3hpjysGCC7fGGCChhpj1GjjCCCh!/3hpj{~GCC7fGGCChhpj1GjjCCCh!/3hpj{GCC7fGGCCh
hpj1GjjCCCh!/3hpj{|GCC7fGGCChhpj1GjjCCCh!/3hpj{}GCC7fGGCChhpj1GjjCCCh!/3hpjh=hGCC7fGGCChhpj1GjjCCCh!/3hpjh+hGCC7fGGCChhpj1GjjCCCh!/3hpjh9hGCC7fGGCCh
hpj1GjjCCCh!/3hpjh.hGCC7GC7G7G
这里有很多我认为是非 UTF 字符的结果。
是否可以执行按位异或运算以仅生成 UTF 字符?
作为参考,这是我的加密函数:
static std::string XORCrypt(std::string key, std::string data) {
for (size_t i = 0; i != data.size(); i++) {
data[i] ^= key[i % key.size()];
}
return data;
}
不,你不能。 UTF-8 序列中的每个字节都有一些固定的位和一些取决于字符的位。如果字节的高位为 0,则它是一个 ASCII 字符,您可以想象只对低 7 位 (*) 进行异或运算,但这会揭示哪些字符在原始字符中是 ASCII,这并不好。如果更改高位,则会完全破坏 UTF-8 编码。
此外,如果您可以发送一个已知的纯文本,那么简单的异或加密就会被破坏。
简单的建议是不要自己加密。
(*) 同理,高位设置更复杂
UTF8 具有可变字符长度,这意味着它将某些字节序列(1、2 或更多字节)定义为一些特定字符。有许多可能的字节组合,但只有其中的一个子集是有效的,例如可以看到这个子集 here。这里发生的是您一次只更改该序列中的一个字节。这可能不仅会改变单个字符,而且会随着序列现在变得不对齐而改变后面的更多字符。除此之外,您可能会生成一些根本不存在于 table 中的东西。因此,如果您想加密 UTF8 文本并且密码必须是 UTF8 可读的,您需要有适当的逻辑来识别 UTF 字符并以某种谓词 table 方式更改它们。
当然可以,只需将更改的位限制为最低 3 位即可。这是 UTF-8 中唯一对所有有效 UTF-8 代码单元都是任意的位区域。
您可以 运行 您的密钥通过扩展函数来延长它以满足该要求。
而且,如果您将措辞从 "encryption" 更改为 "obfuscation."
,我想我们都会感觉更舒服