如何计算C#中的SQL Server(hashbytes('SHA1',[ColumnName]))的等价物?

时间:2013-01-03 20:25:18

标签: c# sql-server tsql sha

在我的数据库中,我有一个计算列,其中包含一个名为URLString的列的SHA1哈希,该列包含URL(例如“http://xxxx.com/index.html”)。

我经常需要查询表以根据URLString列查找特定的URL。 该表包含100K,这些查询需要几秒钟(使用SQL Azure)。 由于URL可能很长,我无法在此列上创建索引(大于450字节)。

为了加快速度,我想从C#计算SQL Server哈希字节('SHA1',[URLString])的等效值,并根据此值进行查询。

我尝试了下面的代码,但是我获得的值与数据库计算的值不同。

var urlString = Encoding.ASCII.GetBytes(url.URLString); //UTF8 also fails
var sha1 = new SHA1CryptoServiceProvider();
byte[] hash = sha1.ComputeHash(urlString);

我在这里错过了一些小事吗? 我对其他可以解决相同问题的想法持开放态度(只要SQL Azure支持它们)。

示例:在数据库中,URL http://www.whatismyip.org/的自动计算SHA1值为0xAE66CA69A157186A511ED462153D7CA65F0C1BF7。

3 个答案:

答案 0 :(得分:9)

你可能会被字符编码差异所困扰:

http://weblogs.sqlteam.com/mladenp/archive/2009/04/28/Comparing-SQL-Server-HASHBYTES-function-and-.Net-hashing.aspx

您可以尝试通过Encoding.ASCII.GetBytes(url)Encoding.Unicode.GetBytes(url)获取字节,并查看您的数据库正在使用哪个字节。

答案 1 :(得分:4)

下面是两种对字符串和字节进行散列的方法。 HashBytes方法返回结果字节的Base64,但如果您愿意,则只返回字节

public static string HashString(string cleartext)
{
    byte[] clearBytes = Encoding.UTF8.GetBytes(cleartext);
    return HashBytes(clearBytes);
}  

public static string HashBytes(byte[] clearBytes)
{
    SHA1 hasher = SHA1.Create();
    byte[] hashBytes =   hasher.ComputeHash(clearBytes);
    string hash = System.Convert.ToBase64String(hashBytes);
    hasher.Clear();
    return hash;
}

答案 2 :(得分:1)

下面的代码等效于SQL Server的hashbytes('sha1')

using (SHA1Managed sha1 = new SHA1Managed()) {
    var hash = sha1.ComputeHash(Encoding.Unicode.GetBytes(input));
    var sb = new StringBuilder(hash.Length * 2);

    foreach (byte b in hash) {
        // can be "x2" if you want lowercase
        sb.Append(b.ToString("X2"));
    }

    string output = sb.ToString();
}