【问题标题】:MD5 HashCode in C#.NETC#.NET 中的 MD5 哈希码
【发布时间】:2016-12-11 10:07:23
【问题描述】:

如何绕过 SQL Server 2012 中创建哈希码的 8000 个字符限制,

 select SUBSTRING(sys.fn_sqlvarbasetostr(HASHBYTES('MD5', 'Sample
 string with more than 8000 Characters')),3,32) as MD5HashCode

我尝试使用 C# 语法。

String  str = "Sample string with more than 8000 Characters"
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.Unicode.GetBytes(str);
bs = x.ComputeHash(bs);
System.Text.StringBuilder s = new System.Text.StringBuilder();
  foreach (byte b in bs)
  {
    s.Append(b.ToString("x2").ToLower());
  }

但是计算出的 HashCode SQL Query 在 C# 语法中是不同的。

提前致谢。

【问题讨论】:

标签: c# sql-server md5


【解决方案1】:

当使用 SQL Server 的 varchar 数据类型时,.Net 编码是 UTF8,因为它是三种(ASCII、UTF7、UTF8)中最快和最优化的。当使用 nvarchar 数据类型时,要使用 Unicode (UTF16),但我们还必须知道文本的字节顺序才能创建正确的散列。

示例

点网

string source = "Sample string with more than 8000 Characters";
using (MD5 md5Hash = MD5.Create()) 
{ 
    Console.WriteLine(GetMd5Hash(md5Hash, source, System.Text.Encoding.ASCII)); <br/>Console.WriteLine(GetMd5Hash(md5Hash, source, System.Text.Encoding.UTF7));
    Console.WriteLine(GetMd5Hash(md5Hash, source, System.Text.Encoding.UTF8));  
    Console.WriteLine(GetMd5Hash(md5Hash, source,System.Text.Encoding.Unicode)); 
    Console.WriteLine(GetMd5Hash(md5Hash, source, System.Text.Encoding.UTF32)); 
}

DotNet Image

数据库

-- 注意所有数据类型的大小为 15

declare @val1 varchar(50),
    @val2 nvarchar(50),
    @val3 char(50),
    @val4 nchar(50)

-- 1 字节/字符文本示例
-- 所有变量的长度相同

select  @val1 =  'Sample string with more than 8000 Characters'
    @val2 = N'Sample string with more than 8000 Characters',
    @val3 =  'Sample string with more than 8000 Characters',
    @val4 = N'Sample string with more than 8000 Characters'

-- 4 个都返回不同的结果

select  HASHBYTES('md5', @val1) as MD5_varchar,    
-- result = 0xAE1C585474D90965ED832A7E588D4AF4
-- just to show that collation doesnot change the hash
HASHBYTES('md5', @val1 collate Cyrillic_General_BIN2) as MD5_varchar_collation, 
-- result = 0xAE1C585474D90965ED832A7E588D4AF4
HASHBYTES('md5', @val2) as MD5_Nvarchar,    
-- result = 0x880632484491D1283818B7A3AE3D2AFC
HASHBYTES('md5', @val3) as MD5_char,        
-- result = 0x77D2A2CF22998C4CD5AD5550664BF931
HASHBYTES('md5', @val4) as MD5_Nchar        
-- result = 0x9B55DF00EAFE01D764BB944592C27521

Database Image

【讨论】:

  • 感谢您的解释,现在我意识到每种编码类型之间的区别。我选择 UTF8。
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 2019-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-19
  • 2012-08-17
相关资源
最近更新 更多