为什么这个简单的JavaScript XOR加密算法不起作用?

Ren*_*ato 4 javascript xor

我正在尝试用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;
}
Run Code Online (Sandbox Code Playgroud)

但是,以下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;
}
Run Code Online (Sandbox Code Playgroud)

测试案例如下:

Text: someRandomText
Key:  123456789
PHP output: B]^QgWY\V\fVLA
JS output:  12345678912345
Run Code Online (Sandbox Code Playgroud)

显然,^运营商在两种语言之间表现不同.

我发现了一些关于PHP和JavaScript ^运算符之间差异的问题,比如这个,这个或者这个,但我仍然无法解决这个问题.

为什么这个JavaScript算法没有按预期工作?


次要注释1:由于无法迭代字符串的字符并在JavaScript中逐个替换它们,因此我+=for循环中使用了运算符,以便将每个XOR运算的输出附加到result变量.

次要注2:为规范的字符集,函数实际上会返回base64_encode($result),并btoa(result)分别在PHP和JS.然后,为了解密它,decryptXor()函数必须result在迭代它们之前解码变量.尽管如此,由于这与问题无关,我简化了一些功能.在这种情况下,对于测试的例子,在text变量中仅使用字母数字字符并且在变量中仅使用数字key(反之亦然)更安全.

Nin*_*olz 7

您需要一些其他方法,例如String#charCodeAtString.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
Run Code Online (Sandbox Code Playgroud)

有点短版本

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
Run Code Online (Sandbox Code Playgroud)