I am trying to develop a (very) simple XOR encryption algorithm in JavaScript.
In PHP, the following encryption algorithm works as expected:
function encryptXor($text, $key) {
$result = '';
for ($i = 0; $i < strlen($text); $i++)
$result[$i] = $text[$i] ^ $key[$i % strlen($key)];
return $result;
}
However, the following JavaScript algorithm does not work properly:
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;
}
A test case follows:
Text: someRandomText
Key: 123456789
PHP output: B]^QgWY\V\fVLA
JS output: 12345678912345
Apparently, the ^
operator is behaving differently between the two languages.
I have found some questions regarding the difference between PHP's and JavaScript's ^
operators, such as this one, this one or this one, but I still could not resolve this issue.
Why is this JavaScript algorithm not working as expected?
Minor note 1: Since it is not possible to iterate over the characters of a string and replace them one by one in JavaScript, I used the +=
operator inside the for
loop in order to append the output of each XOR operation to the result
variable.
Minor note 2: In order to normalize the character set, the functions actually return base64_encode($result)
and btoa(result)
in PHP and JS, respectively. Then, in order to decrypt it, the decryptXor()
functions have to decode the result
variables before iterating over them. Nonetheless, since this is not relevant to the question, I simplified the functions a bit. In this case, for the purpuses of testing, it is safer to use only alphanumeric characters in the text
variable and only numerals in the key
variable (or vice-versa).
You need some other methods, like String#charCodeAt
or String.fromCharCode
for getting the same result.
The main problem is, you need a numerical value instead of the character/string.
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
A bit shorter version
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With