【发布时间】:2020-02-11 20:44:57
【问题描述】:
我尝试在 PHP 和 JS 中对两个字符串进行异或运算,得到了不同的结果:
PHP 函数
function xh($a, $b) {
$res = ""; $i = strlen($a); $j = strlen($b);
while($i-->0 && $j-->0) {
$res.= $a[$i] ^ $b[$j];
}
return base64_encode($res);
}
JS函数
function xh(a, b) {
var res = "", i = a.length, j = b.length;
while (i-->0 && j-->0) {
res+= String.fromCharCode(a.charCodeAt(i) ^ b.charCodeAt(j));
}
return btoa(res);
}
我检查了字节,发现PHP函数中的第六个字节总是为零,所以我将JS函数更新为
JS函数相当于PHP
function xh2(a, b) {
var res = "", i = a.length, j = b.length;
while (i-->0 && j-->0) {
res+= String.fromCharCode((a.charCodeAt(i) ^ b.charCodeAt(j)) & 95);
}
return btoa(res);
}
那么那个位发生了什么?
输入/输出示例:
string a: 5D41402ABC4B2A76B9719D911017C592
string b: FE2D010308A6B3799A3D9C728EE74244
PHP says: Bg0HVwBUVQkDDgcAVQRYWw8AUlBUVVtSUgIBBFUGAVM=
JS says: Bg0HdwB0dQkDDgcAdQR4ew8AcnB0dXtycgIBBHUGAXM=
JS2 says: Bg0HVwBUVQkDDgcAVQRYWw8AUlBUVVtSUgIBBFUGAVM=
本例中的第一个区别:
C: 0x43 = 0100 0011
4: 0x34 = 0011 0100
C^4 (JS) = 0111 0111 = 0x77 (correct)
C^4 (PHP)= 0101 0111 = 0x57
^
sixth bit wrong
输入是 MD5 哈希,我使用默认编码,我的 OEM 字符集是 CP1250,语言环境 cs-cz,文件以 UTF-8 编码存储,页面使用 HTTP 标头 text/html;charset=UTF- 生成8 和元标记 UTF-8(如果有任何这些问题)。
我的网络服务器是捆绑了 php 5.6 (cgi) 的 Mongoose 6.7。我还尝试了最新的 7.3(x86 和 x64),结果相同,但是 cmets 中的 @apokryfos tested it 第六位正确。
【问题讨论】:
-
-->这是什么黑魔法? -
@Dominic
(i--)>0 -
意思是
(i--)> 0 -
JS 和 PHP 脚本是否都使用相同的字符编码?当您使用 PHP strlen 函数时,我可以推断您正在使用 ASCII,或者您不知道 strlen 不适合多字节编码。
-
先尝试将字符串作为文字传递,不要让猫鼬参与其中,看看是否有帮助。
标签: javascript php xor mongoose-web-server