使用T-SQL生成MD5哈希字符串

133

有没有一种方法可以生成类型为varchar(32)的MD5哈希字符串,而不使用fn_varbintohexstr?

SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'email@dot.com')), 3, 32)

因此它可以在具有SCHEMABINDING的视图中使用。


请参见 https://dev59.com/ZZPfa4cB1Zd3GeqPHL2L#35289890。 - Ben
10个回答

243
CONVERT(VARCHAR(32), HashBytes('MD5', 'email@dot.com'), 2)

你如何在SQL2005中实现这个?它没有正确返回编码字符串...? - Joshua F. Rountree
@JoshuaRountree,请看我在https://dev59.com/wXA75IYBdhLWcg3wAD_x#28903685 的答案。 - deldev

79

使用 HashBytes 函数。

SELECT HashBytes('MD5', 'email@dot.com')

这将给你0xF53BD08920E5D25809DF2563EF9C52B6。

-

SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'email@dot.com'),2)

这将给你 F53BD08920E5D25809DF2563EF9C52B6


1
@Brendan,你在结尾处漏掉了",2)"。 - Ryan Elkins
1
@RyanElkins 我得到了和Brendan相同的结果,我肯定包括了",2)" :( - Matthew

20

解决方案:

SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5','your text')),3,32)

19

其他答案对我都不适用。请注意,如果您传入硬编码的字符串与从结果集中的列中提取数据结果将有所不同。以下是对我有效的方法,可以在SQL Server和MySQL之间实现完全匹配。

select LOWER(CONVERT(VARCHAR(32), HashBytes('MD5', CONVERT(varchar, EmailAddress)), 2)) from ...

1
只有在区分大小写的情况下才需要使用 LOWER() - T.Coutlakis
第一次转换非常重要。这会产生与PostgresqlMD5()函数相同的MD5哈希值。我曾经想知道为什么PythonPostgresqlMD5哈希值不同。感谢您提供的方法。 - Ben

18

对于长度不超过8000个字符的数据,请使用:

CONVERT(VARCHAR(32), HashBytes('MD5', 'email@dot.com'), 2)

演示

对于二进制数据(没有8000字节的限制),请使用:

CONVERT(VARCHAR(32), master.sys.fn_repl_hash_binary(@binary_data), 2)

演示


5

试试这个:

select SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5',  'email@dot.com' )),3,32) 

1

再次强调,大多数解决方案都不能正常工作,因此我们经过仔细测试,使用10个不同的文本列的组合来返回唯一的结果(关键更改:将其转换为varchar(X),其中x是您字符串的最大长度<4000,对于更长的字符串,请使用其他方法):

LOWER(CONVERT(VARCHAR(32), HashBytes('MD5', CONVERT(varchar(4000), EmailAddress)), 2))

1
SELECT CONVERT(
      VARCHAR(32),
      HASHBYTES(
                   'MD5',
                   CAST(prescrip.IsExpressExamRX AS VARCHAR(250))
                   + CAST(prescrip.[Description] AS VARCHAR(250))
               ),
      2
  ) MD5_Value;

适用于我。

1

如果您没有明确说明要将字符串转换为十六进制,而且您可以接受更节省空间的 base 64 字符串编码,并且您使用的是 SQL Server 2016 或更高版本,则有一种替代方案:

select SubString(h, 1, 32) from OpenJson(
    (select HashBytes('MD5', 'email@dot.com') h for json path)
) with (h nvarchar(max));

这句话的意思是:这将产生:
9TvQiSDl0lgJ3yVj75xStg==

无法工作:“关键字'with'附近的语法不正确。如果此语句是公共表达式、xmlnamespaces子句或更改跟踪上下文子句,则前一语句必须以分号终止。” - symbiont
@symbiont 你必须在具有更高支持级别的数据库中才能使用;它不会在较旧的版本或主分支中工作。 - N8allan

0
declare @hash nvarchar(50)
--declare @hash varchar(50)

set @hash = '1111111-2;20190110143334;001'  -- result a5cd84bfc56e245bbf81210f05b7f65f
declare @value varbinary(max);
set @value = convert(varbinary(max),@hash);


select  
 SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5', '1111111-2;20190110143334;001')),3,32) as 'OK'
,SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5', @hash)),3,32) as 'ERROR_01'
,SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5',convert(varbinary(max),@hash))),3,32) as 'ERROR_02'
,SUBSTRING(sys.fn_sqlvarbasetostr(sys.fn_repl_hash_binary(convert(varbinary(max),@hash))),3,32)
,SUBSTRING(sys.fn_sqlvarbasetostr(master.sys.fn_repl_hash_binary(@value)),3,32)

1
解决方案... 声明 @hash varchar(50) https://md5.gromweb.com/?string=1111111-2%3B20190110143334%3B001 - fernando yevenes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接