Conversão HashBytes para VarChar

127

Desejo obter o hash MD5 de um valor de seqüência de caracteres no SQL Server 2005. Faço isso com o seguinte comando:

SELECT HashBytes('MD5', 'HelloWorld')

No entanto, isso retorna um VarBinary em vez de um valor VarChar. Se eu tentar converter 0x68E109F0F40CA72A15E05CC22786F8E6em um VarChar, em há ðô§*à\Â'†øævez de 68E109F0F40CA72A15E05CC22786F8E6.

Existe alguma solução baseada em SQL?

sim

GateKiller
fonte

Respostas:

147

Encontrei a solução em outro lugar:

SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'HelloWorld')), 3, 32)
GateKiller
fonte
19
fn_varbintohexstr não está documentada. Use CONVERT (Char, @ value, 2)
Cheburek
Acabei de me entender por varbinary, pois precisava de uma maneira de atualizar o warehouse. Isso funcionou como um encanto! Obrigado ...
nitefrog
Este método é muito lento, usa uma função não documentada e não funciona no Azure. Não é legal. Use Converter em vez disso!
Rocklan
4
CONVERT () não funciona no SQL 2005. Se você estiver usando o SQL 2008 ou superior, use CONVERT () tudo o que quiser. Infelizmente, não conheço um único comando que funcione para todas as versões do SQL; portanto, faça alguma verificação maluca de versão no seu script ou apenas anote em algum lugar que você precisa corrigir a função se atualizar as versões do SQL.
Carl Bussema
5
CONVERT (Char, @ value, 2) gera apenas 32 bytes - se você fizer isso com um hash sha1, você o truncará, precisará converter (char (48), @ value, 2) para manter a saída apropriada.
Andrew Hill
82
SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'Hello World'),2)
Rapscallion
fonte
4
isso funciona no SQL Azure. para SHA1: SELECT CONVERT (VARCHAR (40), HashBytes ('SHA1', 'Hello World'), 2)
Raptor
4
Não há necessidade de usar o nvarchar desnecessariamente.
31812 Ian Kemp
3
A pergunta indica o SQL Server 2005 e, se você seguir uma das sugestões acima (e provavelmente qualquer outra versão), elas não farão o que é solicitado. Você obtém qualquer caractere ao qual os bytes sejam equivalentes, não os bytes como uma sequência hexadecimal que é solicitada. GateKiller e Xarqron dão respostas que funcionam.
David Cavaleiro
Onde posso ler sobre esses estilos de conversão? 2 , neste caso, que é passado como parâmetro. E como fazer um equivalente ao código C #? Qual codificação devo escolher?
Dmytro Zhluktenko
31

Use em master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', @input), 1, 0)vez de master.dbo.fn_varbintohexstre, em seguida, substringingo resultado.

De fato fn_varbintohexstrchama fn_varbintohexsubstringinternamente. O primeiro argumento de fn_varbintohexsubstringdiz para adicionar 0xFcomo prefixo ou não. fn_varbintohexstrchama fn_varbintohexsubstringcom 1como o primeiro argumento internamente.

Porque você não precisa 0xF, ligue fn_varbintohexsubstringdiretamente.

Xaqron
fonte
27

Ao contrário do que David Knight diz, essas duas alternativas retornam a mesma resposta no 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))

Portanto, parece que o primeiro é uma escolha melhor, a partir da versão 2008.

Timo Riikonen
fonte
Não digite isso por engano, o que dá uma resposta sutilmente diferente! ... convert (varchar, HashBytes ('MD5', 'Hello World')), 2)
andrew pate
13
convert(varchar(34), HASHBYTES('MD5','Hello World'),1)

(1 para converter hexadecimal em string)

converta isso para abaixar e remova 0x do início da cadeia de caracteres por substring:

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

exatamente o mesmo que obtemos em c # depois de converter bytes em string

Ramans
fonte
2

Com a experiência pessoal de usar o seguinte código em um Procedimento Armazenado que Hashed uma Variável SP, posso confirmar, embora não documentada, essa combinação funciona 100% conforme meu exemplo:

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

Alterar o tipo de dados para varbinary parece funcionar melhor para mim.

anopres
fonte