2013-09-18 3 views
7

Я использую функцию chechsum в sql server 2008 R2, и я хотел бы получить одинаковые значения int в приложении C#. Есть ли эквивалентный метод в C#, который возвращает значения, такие как функция контрольной суммы sql? ThanxКонтрольная сумма SqlServer в C#

+0

Аналогичный вопрос здесь http://stackoverflow.com/questions/6892138/implementing-sql-checksum-in-java – dna2

+0

См. Мой ответ, я нашел алгоритм на форумах SQL Server. Это серия из 4-х битных операций поворота xor. – dna2

+0

Согласно Microsoft, «вы не можете вызвать эту функцию напрямую», однако она может «появляться в запросе LINQ to Entities» в приложении C#, [ссылка] (http://msdn.microsoft.com/en-us/library /dd466233(v=vs.100).aspx) –

ответ

1

CHECKSUM Документы не раскрывают, как он вычисляет хэш. Если вы хотите хэш вы можете использовать в T-SQL и C#, выбрать из алгоритмов, поддерживаемых в HashBytes

+0

Это очень плохо, я искал эффективный способ хэширования строки для int (несмотря на столкновения). – Andres

+0

@Andres - String.GetHashCode() будет содержать строку для int, и вы можете открыть ее из функции SQLCLR для использования в вашей базе данных –

9

На SQL Server Форум, в этом page, он заявил:

Встроенная функция CHECKUM в SQL Server построен на серии 4 битовых левых вращательных операций XOR. См. Это post для более подробного объяснения.

я смог портировать BINARY_CHECKSUM на C# и это, кажется, работает ... Я буду смотреть на равнинной CHECKSUM позже ...

private int SQLBinaryChecksum(string text) 
{ 
    long sum = 0; 
    byte overflow; 
    for (int i = 0; i < text.Length; i++) 
    { 
     sum = (long)((16 * sum)^Convert.ToUInt32(text[i])); 
     overflow = (byte)(sum/4294967296); 
     sum = sum - overflow * 4294967296; 
     sum = sum^overflow; 
    } 

    if (sum > 2147483647) 
     sum = sum - 4294967296; 
    else if (sum >= 32768 && sum <= 65535) 
     sum = sum - 65536; 
    else if (sum >= 128 && sum <= 255) 
     sum = sum - 256; 

    return (int)sum; 
} 
+0

Это фантастика и, кажется, отлично работает с текстом. Тем не менее, у меня есть varbinary (max), который хранит файлы, и я изменил эту функцию, чтобы взять байтовый массив вместо строки. Он отлично работает для текстовых файлов, но не возвращает одинаковые результаты для двоичных файлов. Есть идеи? – codeConcussion

2

Документация T-SQL не указать, какой алгоритм используется checksum() за пределами этого:

CHECKSUM вычисляет хэш-значение, называется контрольной суммы, по его списку аргументов. Хэш-значение предназначено для использования в строительных хэш-индексах. Если аргументы для CHECKSUM являются столбцами, а индекс построен по вычисленному значению CHECKSUM, результатом является хэш-индекс. Это можно использовать для поиска по столбцам.

Вряд ли вычислить хэш MD5, так как его возвращаемое значение (вычисленный хэш) является 32-битным целым числом; хэш MD5 имеет длину 128 бит.

+0

Фактически SQLServer возвращает int для функции контрольной суммы. MD5-хеширование выполняется через функцию HASHBYTES и возвращает varbinary (это должно быть возвращаемое значение вашей функции C#). Я ищу функции C#, которые также возвращают int. – Andres

+0

Вы правы, я дважды читаю страницу MSDN и ничего не говорит об этом ... Вместо этого предлагается использовать HASHBYTES, который реализует различные алгоритмы хеширования. – dna2

0

В случае, если вам необходимо сделать контрольную сумму на GUID, ответ изменить DNA2 на это:

private int SQLBinaryChecksum(byte[] text) 

С байтовым массивом значение из SQL будет соответствовать значению из C#. Для теста:

var a = Guid.Parse("DEAA5789-6B51-4EED-B370-36F347A0E8E4").ToByteArray(); 
Console.WriteLine(SQLBinaryChecksum(a)); 

против SQL:

select BINARY_CHECKSUM(CONVERT(uniqueidentifier,'DEAA5789-6B51-4EED-B370-36F347A0E8E4')) 

оба ответа будут -1897092103.

Смежные вопросы