Convertir HashBytes a VarChar

127

Quiero obtener el hash MD5 de un valor de cadena en SQL Server 2005. Hago esto con el siguiente comando:

SELECT HashBytes('MD5', 'HelloWorld')

Sin embargo, esto devuelve un valor VarBinary en lugar de un valor VarChar. Si intento convertirme 0x68E109F0F40CA72A15E05CC22786F8E6en un VarChar me sale en há ðô§*à\Â'†øælugar de 68E109F0F40CA72A15E05CC22786F8E6.

¿Hay alguna solución basada en SQL?

si

GateKiller
fuente

Respuestas:

147

He encontrado la solución más donde:

SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'HelloWorld')), 3, 32)
GateKiller
fuente
19
fn_varbintohexstr no es función documentada. Use CONVERT (Char, @ value, 2)
Cheburek el
Varbinary acaba de morderme porque necesitaba una forma de actualización en el almacén. ¡Funcionó como por arte de magia! gracias ...
nitefrog
Este método es muy lento, usa una función no documentada y no funciona en Azure. No es genial Utilice Convertir en su lugar!
Rocklan
44
CONVERT () no funciona en SQL 2005. Si está utilizando SQL 2008 o superior, use CONVERT () todo lo que desee. Lamentablemente, no conozco un solo comando que funcione para todas las versiones de SQL, por lo tanto, haga una revisión loca de la versión en su script o simplemente anote en alguna parte que necesita corregir la función si actualiza las versiones de SQL.
Carl Bussema
55
CONVERT (Char, @ value, 2) solo genera 32 bytes: si hace esto en un hash sha1, lo truncará, necesita convertir (char (48), @ value, 2) para mantener la salida adecuada.
Andrew Hill
82
SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'Hello World'),2)
Rapscallion
fuente
44
Esto funciona en SQL Azure. SHA1: SELECT CONVERT (VARCHAR (40), HashBytes ('SHA1', 'Hello World'), 2)
Raptor
44
No es necesario usar nvarchar innecesariamente.
Ian Kemp
3
La pregunta indica SQL Server 2005 y si hace alguna de las sugerencias anteriores (y probablemente también cualquier otra versión), no hacen lo que se les pide. Obtiene el carácter al que equivalen los bytes, no los bytes como una cadena hexadecimal, que es lo que se solicita. GateKiller y Xarqron dan respuestas que funcionan.
David Knight
¿Dónde puedo leer sobre estos estilos de conversión? 2 en este caso que se pasa como parámetro. ¿Y cómo hacer un equivalente de eso en el código C #? ¿Qué codificación debo elegir?
Dmytro Zhluktenko
31

Use en master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', @input), 1, 0)lugar de master.dbo.fn_varbintohexstry luego substringingel resultado.

De hecho fn_varbintohexstrllama fn_varbintohexsubstringinternamente. El primer argumento de fn_varbintohexsubstringle dice que agregue 0xFcomo prefijo o no. fn_varbintohexstrllamadas fn_varbintohexsubstringcon1 el primer argumento interno.

Porque no necesitas 0xF, llama fn_varbintohexsubstringdirectamente.

Xaqron
fuente
27

Al contrario de lo que dice David Knight , estas dos alternativas devuelven la misma respuesta en 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))

Parece que la primera es una mejor opción, a partir de la versión 2008.

Timo Riikonen
fuente
¡No escriba esto por error que da una respuesta sutilmente diferente! ... convert (varchar, HashBytes ('MD5', 'Hello World')), 2)
andrew pate
13
convert(varchar(34), HASHBYTES('MD5','Hello World'),1)

(1 para convertir hexadecimal a cadena)

Convierta esto para reducir y eliminar 0x desde el inicio de la cadena subcadena:

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

exactamente lo mismo que obtenemos en C # después de convertir bytes a cadena

Ramans
fuente
2

Con la experiencia personal de usar el siguiente código dentro de un Procedimiento almacenado que modifica una variable SP, puedo confirmar, aunque no está documentado, esta combinación funciona al 100% según mi ejemplo:

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

Cambiar el tipo de datos a varbinary parece funcionar mejor para mí.

anopres
fuente