Comparing a C# generated Checksum with a SQL Server one

萝らか妹 提交于 2019-12-12 20:21:05

问题


I want to send a lot of data from c# to my database, together with a calculated checksum as the last value, which should be compared to the one that the SQL Server's stored procedure will compute from those values.

To achieve this, I have tried a lot of different ways like the SQL built-in Checksum method and different hashings, but either the C# and SQL compute a different value, or the hashing doesn't work with nvarchars and integers (fx. MD5 hashing) which is required for me.

Did anyone actually manage to do this, or know how to?

Reference to our failed MD5 attempt: SQL Server HASHBYTES conversion inconsistency?

here, the computed result is different than the c# one when it uses nvarchars

Hashing method:

Set @result = convert(nvarchar(32), hashbytes('MD5', @DataID + @Data1 + @Data2 + @Data3), 2)

Also, when you give the hashing method an integer as parameter (like DataID), it complains:

"Argument data type int is invalid for argument 2 of hashbytes function."


回答1:


Comments considered, here is how you can do it (/ is used as a guard char, only one is needed as the int is always 4 bytes):

declare @DataID int = 1234
declare @Data1 nvarchar(max) = N'foo æøåè𨝫 bar'
declare @Data2 nvarchar(max) = N'qux quee'

declare @buffer varbinary(max)
 = cast(@DataID as varbinary(4)) + cast(@Data1 + N'/' as varbinary(max)) + cast(@Data2 as varbinary(max))

select @buffer, select hashbytes('MD5', @buffer)

For

0x000004D266006F006F002000E600F800E500E80061D86BDF20006200610072002F0071007500780020007100750065006500  
0x9DA035DB9D9C319BB636D5E89F4D0EC6

C#

int    DataID = 1234;
string Data1  = "foo æøåè𨝫 bar";
string Data2  = "qux quee";

List<byte> buffer = new List<byte>(BitConverter.GetBytes(DataID));
buffer.Reverse(); // swap endianness for int
buffer.AddRange(Encoding.Unicode.GetBytes(Data1 + "/"));
buffer.AddRange(Encoding.Unicode.GetBytes(Data2));

using (MD5 md5 = MD5.Create())
{
    byte[] hashBytes = md5.ComputeHash(buffer.ToArray());

    //...
}

For

000004D266006F006F002000E600F800E500E80061D86BDF20006200610072002F0071007500780020007100750065006500
9DA035DB9D9C319BB636D5E89F4D0EC6


来源:https://stackoverflow.com/questions/40912390/comparing-a-c-sharp-generated-checksum-with-a-sql-server-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!