Создайте хеш PHP UTF-16 SHA1 для соответствия методу C # - PullRequest
2 голосов
/ 19 августа 2010

Я пытаюсь скопировать некоторый код C # в PHP5, и у меня возникли некоторые трудности.

Код C # выглядит следующим образом, и важно отметить, что его нельзя изменить:

string s = strToHash;
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] bytes = encoding.GetBytes(s);
SHA1Managed managed = new SHA1Managed();     
bytes = encoding.GetBytes(Convert.ToBase64String(managed.ComputeHash(bytes)) + "Space");
return Convert.ToBase64String(managed.ComputeHash(bytes));

PHP-код, который я написал для повторения, выглядит следующим образом:

utfString = mb_convert_encoding($strToHash,"UTF-16");
hashTag = sha1($utfString,true); 
base64Tag = base64_encode($hashTag); 
encodedBase64Tag = mb_convert_encoding($base64Tag."Space","UTF-16");
base64EncodedAgain = base64_encode($encodedBase64Tag);

echo $base64EncodedAgain

Однако два выхода не совпадают. Я считаю, что это потому, что метод SHA1 в PHP работает на ASCII-кодированных строках, а не на кодировке, фактически используемой переданной строкой.

Я бы хотел, чтобы это сработало, и я не могу добиться этого, изменив код c # (хотя, без сомнения, это было бы самым простым решением).

Пожалуйста, можете посоветовать какие-нибудь идеи?


ОК, я изменил код, следуя совету Артефакто, и он все еще не работает должным образом.

Код PHP теперь выглядит следующим образом:

$utfString = "\xFF\xFE".mb_convert_encoding($strToHash,"UTF-16LE");
$hashTag = sha1($utfString,true);       
$base64Tag = base64_encode($hashTag);   
$encodedBase64Tag = "\xFF\xFE".mb_convert_encoding($base64Tag."Space","UTF-16LE");  
$hashedAgain = sha1($encodedBase64Tag,true);
$base64EncodedAgain = base64_encode($hashedAgain);

echo $base64EncodedAgain."<Br/>";

И расчетная стоимость этого метода:

* * 1 тысячу двадцать-три / Y5MCzI8vDJqc456YIicpwoyy0 =

Однако из кода C # это значение:

VPf7BhT1ksAfWbzeJw35g + bVKwY =

Ответы [ 3 ]

2 голосов
/ 19 августа 2010

Документы для конструктора без аргументов из UnicodeEncoding говорят:

Этот конструктор создает экземпляр, который использует порядок байтов с прямым порядком байтов, предоставляет метку порядка байтов в Юникоде и не выдает исключение при обнаружении неверной кодировки.

Теперь mb_convert_encoding принимает "UTF-16" как "UTF-16BE" (big-endian). Это также не обеспечивает спецификацию. Таким образом, вы должны сделать вместо:

$utfString = "\xFF\xFE" . mb_convert_encoding($strToHash,"UTF-16LE");
/* ...*/
$encodedBase64Tag = "\xFF\xFE" . mb_convert_encoding($base64Tag."Space","UTF-16LE");

Как указала Paja , вы также пропускаете звонок на sha1.

2 голосов
/ 19 августа 2010

Ну, попробуйте этот код:

$utfString = mb_convert_encoding($strToHash,"UTF-16");
$hashTag = sha1($utfString,true); 
$base64Tag = base64_encode($hashTag); 
$encodedBase64Tag = mb_convert_encoding($base64Tag."Space","UTF-16");
$base64EncodedAgain = base64_encode(sha1($encodedBase64Tag, true));

echo $base64EncodedAgain

Потому что вы пропускаете один sha1 звонок.

Обновление

Теперь этот код должен работать:

$utfString = mb_convert_encoding($strToHash,"UTF-16LE");
$hashTag = sha1($utfString,true);       
$base64Tag = base64_encode($hashTag);   
$encodedBase64Tag = mb_convert_encoding($base64Tag."Space","UTF-16LE");  
$hashedAgain = sha1($encodedBase64Tag,true);
$base64EncodedAgain = base64_encode($hashedAgain);
echo $base64EncodedAgain . "<br />";
0 голосов
/ 21 марта 2019
  1. Этот код должен работать ...

    $utfString = mb_convert_encoding($strToHash,"UTF-16LE");
    $hashTag = sha1($utfString,true);
    $base64Tag = base64_encode($hashTag);
    echo $base64Tag;
    
...