[英]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.