HashCode được sử dụng để làm gì? Nó có độc đáo không?


129

Tôi nhận thấy có một getHashCode()phương thức trong mọi điều khiển, các mục, trong WP7, trả về một chuỗi số. Tôi có thể sử dụng mã băm này để xác định một mục không? Ví dụ: tôi muốn xác định một hình ảnh hoặc một bài hát trong thiết bị và kiểm tra nó ở đâu. Điều này có thể được thực hiện nếu mã băm được cung cấp cho các mục cụ thể là duy nhất.

Bạn có thể giúp giải thích cho tôi hashCode là gì và getHashCode()sử dụng để làm gì không?


Tôi biết hashCode có nghĩa là gì, tôi cố gắng chạy mã của mình nhiều lần để lấy mã băm và nó trả lại cùng mã băm cho cùng một lúc và dường như không bị trùng lặp, nhưng tôi không chắc lắm. Chà, không sao nếu bạn muốn downvote, đó là ý kiến ​​của bạn. Cảm ơn vì đã chỉnh sửa!
Nghĩa Nguyễn

7
Tôi khuyên bạn nên đọc Nguyên tắc và quy tắc của Eric Lippert cho GetHashCode , mặc dù nó tập trung vào các quy tắc để triển khai HashCodes thay vì quy tắc sử dụng chúng ... vì chúng "chỉ thiết kế hữu ích cho một điều: đặt một đối tượng vào bảng băm"
Brian

Câu trả lời:


108

MSDN nói :

Mã băm là một giá trị số được sử dụng để xác định một đối tượng trong quá trình kiểm tra đẳng thức. Nó cũng có thể phục vụ như là một chỉ mục cho một đối tượng trong một bộ sưu tập.

Phương thức GetHashCode phù hợp để sử dụng trong các thuật toán băm và cấu trúc dữ liệu như bảng băm.

Việc triển khai mặc định của phương thức GetHashCode không đảm bảo các giá trị trả về duy nhất cho các đối tượng khác nhau. Hơn nữa, .NET Framework không đảm bảo việc triển khai mặc định của phương thức GetHashCode và giá trị mà nó trả về sẽ giống nhau giữa các phiên bản khác nhau của .NET Framework. Do đó, việc triển khai mặc định của phương thức này không được sử dụng làm định danh đối tượng duy nhất cho mục đích băm.

Phương thức GetHashCode có thể được ghi đè bằng một loại dẫn xuất. Các loại giá trị phải ghi đè phương thức này để cung cấp hàm băm phù hợp với loại đó và để cung cấp phân phối hữu ích trong bảng băm. Để duy nhất, mã băm phải dựa trên giá trị của trường hoặc thuộc tính thay vì trường tĩnh hoặc thuộc tính.

Các đối tượng được sử dụng làm khóa trong đối tượng Hashtable cũng phải ghi đè phương thức GetHashCode vì các đối tượng đó phải tạo mã băm của riêng chúng. Nếu một đối tượng được sử dụng làm khóa không cung cấp triển khai GetHashCode hữu ích, bạn có thể chỉ định nhà cung cấp mã băm khi đối tượng Hashtable được xây dựng. Trước phiên bản .NET Framework 2.0, nhà cung cấp mã băm dựa trên giao diện System.Collections.IHashCodeProvider. Bắt đầu với phiên bản 2.0, nhà cung cấp mã băm dựa trên giao diện System.Collections.IEqualityComparer.

Về cơ bản, mã băm tồn tại để làm cho hashtables có thể.
Hai đối tượng bằng nhau được đảm bảo có mã băm bằng nhau.
Hai đối tượng bất bình đẳng đang không đảm bảo để có hashcodes bất bình đẳng (đó được gọi là một vụ va chạm).


3
Báo giá từ MSDN hiện đã lỗi thời. MSDN hiện không rõ ràng về mã băm không phải là duy nhất.
user34660

248

Sau khi tìm hiểu tất cả về nó, tôi nghĩ sẽ viết một lời giải thích hy vọng đơn giản hơn thông qua sự tương tự:

Tóm tắt: Mã băm là gì?

  • Đó là dấu vân tay. Chúng tôi có thể sử dụng dấu vân tay này để xác định những người quan tâm.

Đọc dưới đây để biết thêm chi tiết:

Hãy nghĩ về một Hashcode khi chúng ta cố gắng xác định duy nhất một ai đó

Tôi là một thám tử, tìm kiếm một tên tội phạm. Chúng ta hãy gọi anh ta là Mr Cruel. . Ông Cruel có những đặc điểm đặc biệt nhất định mà tôi có thể sử dụng để nhận dạng duy nhất ông ta giữa một biển người. Chúng tôi có 25 triệu người ở Úc. Một trong số họ là Mr Cruel. Làm thế nào chúng ta có thể tìm thấy anh ta?

Những cách xấu để xác định ông độc ác

Rõ ràng ông Cruel có đôi mắt xanh. Điều đó không giúp được gì nhiều vì gần một nửa dân số ở Úc cũng có đôi mắt xanh.

Cách tốt để xác định ông độc ác

Tôi có thể sử dụng cái gì khác? Tôi biết: Tôi sẽ sử dụng dấu vân tay!

Ưu điểm :

  • Thực sự rất khó để hai người có cùng một dấu vân tay (không phải là không thể, nhưng cực kỳ khó xảy ra).
  • Dấu vân tay của ông Cruel sẽ không bao giờ thay đổi.
  • Mỗi một phần trong toàn bộ thực thể của ông Cruel: ngoại hình, màu tóc, tính cách, thói quen ăn uống, v.v ... phải được phản ánh (lý tưởng) trong dấu vân tay của ông, để nếu ông có một người anh em (rất giống nhau nhưng không giống nhau) - thì cả hai nên có dấu vân tay khác nhau . Tôi nói "nên" bởi vì chúng tôi không thể đảm bảo 100% rằng hai người trên thế giới này sẽ có dấu vân tay khác nhau.
  • Nhưng chúng tôi luôn có thể đảm bảo rằng ông Cruel sẽ luôn có cùng dấu vân tay - và dấu vân tay của ông sẽ KHÔNG BAO GIỜ thay đổi.

Các đặc điểm trên thường làm cho các hàm băm tốt.

Vì vậy, những gì đối phó với 'Va chạm'?

Hãy tưởng tượng nếu tôi có được một khách hàng tiềm năng và tôi tìm thấy ai đó khớp với dấu vân tay của ông Cruel. Điều này có nghĩa là tôi đã tìm thấy Mr Cruel?

........có lẽ! Tôi phải xem xét kỹ hơn. Nếu tôi đang sử dụng SHA256 (một chức năng băm) và tôi đang tìm kiếm trong một thị trấn nhỏ chỉ có 5 người - thì rất có thể tôi đã tìm thấy anh ấy! Nhưng nếu tôi đang sử dụng MD5 (một chức năng băm nổi tiếng khác) và kiểm tra dấu vân tay trong một thị trấn có hơn 2 ^ 1000 người, thì có khả năng hai người hoàn toàn khác nhau có thể có cùng dấu vân tay.

Vì vậy, lợi ích của tất cả các cách này là gì?

Lợi ích thực sự duy nhất của mã băm là nếu bạn muốn đặt thứ gì đó vào bảng băm - và với bảng băm bạn muốn tìm nhanh các đối tượng - và đó là nơi mã băm xuất hiện. Chúng cho phép bạn tìm thấy những thứ trong bảng băm Mau. Đó là một bản hack giúp cải thiện hiệu năng một cách ồ ạt, nhưng với chi phí nhỏ là chính xác.

Vì vậy, hãy tưởng tượng chúng ta có một bảng băm chứa đầy người - 25 triệu nghi phạm ở Úc. Mr Cruel đang ở đâu đó trong đó ..... Làm thế nào chúng ta có thể tìm thấy anh ta thực sự nhanh chóng ? Chúng ta cần sắp xếp tất cả chúng: để tìm ra một đối thủ tiềm năng, hoặc để tha bổng cho các nghi phạm tiềm năng. Bạn không muốn xem xét các đặc điểm độc đáo của mỗi người vì điều đó sẽ mất quá nhiều thời gian. Bạn sẽ sử dụng cái gì thay thế? Bạn sẽ sử dụng mã băm! Một mã băm có thể cho bạn biết nếu hai người khác nhau. Cho dù Joe Bloggs không phải là ông độc ác. Nếu các bản in không khớp thì bạn biết chắc chắn đó không phải là Mr Cruel. Nhưng, nếu các dấu vân tay phù hợpsau đó tùy thuộc vào hàm băm bạn đã sử dụng, rất có thể bạn đã tìm thấy người đàn ông của mình khá tốt. Nhưng nó không phải là 100%. Cách duy nhất bạn có thể chắc chắn là điều tra thêm: (i) anh ấy / cô ấy có cơ hội / động cơ, (ii) nhân chứng, v.v.

Khi bạn đang sử dụng máy tính nếu hai đối tượng có cùng giá trị mã băm, thì bạn lại cần điều tra thêm xem chúng có thực sự bằng nhau không. ví dụ: Bạn phải kiểm tra xem các vật thể có cùng chiều cao, cùng trọng lượng, v.v., nếu các số nguyên giống nhau hay không, nếu khách hàng có khớp nhau không, rồi đưa ra kết luận liệu chúng có giống nhau không. điều này thường được thực hiện bằng cách triển khai giao diện IComparer hoặc IEquality.

Tóm tắt chính

Vì vậy, về cơ bản một mã băm là một dấu vân tay.

Dấu vân tay kỹ thuật số - Thuộc tính hình ảnh cho Pixabay - Có sẵn để sử dụng tại: https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. Hai người / đối tượng khác nhau về mặt lý thuyết vẫn có thể có cùng dấu vân tay. Hay nói cách khác. Nếu bạn có hai dấu vân tay giống nhau ......... thì chúng không cần cả hai đến từ cùng một người / đối tượng.
  2. Buuuuuut, cùng một người / đối tượng sẽ luôn trả lại cùng dấu vân tay .
  3. Điều đó có nghĩa là nếu hai đối tượng trả về mã băm khác nhau thì bạn biết chắc chắn 100% rằng các đối tượng đó là khác nhau.

Phải mất 3 phút để có được đầu của bạn xung quanh ở trên. Có lẽ đọc nó một vài lần cho đến khi nó có ý nghĩa. Tôi hy vọng điều này sẽ giúp được ai đó vì tôi đã mất rất nhiều đau buồn để học được tất cả!


1
Re: Tài liệu MSDN đã giết chết một vài tế bào não của tôi .... đã khiến một vài người trong số tôi rơi vào bờ vực tự sát. chỉ được cứu vì tôi đã ngủ;)
Shwrk 23/03/18

Bạn đã phá hủy toàn bộ lời giải thích tốt đẹp của bạn với nhận xét hoa thị ở cuối.
Waldemar Gałęzinowski

Tôi yêu nó! chủ yếu là cái tên "Mr.Cruel!
João Pedro Andrade Marques

Là một người hâm mộ tội phạm thực sự, đây hoàn toàn có thể là câu trả lời SO yêu thích nhất của tôi ... từ trước đến nay.
IfElseTryCatch

11

GetHashCode()được sử dụng để hỗ trợ sử dụng đối tượng làm khóa cho các bảng băm. (Một điều tương tự tồn tại trong Java, v.v.). Mục tiêu là cho mọi đối tượng trả về một mã băm riêng biệt, nhưng điều này thường không thể được đảm bảo tuyệt đối. Người ta đòi hỏi dù rằng hai đối tượng một cách logic bằng trả lại cùng một mã băm.

Việc triển khai bảng băm điển hình bắt đầu bằng giá trị hashCode, lấy một mô-đun (do đó ràng buộc giá trị trong một phạm vi) và sử dụng nó làm chỉ mục cho một mảng "xô".


8

Nó không phải là duy nhất cho WP7 - nó hiện diện trên tất cả các đối tượng .Net. Nó giống như những gì bạn mô tả, nhưng tôi sẽ không đề xuất nó như một định danh duy nhất trong các ứng dụng của bạn, vì nó không được đảm bảo là duy nhất.

Phương thức Object.GetHashCode


4

Đây là từ bài viết msDN ở đây:

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

"Mặc dù bạn sẽ nghe mọi người nói rằng mã băm tạo ra một giá trị duy nhất cho một đầu vào nhất định, nhưng thực tế là, trong khi khó thực hiện, về mặt kỹ thuật có thể tìm thấy hai đầu vào dữ liệu khác nhau băm với cùng một giá trị . việc xác định các yếu tố liên quan đến hiệu quả của thuật toán băm nằm ở độ dài của mã băm được tạo và độ phức tạp của dữ liệu được băm. "

Vì vậy, chỉ cần sử dụng một thuật toán băm phù hợp với kích thước dữ liệu của bạn và nó sẽ có mã băm duy nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.