用于将电子邮件转换为MD5的更新语句未计算正确的结果

时间:2013-03-04 19:00:47

标签: sql sql-server-2008

我试图遍历我的数据库并使用MD5哈希我的电子邮件地址。这是我厌倦了使用的代码:

update Recipients set MD5Email = CONVERT(VARCHAR(MAX), HASHBYTES( 'md5', NonMd5.EmailAddress ), 2)
from 
 Recipients INNER JOIN Recipients as NonMd5
on 
 Recipients.Id = NonMd5.Id 

我也尝试了这个,结果相同:

update Recipients set MD5Email = CONVERT(VARCHAR(MAX), HASHBYTES( 'md5', Recipients.EmailAddress ), 2)
    from 
     Recipients

如果我用一个硬编码字符串替换NonMd5.EmailAddress,它会正确计算它。我不知道出了什么问题。

这是我的表:

CREATE TABLE [dbo].[Recipients] (
[Id] uniqueidentifier NOT NULL DEFAULT (newid()) ,
[EmailAddress] nvarchar(MAX) COLLATE Latin1_General_CI_AS NULL ,
[IsProcessed] bit NOT NULL ,
[MD5Email] nvarchar(80) COLLATE Latin1_General_CI_AS NULL ,
CONSTRAINT [PK__Recipien__3214EC0703317E3D] PRIMARY KEY ([Id])
)
ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO

更新

如果我将电子邮件地址设置为test@test.com,这是我的结果:4767DCA4A82B295C59D18097EE7B4070

在上面的代码中将其作为直接值运行,这是我的结果:

b642b4217b34b1e8d3bd915fc65c4452

1 个答案:

答案 0 :(得分:1)

如何:

UPDATE dbo.Recipients 
  SET MD5Email = CONVERT(NVARCHAR(80), HASHBYTES('MD5', EmailAddress), 2);

那说你真的应该考虑使用SHA或其他算法而不是MD5,你真的不应该将哈希输出存储为字符串 - 使用varbinary。

以下是我得到的结果:

SQLFiddle

现在有一个非常重要的区别,我认为你错过了。您当前正在将电子邮件地址存储为NVARCHAR(MAX) - 我不知道您为什么使用Unicode(世界上大多数服务器仍然不支持双字节字符),我不知道为什么你正在使用MAX。然而,比较这些:

SELECT CONVERT(NVARCHAR(80), HASHBYTES('MD5', 'test@test.com'), 2);

SELECT CONVERT(NVARCHAR(80), HASHBYTES('MD5', N'test@test.com'), 2);
----------- this N is very important ---------^

根据当前的SMTP标准,您的列可能为320个字符(域名为255个字符,本地部分为64个字符,加上@符号)而不是MAX(没有人有一个包含> 4000个字符的电子邮件地址,从不介意10亿个字符)。如果你真的需要支持Unicode电子邮件地址,你只需要NVARCHAR - 就像我说的那样,今天大多数邮件服务器都无法识别它们。如果更改数据类型,您将看到它与您的测试匹配。如果您使用NVARCHAR,则需要比较苹果和苹果,因此在运行测试时,请确保使用N为硬编码值添加前缀。