2010-02-10 120 views
25

Bảng băm được cho là cách nhanh nhất/tốt nhất để lưu trữ/truy xuất dữ liệu.Cách viết hàm băm trong C?

sự hiểu biết của tôi về một bảng băm, băm như sau (Xin vui lòng sửa tôi nếu tôi sai hoặc Vui lòng thêm Nếu có bất cứ điều gì nhiều hơn):

  • Một Hash Table là gì, nhưng một mảng (một hoặc nhiều chiều) để lưu trữ các giá trị.
  • Hashing là quá trình tìm chỉ mục/vị trí trong mảng để chèn/truy xuất dữ liệu. Bạn lấy một (các) mục dữ liệu và chuyển nó thành một khóa (s) cho hàm băm và bạn sẽ nhận được chỉ mục/vị trí để chèn/lấy dữ liệu.

Tôi có một câu hỏi:

Là hàm băm dùng để lưu trữ/lấy dữ liệu từ một KHÁC hàm băm mật mã được sử dụng trong ứng dụng bảo mật để xác thực như MD5, HMAC, SHA-1, vv ..?

Chúng khác nhau theo cách nào?

  • Cách viết hàm băm trong C?
  • Có một số tiêu chuẩn hoặc nguyên tắc cho nó không?
  • Làm cách nào để đảm bảo rằng đầu ra của hàm băm tức là, chỉ mục không nằm ngoài phạm vi?

Thật tuyệt vời nếu bạn có thể đề cập đến một số liên kết tốt để hiểu những điều này tốt hơn.

+1

Phạm vi có thể bị giới hạn với toán tử mô-đun (%). – tur1ng

+23

Trang tiếp theo có một số triển khai chức năng băm mục đích chung được triển khai trong C (và nhiều ngôn ngữ khác): http://partow.net/programming/hashfunctions/index.html –

Trả lời

4

Bob Jenkins đã viết một mô tả chuyên sâu về hàng hóa của mình, nếu hơi lỗi thời, hash function. Bài viết này có các liên kết đến các hàm băm mới hơn, tốt hơn, nhưng việc ghi lại đề cập đến các mối quan tâm của việc xây dựng một hàm tốt.

Ngoài ra, hầu hết các triển khai bảng băm thực sự sử dụng một danh sách liên kết để giải quyết xung đột. Nếu bạn muốn chỉ sử dụng một mảng thì hàm băm cần kiểm tra các xung đột và tạo ra một chỉ mục băm mới.

Các hàm băm mật mã mà bạn đề cập có thể được sử dụng làm hàm băm cho bảng băm, nhưng chúng chậm hơn nhiều so với hàm băm được thiết kế cho bảng băm. Tốc độ làm cho các cuộc tấn công bạo lực trở nên dễ dàng hơn.

11

Băm mật mã nhấn mạnh việc làm cho mọi người cố ý tạo ra một vụ va chạm khó khăn. Đối với một bảng băm, sự nhấn mạnh là bình thường trên việc tạo ra sự lây lan hợp lý các kết quả một cách nhanh chóng. Như vậy, cả hai thường khá khác nhau (đặc biệt, băm mật mã thường là số nhiều hơn chậm hơn).

Đối với hàm băm điển hình, kết quả chỉ bị giới hạn bởi loại - ví dụ: nếu nó trả về một size_t, thì hoàn toàn tốt đẹp nếu nó trả về bất kỳ kích thước nào có thể là. Bạn có thể giảm phạm vi đầu ra đó xuống kích thước bảng của bạn (ví dụ: sử dụng phần còn lại chia cho kích thước bảng của bạn, số này thường phải là số nguyên tố).

Như một ví dụ, một hàm băm bình thường khá điển hình có thể giống như thế:

// warning: untested code. 
size_t hash(char const *input) { 

    const int ret_size = 32; 
    size_t ret = 0x555555; 
    const int per_char = 7; 

    while (*input) { 
     ret ^= *input++; 
     ret = ((ret << per_char) | (ret >> (ret_size - per_char)); 
    } 
    return ret; 
} 

Ý tưởng cơ bản ở đây là phải có tất cả các bit của chuỗi đầu vào ảnh hưởng đến kết quả, và (càng nhanh càng tốt) có tất cả các bit của kết quả bị ảnh hưởng bởi ít nhất một phần của đầu vào. Lưu ý rằng tôi không đặc biệt đề xuất điều này như một hàm băm tuyệt vời - chỉ cố gắng minh họa một số khái niệm cơ bản về những gì bạn đang cố gắng thực hiện.

+0

Chức năng băm mật mã không nhất thiết phải chậm. Cụ thể, hàm băm MD4 được báo cáo là nhanh hơn CRC32 trên một số nền tảng (dựa trên ARM, tôi nghĩ). Tuy nhiên, các hàm băm mật mã có xu hướng có chi phí cố định lớn, có nghĩa là chúng sẽ chậm cho các thông điệp đầu vào nhỏ. Một chức năng như MD4 đạt được băng thông xử lý rất cao (hơn 600 MB/s trên CPU Intel 2,4 GHz của tôi) khi kích thước đầu vào vượt quá 1 KB hoặc hơn. Tuy nhiên, đối với các đầu vào nhỏ (dưới 54 byte), PC của tôi vẫn tính 8 triệu MD4 mỗi giây (với một lõi đơn). –

+0

@Thomas: Đầu tiên, trong khi CRC32 có thể nhanh chóng hợp lý, hầu hết các hàm băm đều nhanh hơn một chút. Thứ hai, trong khi nó đã được dự định là một băm mật mã, MD4 không thực sự đủ điều kiện nữa. Nó đã bị phá vỡ một cách toàn diện nhiều năm trước đây - tạo ra một vụ va chạm có cùng tốc độ với việc tạo ra băm ban đầu. Xem: http://www.stachliu.com/md4coll.c để thực hiện. –

+0

Tôi biết rằng MD4 đã bị hỏng, nhưng đối với các mục đích không mã hóa (những cái mà chúng ta đang nói đến) MD4 là khá tốt; nếu các xung đột có chủ ý là một vấn đề, thì mọi hàm băm mật mã không bị loại trừ, theo định nghĩa. Khi không có vấn đề bảo mật, MD4 có thể được hình dung ít nhất. Một số hệ thống ngang hàng sử dụng MD4 để xác định các phần tử tệp. Đối với các hàm mã hóa nhanh nhưng mạnh, có sự cạnh tranh liên tục để chọn một chức năng mới. Xem http://en.wikipedia.org/wiki/NIST_hash_function_competition để biết chi tiết (Tôi là đồng tác giả của một trong các ứng cử viên). –

0

Mục tiêu thiết kế khác nhau. Ví dụ:

Với ví dụ cryptographic hash functions, bạn không thể sử dụng hàm băm và hàm băm để xác định dữ liệu gốc hoặc bất kỳ dữ liệu nào khác có thể tạo ra cùng một giá trị băm.

Hàm băm được sử dụng với bảng băm & cấu trúc dữ liệu khác không cần các thuộc tính bảo mật như vậy. Nó thường đủ nếu hàm băm nhanh và nó sẽ phân phối tập hợp đầu vào đồng đều vào tập hợp các băm có thể (để tránh sự phân cụm/va chạm không cần thiết).