我尝试在php中复制这个C#code以获得相同的输出(我无法更改c#代码只有php)。在这里我被卡住了
public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
return System.Text.Encoding.Unicode.GetString(byteHashValue);
}
我到目前为止制作的php代码看起来像这样
$a = "test";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a,true);
$a = unpack('C*', $a);
var_dump($a);
//with the output
array(16) { [1]=> int(200) [2]=> int(5) [3]=> int(158) [4]=> int(46) [5]=> int(199) [6]=> int(65) [7]=> int(159) [8]=> int(89) [9]=> int(14) [10]=> int(121) [11]=> int(215) [12]=> int(241) [13]=> int(183) [14]=> int(116) [15]=> int(191) [16]=> int(230) }
正如您所看到的,输出与C#code中的输出相同
但是我坚持使用System.Text.Encoding.Unicode.GetString()函数。如何在php中复制它?或者有更简单的方法来获得相同的输出?(我无法更改C#代码抱歉)
编辑:基于Vasiliy Zverev的答案,因为php哈希有点不同。我最终用C#hash
function validare_parola($parola,$dbHash){
$parola = mb_convert_encoding($parola, "UTF-16LE");
$parola = md5($parola, true);
$parola = mb_convert_encoding($parola, "UCS-2BE", "UCS-2LE");
$parola = bin2hex($parola);
$procent;
similar_text($dbHash,$parola,$procent);
if($procent>=90){
return true;
}else{
return false;
}
}
$parola = "testa";
$dbHash = "10095018710be2bcbbf9bba3f9d91ce8";
if(validare_parola($parola,$dbHash)){
echo 'PASSWORD CORRECT.You can log in.';
}else{
echo 'INCORRECT PASSWORD.Try again.';
}
作为旁注,请勿使用md5代码来使用php password hashing api
Edit2:我最终使用了Vasiliy Zverev解决方案。
Edit3:对于值“111111”,php中有不同的输出...
Edit4: Vasily Zverev更新了他的解决方案,现在正按预期工作
答案 0 :(得分:2)
删除了此变体,因为它错了。请参阅上面的正确代码。
答案 1 :(得分:2)
解决方案已更新:
$a = "SF0D9G9SGGF0gdsfg976590";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a, true);
$res = '';
for($i=0; $i<16; $i+=2) {
// System.Text.Encoding.Unicode.GetString(byteHashValue) replaces invalid characters to 0xfffd ('я')
// while PHP to 0x003d ('?') or empty string. So replace them like C# does
$a2 = mb_convert_encoding($a[$i].$a[$i+1], "UTF-16LE","UTF-16LE"); // check if this is invalid UTF-16 character
if(strlen($a2)==0 || $a[$i]!=$a2[0]) {
// replace invalid UTF-16 character with C# like
$v = 0xfffd;
}
else {
// prepare a word (UTF-16 character)
$v = ord($a[$i+1])<<8 | ord($a[$i]);
}
// print each word without leading zeros as C# code does
$res .= sprintf("%x",$v);
}
echo($res);