Bài viết Wikipedia về các hàm băm là rất tốt, nhưng tôi sẽ đưa ra đây.
Băm là gì?
"Hash" thực sự là một thuật ngữ rộng với các ý nghĩa chính thức khác nhau trong các bối cảnh khác nhau. Không có một câu trả lời hoàn hảo cho câu hỏi của bạn. Tôi sẽ giải thích khái niệm cơ bản chung và đề cập đến một số cách sử dụng phổ biến nhất của thuật ngữ này.
"Băm" là một hàm được gọi là hàm băm
lấy làm đối tượng đầu vào và xuất ra một chuỗi hoặc số. Các đối tượng đầu vào thường là thành viên của các kiểu dữ liệu cơ bản như chuỗi, số nguyên hoặc lớn hơn bao gồm các đối tượng khác như cấu trúc do người dùng xác định. Đầu ra thường là một số hoặc một chuỗi. Danh từ "băm" thường dùng để chỉ đầu ra này. Động từ "băm" thường có nghĩa là "áp dụng hàm băm". Các thuộc tính chính mà hàm băm nên có là:h
- Nó phải dễ dàng để tính toán và
- Các đầu ra nên tương đối nhỏ.
Thí dụ:
Giả sử chúng tôi muốn băm số trong phạm vi từ 0 đến 999.999.999 đến số từ 0 đến 99. Một hàm băm đơn giản có thể là .h ( x ) = xmod100
Thuộc tính bổ sung phổ biến:
Tùy thuộc vào trường hợp sử dụng, chúng ta có thể muốn hàm băm thỏa mãn các thuộc tính bổ sung. Dưới đây là một số thuộc tính bổ sung phổ biến:
Tính đồng nhất : Thông thường chúng ta muốn băm của các đối tượng là khác biệt. Hơn nữa, chúng tôi có thể muốn băm được "trải ra". Nếu tôi muốn băm một số đối tượng thành 100 nhóm (vì vậy đầu ra của hàm băm của tôi là một số từ 0-99), thì tôi thường hy vọng rằng khoảng 1/100 đối tượng sẽ hạ cánh trong nhóm 0, khoảng 1/100 đất ở xô 1, v.v.
Khả năng chống va chạm mật mã : Đôi khi, điều này được thực hiện thậm chí xa hơn, ví dụ, trong mật mã tôi có thể muốn một hàm băm sao cho đối thủ khó tìm ra hai đầu vào khác nhau ánh xạ tới cùng một đầu ra.
Nén : Tôi thường muốn băm tùy ý - các đầu vào lớn xuống thành đầu ra có kích thước không đổi hoặc số lượng thùng cố định.
Xác định : Tôi có thể muốn một hàm băm có đầu ra không thay đổi giữa các lần chạy, tức là đầu ra của hàm băm trên cùng một đối tượng sẽ luôn giữ nguyên. Điều này có vẻ mâu thuẫn với tính đồng nhất ở trên, nhưng một giải pháp là chọn ngẫu nhiên hàm băm một lần và không thay đổi nó giữa các lần chạy.
Một số ứng dụng
Một ứng dụng phổ biến là trong các cấu trúc dữ liệu như bảng băm, đó là một cách để thực hiện từ điển. Ở đây, bạn phân bổ một số bộ nhớ, giả sử, 100 "xô"; sau đó, khi được yêu cầu lưu trữ một cặp (khóa, giá trị) trong từ điển, bạn băm khóa vào số 0-99 và lưu trữ cặp đó vào nhóm tương ứng trong bộ nhớ. Sau đó, khi bạn được yêu cầu tra cứu một khóa, bạn băm khóa đó thành một số 0-99 với cùng hàm băm và kiểm tra cái xô đó để xem khóa đó có ở đó không. Nếu vậy, bạn trả lại giá trị của nó.
Lưu ý rằng bạn cũng có thể triển khai từ điển theo những cách khác, chẳng hạn như với cây tìm kiếm nhị phân (nếu các đối tượng của bạn có thể so sánh được).
Một ứng dụng thực tế khác là tổng kiểm tra, đó là những cách để kiểm tra hai tệp giống nhau (ví dụ: tệp không bị hỏng từ phiên bản trước của nó). Vì các hàm băm rất khó có thể ánh xạ hai đầu vào vào cùng một đầu ra, nên bạn tính toán và lưu trữ một hàm băm của tệp đầu tiên, thường được biểu diễn dưới dạng một chuỗi. Hàm băm này rất nhỏ, có thể chỉ vài chục ký tự ASCII. Sau đó, khi bạn nhận được tệp thứ hai, bạn băm nó và kiểm tra xem đầu ra có giống nhau không. Nếu vậy, gần như chắc chắn đó là cùng một tệp byte-for-byte.
Một ứng dụng khác là về mật mã, trong đó các giá trị băm này khó "đảo ngược" - nghĩa là, với đầu ra và hàm băm, sẽ rất khó tính toán để tìm ra (các) đầu vào dẫn đến đầu ra đó. Một cách sử dụng này là cho mật khẩu: Thay vì lưu trữ mật khẩu, bạn lưu trữ mật mã băm của mật khẩu (có thể với một số thành phần khác). Sau đó, khi người dùng nhập mật khẩu, bạn tính toán hàm băm của nó và kiểm tra xem nó có khớp với hàm băm chính xác không; Nếu vậy, bạn nói mật khẩu là chính xác. (Bây giờ ngay cả những người có thể nhìn và tìm ra hàm băm được lưu trên máy chủ cũng không có thời gian dễ dàng giả vờ là người dùng.) Ứng dụng này có thể là trường hợp đầu ra dài hơn hoặc dài hơn đầu vào, vì đầu vào quá ngắn