Преобразовать 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 - это недокументированная функция. Use CONVERT (Char, @ value, 2)
— Чебурек

Я только что получил от varbinary, так как мне нужен способ обновления на складе. Это сработало как шарм! спасибо ...
— nitefrog

Этот метод очень медленный, использует недокументированную функцию и не работает в Azure. Не круто. Вместо этого используйте Convert!
— Rocklan

4
CONVERT () не работает в SQL 2005. Если вы используете SQL 2008 или более позднюю версию, используйте CONVERT () сколько угодно. К сожалению, я не знаю ни одной команды, которая будет работать для всех версий SQL, поэтому либо сделайте сумасшедшую проверку версии в своем скрипте, либо просто отметьте где-нибудь, что вам нужно исправить эту функцию, если вы обновляете версии SQL.
— Карл Буссема,

5
CONVERT (Char, @ value, 2) выводит только 32 байта - если вы сделаете это для хэша sha1, вы его усечете, вам нужно convert (char (48), @ value, 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первым внутренним аргументом.

Поскольку вам это не нужно 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.