This question already has an answer here:
I am trying to create a universal hashing alogrithim that hashes a string as a 64 bit int.
I am able to hash the strings correctly: sql:
select
convert
(
varchar(64),
HASHBYTES
(
'SHA1',
'google.com'
),
2
)
returns BAEA954B95731C68AE6E45BD1E252EB4560CDC45
C#
System.Security.Cryptography.SHA1 c = System.Security.Cryptography.SHA1.Create();
System.Text.StringBuilder sb = new StringBuilder();
byte[] b = c.ComputeHash(Encoding.UTF8.GetBytes("google.com"));
for (int i = 0; i < b.Length;i++ )
{
byte by = b[i];
sb.Append(by.ToString("x2").ToUpper());
}
return sb.ToString();
retruns BAEA954B95731C68AE6E45BD1E252EB4560CDC45
However when I convert to a bigint/long the values do not match: sql:
select
convert
(
bigint,
HASHBYTES
(
'SHA1',
'google.com'
)
)
returns 2172193747348806725
c#:
System.Security.Cryptography.SHA1 c = System.Security.Cryptography.SHA1.Create();
byte[] b = c.ComputeHash(Encoding.UTF8.GetBytes("google.com"));
return BitConverter.ToInt64(b, 0);
returns 7501998164347841210
Any ideas on how to get these numbers to match?
Your SQL bigint takes the last 8 bytes while the c# implementation takes the first 8 bytes (and reverses them because its running on little endian).
Take the proper Range of the array in C# and reverse it. Then you should be fine.
Did some coding:
System.Security.Cryptography.SHA1 c = System.Security.Cryptography.SHA1.Create();
byte[] b = c.ComputeHash(Encoding.UTF8.GetBytes("google.com"));
long value = BitConverter.ToInt64(b, 12);
value = IPAddress.HostToNetworkOrder(value);
Debug.WriteLine(value);
// writes 2172193747348806725
来源:https://stackoverflow.com/questions/15579946/sql-bigint-hash-to-match-c-sharp-int64-hash