Hàm băm

**Hàm băm** (tiếng Anh: *hash function*) là giải thuật nhằm sinh ra các **giá trị băm** tương ứng với mỗi **khối dữ liệu** (có thể là một chuỗi ký tự, một đối tượng trong lập trình hướng đối tượng, v.v...). **Giá trị băm** đóng vai gần như một **khóa** để phân biệt các **khối dữ liệu**, tuy nhiên, người ta chấp nhận **hiện tượng trùng khóa** hay còn gọi là đụng độ và cố gắng cải thiện giải thuật để giảm thiểu sự đụng độ đó. Hàm băm thường được dùng trong bảng băm nhằm giảm **chi phí tính toán** khi tìm một **khối dữ liệu** trong một tập hợp (nhờ việc so sánh các **giá trị băm** nhanh hơn việc so sánh những *khối dữ liệu* có kích thước lớn).

Vì tính thông dụng của bảng băm, ngày nay, đa số ngôn ngữ lập trình đều cung cấp thư viện ứng dụng bảng băm, thường gọi là thư viện collection trong đó có các vấn đề như: tập hợp (collection), danh sách (list), bảng(table), ánh xạ (mapping), từ điển (dictionary). Thông thường, các lập trình viên chỉ cần viết hàm băm cho các đối tượng nhằm tích hợp với thư viện bảng băm đã được xây dựng sẵn.

Một hàm băm tốt phải thỏa mãn các điều kiện sau:
* Tính toán nhanh.
* Các khoá được phân bố đều trong bảng.
* Ít xảy ra đụng độ.
* Xử lý được các loại khóa có kiểu dữ liệu khác nhau.

## Ứng dụng
Các hàm băm được ứng dụng trong nhiều lĩnh vực, chúng thường được thiết kế phù hợp với từng ứng dụng. Ví dụ, các hàm băm mật mã học giả thiết sự tồn tại của một đối phương - người có thể cố tình tìm các dữ liệu vào với cùng một giá trị băm. Một hàm băm tốt là một phép biến đổi "một chiều", nghĩa là không có một phương pháp thực tiễn để tính toán được dữ liệu vào nào đó tương ứng với giá trị băm mong muốn, khi đó việc giả mạo sẽ rất khó khăn. Một hàm một chiều mật mã học điển hình không có tính chất hàm đơn ánh và tạo nên một hàm băm hiệu quả; một hàm trapdoor mật mã học điển hình *là* hàm đơn ánh và tạo nên một hàm ngẫu nhiên hiệu quả.

Bảng băm, một ứng dụng quan trọng của các hàm băm, cho phép tra cứu nhanh một bản ghi dữ liệu nếu cho trước *khóa* của bản ghi đó (Lưu ý: các khóa này thường không bí mật như trong mật mã học, nhưng cả hai đều được dùng để "mở khóa" hoặc để truy nhập thông tin.) Ví dụ, các khóa trong một từ điển điện tử Anh-Anh có thể là các từ tiếng Anh, các bản ghi tương ứng với chúng chứa các định nghĩa. Trong trường hợp này, hàm băm phải ánh xạ các xâu chữ cái tới các chỉ mục của mảng nội bộ của bảng băm.

Các hàm băm dành cho việc phát hiện và sửa lỗi tập trung phân biệt các trường hợp mà dữ liệu đã bị làm nhiễu bởi các quá trình ngẫu nhiên. Khi các hàm băm được dùng cho các giá trị tổng kiểm, giá trị băm tương đối nhỏ có thể được dùng để kiểm chứng rằng một file dữ liệu có kích thước tùy ý chưa bị sửa đổi. Hàm băm được dùng để phát hiện lỗi truyền dữ liệu. Tại nơi gửi, hàm băm được tính cho dữ liệu được gửi, giá trị băm này được gửi cùng dữ liệu. Tại đầu nhận, hàm băm lại được tính lần nữa, nếu các giá trị băm không trùng nhau thì lỗi đã xảy ra ở đâu đó trong quá trình truyền. Việc này được gọi là kiểm tra dư (*redundancy check*).

Các hàm băm còn được ứng dụng trong việc nhận dạng âm thanh, chẳng hạn như xác định xem một file MP3 có khớp với một file trong danh sách một loại các file khác hay không.

Thuật toán tìm kiếm xâu Rabin-Karp là một thuật toán tìm kiếm xâu ký tự tương đối nhanh, với thời gian chạy trung bình O(n). Thuật toán này dựa trên việc sử dụng băm để so sánh xâu.

## Lịch sử
Từ "băm" cho ta liên tưởng đến nghĩa thường dùng của nó (băm nhỏ ra rồi làm xáo trộn), cho ta hiểu được phần nào đó việc hàm băm xáo trộn dữ liệu đầu vào để tạo ra giá trị băm. Trong nghiên cứu của mình về nguồn gốc chính xác của thuật ngữ này, Donald Knuth ghi nhận rằng, mặc dù Hans Peter Luhn của IBM có vẻ là người đầu tiên sử dụng khái niệm về hàm băm trong một bản ghi nhớ nội bộ vào tháng 1 năm 1953, bản thân thuật ngữ này lại không xuất hiện trong các tài liệu được xuất bản cho đến tận cuối những năm 1960. Thuật ngữ xuất hiện trong cuốn sách *Digital Computer System Principles* của Herbert Hellerman, dù cho khi đó nó đã là một thuật ngữ chuyên ngành (jargon) được sử dụng rộng rãi."

## Tham khảo

## Liên kết ngoài
* Các hàm băm cho mục đích tổng quát (C/C++/Pascal/Java/Python/Ruby)
* Các hàm băm dành cho tra cứu bảng băm của Bob Jenkins
* mã nguồn hàm LOOKUP3 của Bob Jenkins
* Hàm băm Goulburn của Mayur Patel
* Các hàm băm của Paul Hsieh
* HSH 11/13 của Herbert Glarner
* Công cụ trực tuyến mã hóa/giải mã dữ liệu dạng Char (ASCII), HEX, Binary, Base64, v.v... bằng các thuật toán băm MD2, MD4, MD5, SHA1+2 v.v..