Преобразовать HashBytes в VarChar

Я хочу получить хэш MD5 строкового значения в SQL Server 2005. Я делаю это с помощью следующей команды:

SELECT HashBytes('MD5', 'HelloWorld')

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

Есть ли какое-нибудь решение на базе SQL?

да

Ответов (7)

Решение

Я нашел решение еще где:

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

Мне кажется, что лучше всего подойдет изменение типа данных на varbinary.

SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'Hello World'),2)
convert(varchar(34), HASHBYTES('MD5','Hello World'),1)

(1 для преобразования шестнадцатеричного числа в строку)

преобразуйте это в меньшее и удалите 0x из начала строки с помощью подстроки:

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

точно так же, как то, что мы получаем в C# после преобразования байтов в строку

Имея личный опыт использования следующего кода в хранимой процедуре, которая хеширует переменную SP, я могу подтвердить, хотя и недокументированная, эта комбинация работает на 100%, как в моем примере:

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

Используйте 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 напрямую.

Вопреки тому, что говорит Дэвид Найт , эти две альтернативы возвращают одинаковый ответ в 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 года.