2013-03-22 40 views
9

Ben 64 bit int olarak bir dize sağlamalarının evrensel karma alogrithim oluşturmaya çalışıyorum int64 C# eşleşecek.SQL Bigint karma karma

Ben doğru dizeleri karma hakları taşıyor: sql:

select 
    convert 
    (
     varchar(64), 
     HASHBYTES 
     (
      'SHA1', 
      'google.com' 
     ), 
     2 
    ) 

döner 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 Ancak BAEA954B95731C68AE6E45BD1E252EB4560CDC45

Ben bir bigint dönüştürmek zaman/lo ng değerleri eşleşmiyor: SQL:

select 
    convert 
    (
     bigint, 
     HASHBYTES 
     (
      'SHA1', 
      'google.com' 
     ) 
    ) 

döner 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); 

döner 7501998164347841210

Bu rakamların eşleşmesi almak konusunda herhangi bir fikir?

+0

:

bazı kodlama mü http://stackoverflow.com/questions/8467072/sql-server-varbinary-bigint-with-bitconverter-toint64-values-are-different bir için olası çözüm. –

+0

yerine nesneler üzerinde kendi karmaları üretme sadece yeniden icat daha [ 'GetHashCode'] (http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx), onun çok daha etkili kullanmalıdır tekerleği, aynı karakterleri olan dizeleri aynı "HashCode" 'u üretecektir. – Killrawr

+2

@Killrawr: GetHashCode sadece bir karma tablo dengelemek için kullanılmalıdır. Orijinal posterin bir hash tablosunu dengelemeye çalıştığına dair hiçbir kanıtımız yok; Bir kripto gücü karma deniyor gibi görünüyor. ** kripto karma için ** GetHashCode kullanmak asla çok ama çok önemlidir. Güvenli bir karma oluşturmak için gereken özelliklerin * hiçbiri * yoktur. Yine, GetHashCode'u çağırıyorsanız ve şu anda bir karma tabloyu dengelemeye çalışmıyorsanız, yanlış bir şey yapıyorsunuz demektir. –

cevap

8

Kişisel SQL Bigint C# uygulaması ilk 8 bayt alırken son 8 bayt alır (ve küçük endian üzerindeki çalışan çünkü onları tersine).

C# Dizinin düzgün Aralığı alın ve bunu tersine. O zaman iyi olmalısın. Bkz burada

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 
+0

Ve baytları takas etmek için 'var reversed = BitConverter.GetBytes (IPAdresi.HostToNetworkOrder (longValue))' yi kullanabilirsiniz. –

+0

çok mükemmel cevap! –

+1

@DasKrumelmonster: Eğer Linq yerine 'BitConverter.GetBytes (IPAddress.HostToNetworkOrder (longValue))' kullanırsanız, HostToNetworkOrder() bunun için hesapladığı için istemcinin bayt sırasından bağımsız olarak çalışır. –