2016-12-01 2 views
2

Я хочу отправить большое количество данных из C# в мою базу данных вместе с вычисленной контрольной суммой в качестве последнего значения, которое следует сравнить с тем, что хранимая процедура SQL Server будет вычисляться из этих значений.Сравнение созданной C# контрольной суммы с SQL Server 1

Для этого я пробовал много разных способов, таких как встроенный метод SQL Checksum и разные хешинговые элементы, но либо C#, либо SQL вычисляют другое значение, или хеширование не работает с nvarchars и целыми числами (fx. MD5 хеширование), которое требуется для меня.

Неужели кому-нибудь действительно удалось это сделать или знать как?

Ссылка на нашу неудачную попытку MD5: SQL Server HASHBYTES conversion inconsistency?

здесь, вычисленный результат отличается от C# один, когда он использует nvarchars

метод хэширования:

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

Кроме того, когда вы дать методу хеширования целое число как параметр (например, DataID), он жалуется:

"Тип данных аргумента e int недопустим для аргумента 2 функции hashbytes. "

+1

Скорее всего, если текст задействован, есть разница с сортировкой и кодировкой. В любом случае вы должны опубликовать код. Поместите некоторый код SQL и некоторый код C#, который вычисляет контрольную сумму одних и тех же вещей, а затем публикует сгенерированные контрольные суммы. До тех пор, пока вы это сделаете, самое большее вы получите «Ну, это слишком плохо». –

+1

HASHBYTES() поддерживает MD5 и работает с nvarchar и любым другим типом при преобразовании в varbinary, C# может сделать то же самое, в чем проблема, с которой вы столкнулись? –

+0

добавил ссылку на сообщение моих друзей с кодом SQL. При использовании Nvarchars он не вычисляет то же, что и хеширование C#, и не принимает целые числа. Мы будем проверять оба потока для ответов регулярно. –

ответ

1

Комментарии Рассмотренные, вот как вы можете это сделать (/ используется в качестве защитного полукокса, только один необходим как ИНТ всегда 4 байта):

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) 

Для

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()); 

    //... 
} 

Для

000004D266006F006F002000E600F800E500E80061D86BDF20006200610072002F0071007500780020007100750065006500 
9DA035DB9D9C319BB636D5E89F4D0EC6 
Смежные вопросы