[英]Why is this simple JavaScript XOR encryption algorithm not working?
我正在尝试用JavaScript开发一个( 非常 )简单的XOR加密算法。
在PHP中,以下加密算法按预期工作:
function encryptXor($text, $key) {
$result = '';
for ($i = 0; $i < strlen($text); $i++)
$result[$i] = $text[$i] ^ $key[$i % strlen($key)];
return $result;
}
但是,以下JavaScript算法无法正常工作:
function encryptXor(text, key) {
var result = '';
for(var i = 0; i < text.length; i++)
result += text.charAt(i) ^ key.charAt(i % key.length);
return result;
}
测试案例如下:
Text: someRandomText
Key: 123456789
PHP output: B]^QgWY\V\fVLA
JS output: 12345678912345
显然, ^
运算符在两种语言之间表现不同。
我发现了一些关于PHP和JavaScript的^
运算符之间的区别的问题,比如这个 , 这个或者这个 ,但我仍然无法解决这个问题。
为什么这个JavaScript算法没有按预期工作?
次要注释1:由于无法迭代字符串的字符并在JavaScript中逐个替换它们,因此我在for
循环中使用了+=
运算符,以便将每个XOR运算的输出附加到result
变量。
次要注释2:为了规范化字符集,函数实际上分别在PHP和JS中返回base64_encode($result)
和btoa(result)
。 然后,为了解密它, decryptXor()
函数必须在迭代它们之前解码result
变量。 尽管如此,由于这与问题无关,我简化了一些功能。 在这种情况下,对于测试的例子,在text
变量中仅使用字母数字字符并且仅在key
变量中使用数字(反之亦然)更安全。
您需要一些其他方法,如String#charCodeAt
或String.fromCharCode
来获得相同的结果。
主要问题是,您需要一个数值而不是字符/字符串。
function encryptXor(text, key) { var result = ''; for (var i = 0; i < text.length; i++) { result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length)); } return result; } console.log(encryptXor('someRandomText', '123456789')); // B]^QgWY\\V\\fVLA
有点短版本
function encryptXor(text, key) { return Array.from( text, (c, i) => String.fromCharCode(c.charCodeAt() ^ key.charCodeAt(i % key.length)) ).join(''); } console.log(encryptXor('someRandomText', '123456789')); // B]^QgWY\\V\\fVLA
您的主要问题是您使用charAt而不是charCodeAt 。 'someRandomText'.charAt(0)
计算为's'
。 's' ^ x === x
,因为^
运算符尝试将两个操作数转换为数字而Number('s')
是NaN
。 因此,当你使用除数字之外的任何字符xor时,你只需得到键的值。
关于注1,您还有另一个问题:您不能只是附加到字符串。 如果你的算法导致字符串'567',则无法知道它是否是通过连接'56'和'7'或'5'和'67'创建的。 随着字符串变长,这成为一个更大的问题。 您可以使用数组而不是字符串或将每个子字符串保留为零填充到相同的长度,或者如Nina建议的那样,您可以将XOR的结果转换回使用String.fromCharCode的单个字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.