2016-03-09 15 views
6

Trong tài liệu String.hash dành cho iOS nó nói:Giá trị băm của Chuỗi có thể ổn định trên các bản phát hành iOS?

Bạn không nên dựa vào tài sản này có giá trị băm tương tự trên phiên bản của OS X.

(lạ tại sao họ lại nói về OS X trong Tài liệu iOS)

Vâng, tôi cần một chức năng phức tạp sẽ không thay đổi với bản phát hành iOS. Nó có thể được đơn giản Tôi không cần bất cứ điều gì giống như SHA. Có thư viện nào không?

Có một câu hỏi khác về điều này here nhưng câu trả lời được chấp nhận (và chỉ) có đơn giản chỉ ra rằng chúng ta nên tôn trọng ghi chú trong tài liệu.

+1

nếu nó có thể đơn giản, tại sao không sử dụng [MD5 hash] (http://stackoverflow.com/a/2018626/1219956) chỉnh sửa: [swift version] (http://stackoverflow.com/questions/24123518/ how-to-use-cc-md5-method-in-swift-language) – Fonix

+0

@ Fonix Vâng, đó có thể là giải pháp. Có rất nhiều câu trả lời cho câu hỏi mà bạn đang liên kết - bạn có thể giới thiệu bất kỳ câu hỏi nào có triển khai băm MD5 ổn định và nhanh chóng trong Swift không? – drasto

+0

xem liên kết thứ hai trong nhận xét đầu tiên của tôi, nhưng nếu không có nhiều giải pháp với một google nhanh chóng – Fonix

Trả lời

5

Đây là một băm phi crypto, cho Swift 3:

func strHash(_ str: String) -> UInt64 { 
    var result = UInt64 (5381) 
    let buf = [UInt8](str.utf8) 
    for b in buf { 
     result = 127 * (result & 0x00ffffffffffffff) + UInt64(b) 
    } 
    return result 
} 

Nó được bắt nguồn hơi từ C++ 11 constexpr

constexpr uint64_t str2int(char const *input) { 
    return *input      // test for null terminator 
    ? (static_cast<uint64_t>(*input) + // add char to end 
     127 * ((str2int(input + 1)  // prime 127 shifts left almost 7 bits 
       & 0x00ffffffffffffff))) // mask right 56 bits 
    : 5381;       // start with prime number 5381 
} 

Thật không may, hai không mang lại cùng một băm. Để làm điều đó bạn cần phải đảo ngược thứ tự iterator trong strHash:

for b in buf.reversed() {...} 

Nhưng điều đó sẽ chạy chậm hơn 13x, phần nào so sánh được với phần mở rộng djb2hash Chuỗi mà tôi nhận được từ https://useyourloaf.com/blog/swift-hashable/

Dưới đây là một số tiêu chuẩn, cho một triệu lần lặp:

hashValue execution time: 0.147760987281799 
strHash execution time: 1.45974600315094 
strHashReversed time: 18.7755110263824 
djb2hash execution time: 16.0091370344162 
sdbmhash crashed 

đối với C++, các str2Int là khoảng càng nhanh càng Swift 3 của hashValue:

str2int execution time: 0.136421 
Các vấn đề liên quan