Хэширование строки с помощью Sha256
Я пытаюсь хэшировать строку с помощью SHA256, я использую следующий код:
using System;
using System.Security.Cryptography;
using System.Text;
public class Hash
{
public static string getHashSha256(string text)
{
byte[] bytes = Encoding.Unicode.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash)
{
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
}
однако этот код дает значительно отличающиеся результаты по сравнению с моими друзьями php, а также онлайн генераторами (например,этот генератор)
кто-нибудь знает, в чем ошибка? Разные основания?
3 ответов:
Encoding.UnicodeЭто вводящее в заблуждение имя Microsoft для UTF-16 (двойная кодировка, используемая в мире Windows по историческим причинам, но не используемая никем другим). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspxесли вы осмотрите
bytesмассив, вы увидите, что каждый второй байт0x00(из-за двойного кодирования).вы должны использовать .
но также, вы увидите различные результаты в зависимости от того, рассматриваете ли вы завершение
''байт, чтобы быть частью данных, которые вы хэширования. Хеширование двух байтов"Hi"даст другой результат от хеширования три байт"Hi". Вам придется решить, что вы хотите сделать. (Предположительно, вы хотите сделать то, что делает PHP-код вашего друга.)для текста ASCII,
Encoding.UTF8обязательно подойдет. Если вы стремитесь к идеальный совместимость с кодом вашего друга, даже на входах без ASCII, вам лучше попробовать несколько тестовых случаев с символами без ASCII, такими какéи家и посмотреть, совпадают ли ваши результаты по-прежнему. Если нет, вам придется выяснить, какую кодировку действительно использует ваш друг; это может быть одна из 8-битных "кодовых страниц", которые были популярны до изобретения Unicode. (Опять же, я думаю, что Windows является основной причиной того, что кому-то все еще нужно беспокоиться о "кодовых страницах".)
у меня также была эта проблема с другим стилем реализации, но я забыл, где я его получил, так как это было 2 года назад.
static string sha256(string randomString) { var crypt = new SHA256Managed(); string hash = String.Empty; byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString)); foreach (byte theByte in crypto) { hash += theByte.ToString("x2"); } return hash; }когда я ввожу что-то вроде
abcdefghi2013по какой-то причине это дает разные результаты и приводит к ошибкам в моем модуле входа. Затем я попытался изменить код так же, как предложил Quuxplusone и изменил кодировку сASCIIдоUTF8тогда это, наконец, сработало!static string sha256(string randomString) { var crypt = new System.Security.Cryptography.SHA256Managed(); var hash = new System.Text.StringBuilder(); byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString)); foreach (byte theByte in crypto) { hash.Append(theByte.ToString("x2")); } return hash.ToString(); }еще раз спасибо Quuxplusone за замечательный и подробный ответ! :)
в PHP версии вы можете отправить ' true 'в последнем параметре, но по умолчанию'false'. Следующий алгоритм эквивалентен хэш-функции PHP по умолчанию при передаче 'sha256' в качестве первого параметра:
public static string GetSha256FromString(string strData) { var message = Encoding.ASCII.GetBytes(strData); SHA256Managed hashString = new SHA256Managed(); string hex = ""; var hashValue = hashString.ComputeHash(message); foreach (byte x in hashValue) { hex += String.Format("{0:x2}", x); } return hex; }
Comments