Перетворити HashBytes у VarChar


127

Я хочу отримати хеш MD5 значення рядка в SQL Server 2005. Я роблю це за допомогою наступної команди:

SELECT HashBytes('MD5', 'HelloWorld')

Однак це повертає VarBinary замість значення VarChar. Якщо я спробую перетворити 0x68E109F0F40CA72A15E05CC22786F8E6на VarChar, я отримаю há ðô§*à\Â'†øæзамість 68E109F0F40CA72A15E05CC22786F8E6.

Чи є рішення, засновані на SQL?

Так

Відповіді:


147

Я знайшов рішення ще де:

SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'HelloWorld')), 3, 32)

19
fn_varbintohexstr не є документально підтвердженою функцією. Використовуйте CONVERT (Char, @ value, 2)
Чебурек

Мене просто покусав варбінар, як мені потрібен спосіб оновлення на склад. Це спрацювало як шарм! дякую ...
nitefrog

Цей метод дуже повільний, використовує недокументовану функцію і не працює в Azure. Не круто. Використовуйте конвертувати замість цього!
Rocklan

4
CONVERT () не працює в SQL 2005. Якщо ви використовуєте SQL 2008 або вище, використовуйте CONVERT () все, що вам потрібно. На жаль, я не знаю жодної команди, яка буде працювати для всіх версій SQL, тому або виконайте деяку шалену перевірку версій у вашому сценарії, або просто десь зазначайте, що вам потрібно виправити цю функцію, якщо ви оновлюєте версії SQL.
Карл Буссема

5
CONVERT (Char, @ значення, 2) виводить лише 32 байти - якщо ви зробите це до хешу sha1, ви будете усікати його, вам потрібно конвертувати (char (48), значення @, 2), щоб зберегти відповідний вихід.
Ендрю Хілл

82
SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'Hello World'),2)

4
це працює в SQL Azure. для SHA1: SELECT CONVERT (VARCHAR (40), HashBytes ('SHA1', 'Hello World'), 2)
Raptor

4
Не потрібно використовувати nvarchar без потреби.
Ян Кемп

3
У запитанні йдеться про SQL Server 2005, і якщо ви робите будь-яку із запропонованих вище пропозицій (і, мабуть, будь-яку іншу версію), вони не виконують те, що просять. Ви отримуєте будь-який символ, який байтам еквівалентний, а не байтам як шістнадцятковий рядок, про що вимагається. GateKiller і Xarqron дають відповіді, які працюють.
Давид Найт

Де я можу прочитати про ці стилі перетворення? 2 у цьому випадку, який передається як параметр. І як зробити еквівалент цього в C # коді? Яке кодування слід вибрати?
Дмитро Жлуктенко

31

Використовуйте master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', @input), 1, 0)замість, master.dbo.fn_varbintohexstrа потім substringingрезультат.

Фактично fn_varbintohexstrдзвінки fn_varbintohexsubstringвнутрішньо. Перший аргумент fn_varbintohexsubstringговорить про те, щоб додати 0xFяк префікс чи ні. fn_varbintohexstrвиклики fn_varbintohexsubstringз 1першим аргументом internaly.

Оскільки вам не потрібно 0xF, телефонуйте fn_varbintohexsubstringбезпосередньо.


27

Всупереч сказаному Девідом Найтом , ці дві альтернативи повертають ту саму відповідь у MS SQL 2008:

SELECT CONVERT(VARCHAR(32),HashBytes('MD5', 'Hello World'),2)
SELECT UPPER(master.dbo.fn_varbintohexsubstring(0, HashBytes('MD5', 'Hello World'), 1, 0))

Тож схоже, що перший - кращий вибір, починаючи з версії 2008 року.


Не вводьте це помилково, що дає тонко іншу відповідь! ... convert (varchar, HashBytes ('MD5', 'Hello World')), 2)
andrew pate

13
convert(varchar(34), HASHBYTES('MD5','Hello World'),1)

(1 для перетворення шістнадцяткової у рядок)

конвертуйте це в нижній і видаліть 0x із початку рядка за допомогою підрядка:

substring(lower(convert(varchar(34), HASHBYTES('MD5','Hello World'),1)),3,32)

точно так само, як ми отримуємо в C # після перетворення байтів у рядок


2

Маючи особистий досвід використання наступного коду в Збереженій процедурі, яка має хід змінної SP, я можу підтвердити, хоч і без документації, ця комбінація працює на 100% відповідно до мого прикладу:

@var=SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA2_512', @SPvar)), 3, 128)

-3

Зміна типу даних на varbinary, здається, працює найкраще для мене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.