C# 如何计算C中与SQL Server(hashbytes('SHA1',[ColumnName])的等价物?
在我的数据库中,我有一个计算列,其中包含一个名为URLString的列的SHA1散列,该列保存URL,例如。http://xxxx.com/index.html. 我经常需要查询表以根据URLString列查找特定的URL。 该表包含100K,使用SQLAzure进行这些查询需要几秒钟。 由于URL可能相当长,因此我无法在此列上创建超过450字节的索引 为了加快速度,我想计算SQL Server hashbytes'SHA1'、[URLString]与C的等价值,并基于此值进行查询 我尝试了下面的代码,但得到的值与数据库计算的值不同C# 如何计算C中与SQL Server(hashbytes('SHA1',[ColumnName])的等价物?,c#,sql-server,tsql,sha,C#,Sql Server,Tsql,Sha,在我的数据库中,我有一个计算列,其中包含一个名为URLString的列的SHA1散列,该列保存URL,例如。http://xxxx.com/index.html. 我经常需要查询表以根据URLString列查找特定的URL。 该表包含100K,使用SQLAzure进行这些查询需要几秒钟。 由于URL可能相当长,因此我无法在此列上创建超过450字节的索引 为了加快速度,我想计算SQL Server hashbytes'SHA1'、[URLString]与C的等价值,并基于此值进行查询 我尝试了下面
var urlString = Encoding.ASCII.GetBytes(url.URLString); //UTF8 also fails
var sha1 = new SHA1CryptoServiceProvider();
byte[] hash = sha1.ComputeHash(urlString);
我是不是遗漏了一些琐碎的东西?
我愿意接受其他可以解决同样问题的想法,只要它们得到SQLAzure的支持
示例:在数据库中,自动计算的URL的SHA1值为0xAE66CA69A157186A511ED462153D7CA65F0C1BF7。下面是对字符串和字节进行散列的两种方法。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;
}
您可能会被字符编码差异所困扰:
您可以尝试通过Encoding.ASCII.GetBytesurl或Encoding.Unicode.GetBytesurl获取字节,然后查看您的数据库使用的是哪一个。下面的代码相当于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();
}
您可以发布计算散列的插入吗?如果您的输出与服务器端计算不匹配,请尝试使用许多联机散列计算器中的一个来验证哪个结果是正确的。如果其中一个不正确,可能是因为salt usedIt是一个自动计算列,当我插入新URL时,该值由数据库计算并插入。如果存在salt值,是否所有SQL Server的值都相同?它能从某处获得吗?一定有一段SQL脚本在某处计算它。除非您发现无法猜测发生了什么,否则onI将避免使用cleartext和clearbytes术语,因为这意味着存在相反的含义,例如加密字节/加密字符串。这里没有加密;只有普通的哈希。我们都知道加密!=hashingthis是从生产代码中提取的,在那里“clearbytes”是有意义的。这也不是矛盾,因为输出未命名为“encryptedText”或“encryptedBytes”,输入为相同的“明文”,并适当描述内容。这基本上与我发布的解决方案相同,只是使用了SHA1.Create而不是我的新SHA1 CryptoServiceProvider。我试过了,得到了和以前一样的结果,但数据库还是不一样没问题-是的,哈希算法对编码非常敏感。通常你可以使用Select TABLE\u NAME,COLUMN\u NAME,Columns.COLLATION\u NAME From INFORMATION\u SCHEMA.Columns WHERE TABLE\u NAME='Yourtable'检查用于表/列的排序规则。根据排序规则,如果它是像SQL一样的CP1,那么它是Windows-1252,如果它是,那么它是像SQL一样的代码页号,那么它是437,否则你必须搜索:-varchar=UTF8/extra-accents等nvarchar=UNICODE