7

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

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

为了加快速度,我想从 C# 计算 SQL Server hashbytes('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。

4

4 回答 4

10

You're likely getting bitten by character encoding differences:

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

You could try getting the bytes via Encoding.ASCII.GetBytes(url) or Encoding.Unicode.GetBytes(url) and see which one your db is using.

于 2013-01-03T20:40:00.347 回答
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;
}
于 2013-01-03T20:28:42.680 回答
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();
}
于 2018-09-14T01:57:58.853 回答
0

微软 SQL Server 2008 (RTM) - 10.0.1600.22 (X64)

 DECLARE @inputString NVARCHAR(1000)
 set @inputString='Intel(R) Xeon(R) CPU           X5660  @ 2.80GHz  '
 DECLARE @outputHash VARBINARY(8000)
 SET @outputHash = HASHBYTES('SHA1', (@inputString))
 select  @outputhash

返回 0xAE325D7C3D7720846B42CDD488EBEE5D711CB1AE

C#

public string SQLServerSha1(string input) {
    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();
    return output;
    }

返回AE325D7C3D7720846B42CDD488EBEE5D711CB1AE

于 2021-08-15T18:52:19.627 回答