7

私のデータベースには、URLを保持するURLStringという列のSHA1ハッシュを含む計算列があります(例: "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でサポートされている限り)。

例:データベースでは、URLhttp://www.whatismyip.org/の自動的に計算されたSHA1値は0xAE66CA69A157186A511ED462153D7CA65F0C1BF7です。

4

4 に答える 4

10

文字エンコードの違いに悩まされる可能性があります。

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)、データベースが使用しているバイトを確認することができます。

于 2013-01-03T20:40:00.347 に答える
4

以下は、文字列とバイトのハッシュを行う2つのメソッドです。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

Microsoft 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 に答える