HashCode ne için kullanılır? Eşsiz mi?


129

getHashCode()WP7'deki her denetimde, öğede bir sayı dizisi döndüren bir yöntem olduğunu fark ettim . Bu karma kodu bir öğeyi tanımlamak için kullanabilir miyim? Örneğin cihazdaki bir resim veya şarkıyı belirleyip nerede olduğunu kontrol etmek istiyorum. Bu, belirli öğeler için verilen karma kod benzersizse yapılabilir.

Bana hashCode'un ne olduğunu ve ne için getHashCode()kullanıldığını açıklamaya yardım edebilir misin ?


HashCode'un ne anlama geldiğini biliyorum, hashcode'u almak için kodumu birçok kez çalıştırmaya çalışıyorum ve her seferinde aynı öğeler için aynı hashcode'u döndürüyor ve kopyalanmış gibi görünmüyor, ancak pek emin değilim. Olumsuz oy istersen sorun değil, bu senin fikrin. Yine de düzenleme için teşekkürler!
Nghia Nguyen

7
Eric Lippert'in GetHashCode Yönergelerini ve kurallarını okumanızı tavsiye ederim , ancak bunları kullanma kurallarından ziyade HashCode'ları uygulama kurallarına odaklanır ... çünkü bunlar " tasarım gereği sadece bir şey için yararlıdır : bir nesneyi bir hash tablosuna koymak"
Brian

Yanıtlar:


108

MSDN diyor :

Karma kod, eşitlik testi sırasında bir nesneyi tanımlamak için kullanılan sayısal bir değerdir. Ayrıca bir koleksiyondaki bir nesne için bir dizin görevi görebilir.

GetHashCode yöntemi, karma algoritmalarında ve karma tablo gibi veri yapılarında kullanım için uygundur.

GetHashCode yönteminin varsayılan uygulaması, farklı nesneler için benzersiz dönüş değerleri garanti etmez. Ayrıca, .NET Framework, GetHashCode yönteminin varsayılan uygulamasını garanti etmez ve döndürdüğü değer, .NET Framework'ün farklı sürümleri arasında aynı olacaktır. Sonuç olarak, bu yöntemin varsayılan uygulaması, karma oluşturma amacıyla benzersiz bir nesne tanımlayıcısı olarak kullanılmamalıdır.

GetHashCode yöntemi, türetilmiş bir tür tarafından geçersiz kılınabilir. Değer türleri, söz konusu türe uygun bir karma işlevi sağlamak ve bir karma tabloda yararlı bir dağıtım sağlamak için bu yöntemi geçersiz kılmalıdır. Benzersizlik için, karma kod, statik bir alan veya özellik yerine bir örnek alanı veya özelliğin değerine dayanmalıdır.

Hashtable nesnesinde anahtar olarak kullanılan nesneler, GetHashCode yöntemini de geçersiz kılmalıdır çünkü bu nesnelerin kendi karma kodunu oluşturması gerekir. Anahtar olarak kullanılan bir nesne GetHashCode'un yararlı bir uygulamasını sağlamıyorsa, Hashtable nesnesi oluşturulduğunda bir karma kod sağlayıcısı belirtebilirsiniz. .NET Framework sürüm 2.0'dan önce, karma kod sağlayıcısı System.Collections.IHashCodeProvider arabirimini temel alıyordu. Sürüm 2.0'dan başlayarak, karma kod sağlayıcısı System.Collections.IEqualityComparer arabirimini temel alır.

Temel olarak, hashtable'ları mümkün kılmak için hash kodları vardır.
İki eşit nesnenin eşit karma kodlara sahip olması garanti edilir.
Eşit olmayan iki nesnenin eşit olmayan karma kodlara sahip olması garanti edilmez (buna çarpışma denir).


3
MSDN'den alınan alıntı artık güncel değil. MSDN, artık karma kodun benzersiz olmaması konusunda açık değildir.
user34660

248

Neyle ilgili olduğunu öğrendikten sonra, benzetme yoluyla umarım daha basit bir açıklama yazmayı düşündüm:

Özet: Karma kod nedir?

  • Bu bir parmak izi. Bu parmak izini ilgilendiğimiz kişileri belirlemek için kullanabiliriz.

Daha fazla ayrıntı için aşağıyı okuyun:

Birini Benzersiz Bir Şekilde Tanımlamaya çalışırken bir Hashcode düşünün

Ben bir suçluyu arayan bir dedektifim. Ona Bay Zalim diyelim. (Ben çocukken kötü şöhretli bir katildi - kaçırılan bir eve girdi ve fakir bir kızı öldürdü, vücudunu attı ve hala başıboş dolaşıyor - ama bu ayrı bir mesele). Bay Zalim, onu bir insan denizi arasında benzersiz bir şekilde tanımlamak için kullanabileceğim bazı tuhaf özelliklere sahiptir. Avustralya'da 25 milyon insanımız var. Bunlardan biri Bay Zalim. Onu nasıl bulabiliriz?

Bay Zalim'i Tanımlamanın Kötü Yolları

Görünüşe göre Bay Zalim'in mavi gözleri var. Bu pek yardımcı olmuyor çünkü Avustralya'daki nüfusun neredeyse yarısının mavi gözleri var.

Bay Zalim'i Tanımlamanın İyi Yolları

Başka ne kullanabilirim? Biliyorum: Parmak izi kullanacağım!

Avantajlar :

  • İki kişinin aynı parmak izine sahip olması gerçekten zordur (imkansız değil, ama son derece olası değildir).
  • Mr Cruel'in parmak izi asla değişmeyecek.
  • Mr Cruel'in tüm varlığının her bir parçası: görünüşü, saç rengi, kişiliği, yeme alışkanlıkları vb. (İdeal olarak) parmak izine yansıtılmalıdır, öyle ki (çok benzer ama aynı olmayan) bir erkek kardeşi varsa - o zaman ikisi de farklı parmak izlerine sahip olmalıdır . "Olmalı" diyorum çünkü bu dünyadaki iki insanın farklı parmak izlerine sahip olacağını% 100 garanti edemeyiz.
  • Ancak, Bay Zalim'in her zaman aynı parmak izine sahip olacağını ve parmak izinin ASLA değişmeyeceğini her zaman garanti edebiliriz.

Yukarıdaki özellikler genellikle iyi hash fonksiyonları sağlar.

Öyleyse 'Çarpışmalar' ile anlaşma nedir?

Bir ipucu bulsam ve Bay Cruel'in parmak izlerine uyan birini bulduğumu hayal edin. Bu, Bay Zalim'i bulduğum anlamına mı geliyor?

........ belki! Daha yakından bakmalıyım. SHA256 (hashing işlevi) kullanıyorsam ve sadece 5 kişiyle küçük bir kasabaya bakıyorsam - o zaman onu bulmam çok yüksek bir ihtimal! Ancak MD5 (başka bir ünlü karma işlevi) kullanıyorsam ve + 2 ^ 1000 kişinin bulunduğu bir kasabada parmak izlerini kontrol ediyorsam, tamamen farklı iki kişinin aynı parmak izine sahip olması oldukça iyi bir olasılıktır.

Öyleyse tüm bunların faydası nedir?

Karma kodların tek gerçek yararı, bir karma tabloya bir şey koymak istiyorsanız - ve karma tablolarla nesneleri hızlı bir şekilde bulmak istiyorsanız - ve karma kodun geldiği yer burasıdır. Karma tablolardaki şeyleri gerçekten bulmanızı sağlar hızlı bir şekilde. Bu, performansı büyük ölçüde artıran, ancak küçük bir doğruluk pahasına olan bir saldırıdır.

Öyleyse, Avustralya'da 25 milyon şüpheli olan insanlarla dolu bir hash masamız olduğunu hayal edelim. Mr Cruel oralarda bir yerde ..... Onu gerçekten çabuk nasıl bulabiliriz ? Bunların hepsini gözden geçirmeliyiz: potansiyel bir eşleşme bulmak veya potansiyel şüphelileri başka şekilde aklamak için. Her bir kişinin benzersiz özelliklerini dikkate almak istemezsiniz çünkü bu çok fazla zaman alır. Onun yerine ne kullanırdın? Bir karma kod kullanırsınız! Karma kod, iki kişinin farklı olup olmadığını size söyleyebilir. Joe Bloggs'un Bay Zalim olup olmadığı. Parmak izleri uyuşmuyorsa, kesinlikle Bay Zalim OLMADIĞINI biliyorsunuzdur. Ama parmak izleri uyuyorsao zaman kullandığınız hash fonksiyonuna bağlı olarak, erkeğinizi bulduğunuzda şansınız oldukça yüksektir. Ama% 100 değil. Emin olmanın tek yolu daha fazla araştırma yapmaktır: (i) bir fırsatı / nedeni var mıydı, (ii) tanıklar vb.

Bilgisayar kullanıyorsanız , iki nesne aynı karma kod değerine sahipse, bunların gerçekten eşit olup olmadıklarını yeniden araştırmanız gerekir. Örneğin, nesnelerin örneğin aynı yüksekliğe, aynı ağırlığa vb. sahip olup olmadığını, tam sayıların aynı olup olmadığını veya customer_id'nin bir eşleşme olup olmadığını kontrol etmeniz ve sonra aynı olup olmadıkları sonucuna varmanız gerekir. bu tipik olarak bir IComparer veya IEquality arabirimleri uygulanarak yapılabilir.

Anahtar Özeti

Yani temelde bir hashcode bir parmak izidir.

Dijital Parmak İzi - Pixabay için resim niteliği - Şu adresten ücretsiz olarak kullanılabilir: https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. İki farklı kişi / nesne teorik olarak hala aynı parmak izine sahip olabilir. Veya başka bir deyişle. Aynı ......... olan iki parmak iziniz varsa, ikisinin de aynı kişiden / nesneden gelmesi gerekmez.
  2. Buuuuuut, aynı kişi / nesne her zaman aynı parmak izini döndürür .
  3. Bu, iki nesne farklı karma kodlar döndürürse , bu nesnelerin farklı olduğunu% 100 kesin olarak bildiğiniz anlamına gelir .

Yukarıdakilerin etrafından dolaşmak 3 dakika sürer. Belki mantıklı gelene kadar birkaç kez okuyun. Umarım bu birilerine yardımcı olur çünkü hepsini öğrenmek benim için çok keder aldı!


1
Ynt: MSDN dokümantasyonu, beyin hücrelerimden birkaçını öldürdü .... epeyce benimkini intiharın eşiğine getirdi. sadece uykuya
daldığım için

Sonunda yıldız işareti ile tüm güzel açıklamanı yok ettin.
Waldemar Gałęzinowski

Onu sevdim! esas olarak adı "Mr.Cruel!
João Pedro Andrade Marques

Gerçek bir suç hayranı olarak, bu muhtemelen benim şimdiye kadarki en sevdiğim SO cevabı.
IfElse TryCatch

11

GetHashCode()nesnenin karma tablolar için bir anahtar olarak kullanılmasına yardımcı olmak için kullanılır. (Java'da da benzer bir şey var). Amaç, her nesnenin farklı bir hash kodu döndürmesidir, ancak bu genellikle kesinlikle garanti edilemez. O edilir gerekli iki mantıksal olarak eşit nesneler dönmek olsa aynı hash kodu.

Tipik bir karma tablo uygulaması hashCode değeriyle başlar, bir modül alır (böylece bir aralıktaki değeri sınırlar) ve bunu bir "kova" dizisi için bir indeks olarak kullanır.


8

WP7'ye özgü değildir - tüm .Net nesnelerinde mevcuttur. Tanımladığınız şeyi bir şekilde yapıyor, ancak benzersiz olması garanti edilmediğinden, bunu uygulamalarınızda benzersiz bir tanımlayıcı olarak önermem.

Object.GetHashCode Yöntemi


4

Bu, buradaki msdn makalesinden:

https://blogs.msdn.microsoft.com/tomarcher/2006/05/10/are-hash-codes-unique/

"İnsanların, karma kodların belirli bir girdi için benzersiz bir değer ürettiğini söylediğini duyacak olsanız da, gerçek şu ki, başarmak zor olsa da, aynı değere hash olan iki farklı veri girdisi bulmak teknik olarak mümkün . Ancak, doğru Bir karma algoritmanın etkililiğine ilişkin belirleme faktörleri, oluşturulan karma kodun uzunluğunda ve karma hale getirilen verilerin karmaşıklığında yatmaktadır. "

Bu nedenle, veri boyutunuza uygun bir karma algoritma kullanın ve benzersiz karma kodlara sahip olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.