2011-10-14 43 views

回答

5

您可以散列輸入的8k(或4k或2k)塊,然後連接這些散列或將它們散列爲新的散列值。這可能會很困難,但是如果您必須創建一個類似的算法(例如在外部.NET應用程序中)來比較在SQL Server之外創建的哈希值。

另一種選擇:依靠SQL Server的CLR integration並在.NET程序集中執行散列。

+1

感謝Paul,這是一個非常好的內部使用解決方案。但在這種情況下,它必須完全符合sha1 – SDReyes

+1

@SDReyes:添加到我的答案的另一個想法:依靠SQL Server的CLR集成並在.NET程序集中執行哈希。 –

2

與Paul的想法一樣,想到分塊的想法之一是將散列的字符串存儲在XML列中,並將每個塊存儲爲單獨的XML元素。

+0

+1好主意,但爲了數據完整性,我建議存儲一個散列值(哈希散列)。使用XML結構,您需要一個額外的屬性,將散列值映射到第N個塊的索引散列的數據。 –

9

你可以寫一個SQL CLR函數:

[Microsoft.SqlServer.Server.SqlFunction] 
public static SqlBinary BigHashBytes(SqlString algorithm, SqlString data) 
{ 
    var algo = HashAlgorithm.Create(algorithm.Value); 

    var bytes = Encoding.UTF8.GetBytes(data.Value); 

    return new SqlBinary(algo.ComputeHash(bytes)); 
} 

然後它可以在SQL這樣調用:

--these return the same value 
select HASHBYTES('md5', 'test stuff') 
select dbo.BigHashBytes('md5', 'test stuff') 

BigHashBytes是唯一必要的,如果長度將超過8K。

+7

小心CLR SP參數被無聲地截斷爲8000字節 - 我必須用'[SqlFacet(MaxSize = -1)]'標記參數,否則8000th之後的字節將被忽略!花了我一段時間纔得到那個! – randomdude

+0

-1誤導讀者(當然,無意中)使用UTF-8。 SQL Server(和Windows一般)使用UTF-16。因此,這似乎適用於目前僅使用代碼點0 - 127,或可能高達256的許多人。但使用UTF-8會導致如下問題:[基於.net的SQL CLR函數ComputeHash不是使用Cyrrilic](http://stackoverflow.com/a/35273859/577765) –

+0

@randomdude您的經驗是由於SSDT的舊版本如何生成T-SQL包裝器對象。默認情況下,對'SqlString'使用'NVARCHAR(4000)',對'SqlChars'使用'NVARCHAR(MAX)'。但是從Visual Studio 2013開始,默認情況下就改爲使用'NVARCHAR(MAX)'。不過,正如你所提到的那樣,最好是明確地使用'[SqlFacet()]',但使用較新的SSDT版本的人不會遇到這種情況。此外,SQLCLR僅支持'NVARCHAR',因此它實際上會截斷爲4000個字符:-)。 –

相關問題