gpt4 book ai didi

c# - 如何使用 C# 计算哈希字节 SHA1?

转载 作者:太空宇宙 更新时间:2023-11-03 21:35:37 24 4
gpt4 key购买 nike

在一个表中,我有一列 URL,我用它来保存 url。我正在使用公式 (CONVERT([varbinary](20),hashbytes('SHA1',[URL]))) 计算另一列中的哈希值。它工作正常。

现在我需要在 C# 中获得类似的函数来获取哈希,以便在插入新行之前比较并检查类似的行不存在。我尝试了几个链接但没有运气。

链接如下:

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

How do I calculate the equivalent to SQL Server (hashbytes('SHA1',[ColumnName])) in C#?

** I found this link working. All I need to do is change formula in the db. but is it possible to make it in one line 
**

http://forums.asp.net/t/1782626.aspx

DECLARE @HashThis nvarchar(4000);
DECLARE @BinHash varbinary(4000);
SELECT @HashThis = CONVERT(nvarchar(4000),'Password@Test');
SELECT @BinHash = HashBytes('SHA1', @HashThis);

SELECT cast(N'' as xml).value('xs:base64Binary(xs:hexBinary(sql:variable("@BinHash")))', 'nvarchar(4000)');

在 C# 中

string pwd = "Password@Test"; 
var sha1Provider = HashAlgorithm.Create("SHA1");
var binHash = sha1Provider.ComputeHash(Encoding.Unicode.GetBytes(pwd));
Console.WriteLine(Convert.ToBase64String(binHash));

我使用的是 sql server 2012。数据库的排序规则是 SQL_Latin1_General_CP1_CI_AS

谢谢

参数

最佳答案

这是一个编码问题:

C#/.Net/CLR 字符串在内部是 UTF-16 编码字符串。这意味着每个字符至少两个字节。

SQL Server 不同:

  • charvarchar 使用与该列使用的collat​​ion 绑定(bind)的代码页将每个字符表示为单个字节

  • ncharnvarchar 使用 [old and obsolete] UCS-2 编码为 Unicode 将每个字符表示为 2 个字节——这在 1996 年被弃用了Unicode 2.0 和 UTF-16 的发布。

    UTF-16 和 UCS-2 最大的区别是 UCS-2 只能表示 Unicode BMP(基本多语言平面)内的字符; UTF-16 可以表示任何 Unicode 字符。在 BMP 中,据我了解,UCS-2 和 UTF-16 表示是相同的。

这意味着要计算与 SQL Server 计算的散列相同的散列,您将必须获得与 SQL Server 具有的相同的字节表示形式。由于听起来您正在使用 charvarchar 以及排序规则 SQL_Latin1_General_CP1_CI_ASper the documentation , CP1 部分表示代码页 1252,其余部分表示不区分大小写,区分重音。所以……

您可以通过以下方式获取代码页 1252 的编码:

Encoding enc = Encoding.GetEncoding(1252);

使用该信息并给出此表:

create table dbo.hash_test
(
id int not null identity(1,1) primary key clustered ,
source_text varchar(2000) collate SQL_Latin1_General_CP1_CI_AS not null ,
hash as
( hashbytes( 'SHA1' , source_text ) ) ,
)
go
insert dbo.hash_test ( source_text ) values ( 'the quick brown fox jumped over the lazy dog.' )
insert dbo.hash_test ( source_text ) values ( 'She looked like something that might have occured to Ibsen in one of his less frivolous moments.' )
go

你会得到这个输出

1: the quick brown fox jumped over the lazy dog.
sql: 6039D100 3323D483 47DDFDB5 CE2842DF 758FAB5F
c#: 6039D100 3323D483 47DDFDB5 CE2842DF 758FAB5F

2: She looked like something that might have occured to Ibsen in one of his less frivolous moments.
sql: D92501ED C462E331 B0E129BF 5B4A854E 8DBC490C
c#: D92501ED C462E331 B0E129BF 5B4A854E 8DBC490C

来自这个程序

class Program
{

static byte[] Sha1Hash( string s )
{
SHA1 sha1 = SHA1.Create() ;
Encoding windows1252 = Encoding.GetEncoding(1252) ;
byte[] octets = windows1252.GetBytes(s) ;
byte[] hash = sha1.ComputeHash( octets ) ;

return hash ;
}

static string HashToString( byte[] bytes )
{
StringBuilder sb = new StringBuilder() ;

for ( int i = 0 ; i < bytes.Length ; ++i )
{
byte b = bytes[i] ;
if ( i > 0 && 0 == i % 4 ) sb.Append( ' ' ) ;
sb.AppendFormat( b.ToString("X2") ) ;
}

string s = sb.ToString() ;
return s ;
}

private static DataTable ReadDataFromSqlServer()
{
DataTable dt = new DataTable();

using ( SqlConnection conn = new SqlConnection( "Server=localhost;Database=sandbox;Trusted_Connection=True;"))
using ( SqlCommand cmd = conn.CreateCommand() )
using ( SqlDataAdapter sda = new SqlDataAdapter(cmd) )
{
cmd.CommandText = "select * from dbo.hash_test" ;
cmd.CommandType = CommandType.Text;
conn.Open();
sda.Fill( dt ) ;
conn.Close() ;
}

return dt ;
}

static void Main()
{
DataTable dt = ReadDataFromSqlServer() ;

foreach ( DataRow row in dt.Rows )
{
int id = (int) row[ "id" ] ;
string sourceText = (string) row[ "source_text" ] ;
byte[] sqlServerHash = (byte[]) row[ "hash" ] ;
byte[] myHash = Sha1Hash( sourceText ) ;

Console.WriteLine();
Console.WriteLine( "{0:##0}: {1}" , id , sourceText ) ;
Console.WriteLine( " sql: {0}" , HashToString( sqlServerHash ) ) ;
Console.WriteLine( " c#: {0}" , HashToString( myHash ) ) ;

Debug.Assert( sqlServerHash.SequenceEqual(myHash) ) ;

}

return ;
}

}

简单!

关于c# - 如何使用 C# 计算哈希字节 SHA1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22021949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com