2012-11-10 49 views
6

Tôi cần trích xuất một thông báo 8 byte từ chuỗi có độ dài thay đổi nên tôi đang tìm một thuật toán mà tôi sẽ triển khai trong c/C++. Đó sẽ là một phần của một thủ tục chữ ký kỹ thuật số trên một vi điều khiển, vì vậy nó phải là:Thuật toán hàm băm 8 byte nhẹ

  • ghi trong vài dòng mã, kể từ firmware phải được giữ càng ít càng tốt;
  • mức tiêu thụ tài nguyên thấp, expecially ram (tốt hơn ít hơn 100 byte);
  • đủ mạnh để thay đổi một ký tự đơn tại bất kỳ điểm nào của chuỗi sẽ thay đổi thông báo tổng thể.

Tôi đã xem xét các thuật toán hiện có như crc64 nhưng dường như chúng quá nặng đối với nền tảng của tôi.

+0

Có nhiều hàm băm khả dụng (và dễ tìm). Các chức năng hiện tại nào đã nhìn "gần" mục tiêu mong muốn và tại sao? Nếu chúng không được chấp nhận, tại sao? Có một số kết quả tốt/đọc cho một "hàm băm" đơn giản - trung thực, chỉ có yêu cầu thứ ba được đăng tải về bất kỳ mối quan tâm nào. Ngoài ra, kể từ khi CRC đã được đề cập, là mục tiêu một [chung] * băm * hoặc * checksum *? –

+0

Có lẽ điều này có thể hữu ích: http://en.wikipedia.org/wiki/List_of_hash_functions Có thể kiểm tra sphlib cũng như để làm rõ một cái gì đó 8 byte sẽ dẫn đến va chạm vì vậy điểm 3 của các yêu cầu của bạn không thể được thực hiện bởi BẤT K has băm thuật toán ít nhất không phải cho tất cả các chuỗi và 8 byte là khá thấp. –

+0

@pst: Tôi đã tính đến một số hàm băm hiện có cung cấp đầu ra 64 bit, nhưng ví dụ crc64 cần nhiều hơn 100 byte ram. Như tôi đã nói trong câu hỏi, mục đích là để có được một thông điệp tiêu hóa, do đó, một chức năng mã hóa sẽ tốt hơn. Tuy nhiên, tôi cần nó nhẹ hơn mạnh mẽ, vì vậy tôi đã tính đến các loại hàm băm khác. – etuardu

Trả lời

1

Như AndrewTomazos-Fathomling nói, nó không thể làm một băm an toàn trong 64 bit, vì vậy nếu đó là ý định của bạn sau đó lời khuyên của tôi là STOP, chọn một cuốn sách và đọc về băm mật mã an toàn.

Nếu bạn không có kế hoạch sử dụng băm bảo mật và bạn không quan tâm đến va chạm hoặc tấn công, thì câu trả lời mà anh ấy cung cấp cho bạn hoạt động tốt và bạn có thể chỉnh sửa số nguyên tố P1 và P2 nếu cần. Tôi sẽ cung cấp cho bạn một giải pháp thay thế khác cho phép bạn gắn thẻ băm và trộn lẫn nhiều thứ hơn.

// Disclaimer: I make no claims about the quality of this particular hash - it's 
// certainly not a cryptographically secure hash, nor should it *ever* be 
// construed as such. 

unsigned long long quickhash64(const char *str, unsigned long long mix = 0) 
{ // set 'mix' to some value other than zero if you want a tagged hash   
    const unsigned long long mulp = 2654435789; 

    mix ^= 104395301; 

    while(*str) 
     mix += (*str++ * mulp)^(mix >> 23); 

    return mix^(mix << 37); 
} 
+0

Tôi thích cái này tốt hơn bởi vì nó giữ sự nhạy cảm đối với tất cả các ký tự của chuỗi, những cái khác sử dụng ca làm mất ảnh hưởng của các ký tự đầu tiên của chuỗi sau một số lenghts nhất định. Bằng cách này tôi thấy rằng nó có thể được rút ngắn như, ví dụ, 'uint64_t mix, mulp = 2654435789; trong khi (* str) trộn^= mulp ** str ++; '. – etuardu

7

Không có cơ hội để thực hiện băm an toàn trong 64 bit. Ngay cả SHA-1 ở 160 bit được coi là lý thuyết bị hỏng. Bạn nên sử dụng SHA2-256 nếu bạn thực sự quan tâm đến việc ký số an toàn. Nếu bạn không quan tâm về an ninh và chỉ muốn có một hàm băm mà tránh va chạm không gây tranh cãi chỉ cần sử dụng những điều sau đây, nó là tốt:

constexpr uint64 P1 = 7; 
constexpr uint64 P2 = 31; 

uint64 hash = P1; 
for (const char* p = s; *p != 0; p++) { 
    hash = hash * P2 + *p; 
} 
+0

+1, mặc dù 'strlen' không phải là tên biến lớn trong chương trình C. :-P – ruakh

+1

Cảm ơn bạn đã trả lời, mặc dù điều này không thực sự lấp đầy điểm thứ ba của tôi: 'mystring1' =>' 10000786a32ed', 'mystring2' =>' 10000786a32ee'.Tôi cần một cái gì đó mà có thể "tuyên truyền" một chút thay đổi nhân vật duy nhất thông qua băm. – etuardu

+2

Bạn muốn những gì được gọi là "hiệu ứng tuyết lở", nhưng hãy tự hỏi tại sao bạn muốn điều này. Nó thực sự chỉ có ý nghĩa trong bối cảnh băm an toàn, và với chỉ 64 bit nó sẽ không bao giờ được an toàn chống lại một cuộc tấn công bạo lực. Bạn có thể nhận được nhiều bit lật hơn bằng cách sử dụng hai số nguyên tố lớn hơn cho P1 và P2, nhưng như tôi đã nói không có điểm. –

3

Đây là một phiên bản sửa đổi của một phiên bản 32 bit tôi tìm thấy trong tôi các tệp nguồn cũ

static unsigned long long llhash(const char *str) 
{ 
    unsigned long long hash = 5381; 
    int c; 

    while (c = *str++) 
     hash = ((hash << 5) + hash) + c; 

    return hash; 
} 

Nhưng băm sẽ luôn dẫn đến xung đột. Tất nhiên một số thuật toán tốt hơn các thuật toán khác.

Edit: tôi tìm thấy nguồn gốc của phiên bản 32 bit: http://www.cse.yorku.ca/~oz/hash.html

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