2010-06-17 30 views
15

Một số cách đơn giản để băm số nguyên 32 bit (ví dụ: địa chỉ IP, ví dụ: Unix time_t, v.v.) xuống số nguyên 16 bit?Hash 32bit int đến 16bit int?

Ví dụ: hash_32b_to_16b(0x12345678) có thể trả lại 0xABCD.

Hãy bắt đầu với điều này như một giải pháp dụ khủng khiếp nhưng chức năng:

function hash_32b_to_16b(val32b) { 
    return val32b % 0xffff; 
} 

Câu hỏi là cụ thể về JavaScript, nhưng cảm thấy tự do để thêm bất kỳ giải pháp ngôn ngữ trung tính, tốt nhất là không sử dụng các hàm thư viện.

Ngữ cảnh cho câu hỏi này là tạo ID duy nhất (ví dụ: ID 64 bit có thể bao gồm một số băm 16 bit có giá trị 32 bit khác nhau). Tránh va chạm là quan trọng.

Đơn giản = tốt. Wacky + obfuscated = vui.

+1

XOR cao 2 byte với 2 byte thấp? 0x1234 XOR 0x5678. Nhưng bạn không thể gắn thẻ câu hỏi bằng 'mật mã' và yêu cầu một cái gì đó như thế này ... –

+0

@Remus: Tại sao tôi không thể gắn thẻ nó 'mật mã'?Đây không phải là một câu hỏi liên quan đến mật mã và cực kỳ đơn giản? P.S. Tại sao không đăng bình luận của bạn như một câu trả lời? – dkamins

+0

Tới điểm của Remus, tôi đồng ý rằng đây không phải là về mật mã. Nếu tôi đang suy nghĩ về quyền này, băm 16 bit của bạn sẽ ánh xạ tới một trong hai số nguyên 32 bit. Tôi tò mò về vấn đề cụ thể mà bạn đang cố gắng giải quyết, và tôi hy vọng nó không liên quan gì đến an ninh. –

Trả lời

2

Điều này phụ thuộc vào bản chất của các số nguyên. Nếu chúng có thể chứa một số mặt nạ bit, hoặc có thể khác nhau theo hai lũy thừa, thì các XOR đơn giản sẽ có xác suất va chạm cao. Bạn có thể thử một cái gì đó như (i>>16)^((i&0xffff) * p) với p là số nguyên tố.

Các băm bảo mật như MD5 đều tốt, nhưng chúng rõ ràng là quá mức cần thiết ở đây. Bất cứ điều gì phức tạp hơn CRC16 là quá mức cần thiết.

+0

Đây là một điểm thú vị và dường như có liên quan đến địa chỉ IP băm, phải không? – dkamins

+0

Có. Đối với các giá trị thời gian i & 0xffff thường là đủ. (hy vọng rằng không có giấc ngủ (65536), bất cứ nơi nào :)) – Rotsor

+0

Có bất kỳ số nguyên cố định nào đủ không? Tại sao điều này hoạt động? – dkamins

4

Tôi nghĩ đây là điều tốt nhất bạn sẽ nhận được. Bạn có thể nén các mã để một dòng duy nhất nhưng var của đang có bây giờ như tài liệu:

function hash_32b_to_16b(val32b) { 
    var rightBits = val32b & 0xffff; // Left-most 16 bits 
    var leftBits = val32b & 0xffff0000; // Right-most 16 bits 

    leftBits = leftBits >>> 16; // Shift the left-most 16 bits to a 16-bit value 

    return rightBits^leftBits; // XOR the left-most and right-most bits 
} 

Với các thông số của vấn đề, giải pháp tốt nhất sẽ có mỗi băm 16-bit tương ứng với chính xác 2^16 số 32 bit. Nó cũng sẽ IMO băm tuần tự 32-bit số khác nhau. Trừ khi tôi đang thiếu một cái gì đó, tôi tin rằng giải pháp này làm hai điều đó.

Tôi cho rằng bảo mật không thể xem xét trong vấn đề này, vì giá trị băm chỉ là quá ít bit. Tôi tin rằng giải pháp tôi đã cung cấp thậm chí phân phối số 32-bit đến 16-bit băm

+0

Tại sao bạn nghĩ điều này là tốt nhất? Tôi nghĩ rằng nó có thể nhận được rất nhiều va chạm với những con số hữu ích và thường xuyên. – Rotsor

+1

Đây không phải là ý tưởng hay nhất. Lý do là địa chỉ IP thường được gán làm mạng con liền kề. Điều này có nghĩa là nếu địa chỉ IP A.B.C.D tồn tại trên một mạng thì A. (B^1) .C.D và A.B.C. (D^1) có nhiều khả năng tồn tại hơn và sẽ nhận được cùng một băm. Rõ ràng mọi băm sẽ có nhiều va chạm. Nhưng lược đồ của bạn sẽ có nhiều va chạm hơn bạn mong đợi từ các số nguyên 32 bit băm được chọn thống nhất. Bạn sẽ nhận được kết quả tốt hơn bằng cách khuấy động các bit nhiều hơn một chút. – sigfpe

+1

tiêu chí bạn đã sử dụng để đánh giá chất lượng của hàm băm, giữ ngay cả đối với hàm băm đơn giản: hash = val & 0xffff. Tuy nhiên, các hàm này có xác suất va chạm khác nhau trên dữ liệu thực tế. – Rotsor

0

Something đơn giản như thế này ....

function hash_32b_to_16b(val32b) {  
    var h = hmac(secretKey, sha512); 
    var v = val32b; 
    for(var i = 0; i < 4096; ++i) 
     v = h(v); 
    return v % 0xffff; 
} 
+0

Tại sao 4096 lần? – dkamins

+2

Để làm chậm nó xuống. Đây là một kỹ thuật phổ biến cho mật khẩu băm, để làm cho nó đơn đặt hàng của cường độ khó khăn hơn để tạo ra một bảng cầu vồng hoặc mật khẩu bạo lực. – yfeldblum

2

tôi sẽ nói chỉ áp dụng một tiêu chuẩn như băm SHA1 hoặc md5 và sau đó lấy 16 bit cuối cùng.

+0

Có thể có sự cố với luồng đầu vào ngắn (như 4 byte) cho sha1 hoặc md5 không? – dkamins

+0

sh1 và md5 thường không có sẵn trong môi trường JavaScript. Có các phiên bản kém an toàn hơn nhưng rất đơn giản hóa có thể diễn đạt trong một vài dòng JS không? – dkamins

2

Giả sử bạn mong đợi các bit quan trọng nhất để 'thay đổi' nhiều nhất, tôi nghĩ bạn có thể sẽ nhận được phân phối đủ tốt bằng cách chỉ sử dụng 16 bit thấp hơn của giá trị dưới dạng băm.

Nếu các số bạn sắp băm sẽ không có loại phân phối đó, thì bước bổ sung xor-ing trong 16 bit trên có thể hữu ích. Tất nhiên, gợi ý này là nếu bạn dự định sử dụng băm chỉ cho một số loại lược đồ tìm kiếm/lưu trữ và không tìm kiếm các thuộc tính liên quan đến mật mã của khả năng không đoán trước và không đảo ngược (trong đó xor đề xuất -ing không thực sự mua cho bạn một trong hai).

Các vấn đề liên quan