2009-04-29 17 views
30

thể trùng lặp:
How do I generate a hashcode from a byte array in c#C# Tạo một hash cho một mảng byte hoặc hình ảnh

Trong C#, tôi cần phải tạo ra một Hash của một hình ảnh để đảm bảo nó là duy nhất trong lưu trữ .

Tôi có thể dễ dàng chuyển đổi nó thành một mảng byte, nhưng không chắc chắn cách tiếp tục từ đó.

Có bất kỳ lớp nào trong khuôn khổ .NET có thể hỗ trợ tôi hay bất kỳ ai biết về một số thuật toán hiệu quả để tạo một băm duy nhất như vậy là ?

Trả lời

43

Có rất nhiều nhà cung cấp băm trong .NET tạo các băm mật mã - điều này làm hài lòng tình trạng của bạn rằng chúng là duy nhất (đối với hầu hết các mục đích chống va chạm). Họ là tất cả cực kỳ nhanh chóng và băm chắc chắn sẽ không phải là nút cổ chai trong ứng dụng của bạn trừ khi bạn đang làm nó một nghìn lần hơn.

Cá nhân tôi thích SHA1:

string hash; 
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) 
{ 
    hash = Convert.ToBase64String(sha1.ComputeHash(byteArray)); 
} 

Ngay cả khi người ta nói một phương pháp có thể chậm hơn so với khác, đó là tất cả trong điều kiện tương đối. Một chương trình xử lý ảnh chắc chắn sẽ không nhận thấy quá trình micro giây tạo ra hashsum.

Và liên quan đến va chạm, vì hầu hết các mục đích, điều này cũng không liên quan. Ngay cả các phương thức "lỗi thời" như MD5 vẫn rất hữu ích trong hầu hết các tình huống. Chỉ khuyên bạn không nên sử dụng nó khi bảo mật hệ thống của bạn dựa trên để tránh xung đột.

+2

Rex I ' m chắc chắn bạn nhận thức được điều này, nhưng như @AdamRobinson lưu ý, không có băm (bao gồm cả băm mật mã .NET chẳng hạn như SHA1) có thể đảm bảo tính duy nhất, miễn là băm là một bản đồ nhiều người, ví dụ nếu có ít ha shcodes hơn đầu vào có thể. – Spike0xff

+2

@ Spike0xff trong phần mềm khi chúng ta nói "duy nhất", nó được hiểu là có nghĩa là "duy nhất đủ". Tôi không thấy bất kỳ dấu hiệu nào cho thấy bất kỳ ai trong chủ đề này đều nhầm lẫn về điều đó. –

+2

Mối quan tâm của tôi không chỉ với những người đăng bài, mà với tất cả những người đọc, và tôi không nghĩ bạn nhất thiết sẽ thấy bất kỳ dấu hiệu nào nếu họ bối rối. Và tôi nghĩ bạn có nghĩa là "Tôi hy vọng nó sẽ được hiểu là có nghĩa là" bởi vì đó không phải là định nghĩa trong từ điển, cũng không phải là cách tôi muốn nói hay hiểu nó. Có lẽ bạn có thể trích dẫn một nguồn có uy tín? – Spike0xff

2

Bạn có thể sử dụng bất kỳ thuật toán băm tiêu chuẩn nào, nhưng việc bẻ khóa không thể đảm bảo tính duy nhất về mặt kỹ thuật. Hashing được thiết kế để trở thành một mã thông báo tương đối nhanh và/hoặc nhỏ để có thể xem liệu một phần dữ liệu có giống như một phần dữ liệu khác hay không. Nó hoàn toàn có thể cho các bộ dữ liệu hoàn toàn khác nhau để tạo ra cùng một giá trị băm, mặc dù có thể tạo ra những thuật toán này là rất khó.

Tất cả điều đó sang một bên, để kiểm tra danh tính có khả năng, MD5 khá nhanh. SHA đáng tin cậy hơn (MD5 đã bị tấn công, vì vậy không nên sử dụng để bảo mật), nhưng nó cũng chậm hơn.

3

Tạo phiên bản mới của SHA1CryptoServiceProvider mỗi lần bạn cần tính toán hàm băm không nhanh chút nào. Sử dụng cùng một trường hợp khá nhanh. Tôi vẫn muốn thực hiện một trong nhiều thuật toán CRC thay vì băm mật mã vì hàm băm được thiết kế cho mật mã không hoạt động tốt cho các kích thước băm rất nhỏ (32 bit), đó là những gì bạn muốn cho GetHash của mình() ghi đè (giả sử đó là những gì bạn muốn).

Kiểm tra liên kết này ra cho một ví dụ về tính toán CRC trong C#: http://sanity-free.org/134/standard_crc_16_in_csharp.html

T.B. lý do bạn muốn hash của bạn là nhỏ (16 hoặc 32 bit) là để bạn có thể so sánh chúng nhanh (đó là toàn bộ điểm có băm, nhớ không?). Có hàm băm được biểu diễn bằng một giá trị dài 256 bit được mã hóa dưới dạng chuỗi là khá điên về hiệu suất.

11

Phần Rex M's answer về cách sử dụng SHA1 để tạo băm là một hàm băm tốt (MD5 cũng là một tùy chọn phổ biến).đề nghị zvolkov về không liên tục tạo ra các nhà cung cấp crypto mới cũng là một trong những tốt (như là những gợi ý về việc sử dụng CRC nếu tốc độ là quan trọng hơn tính độc đáo hầu như bảo lãnh.

Tuy nhiên, đừng không sử dụng Encoding.UTF8.GetString() để chuyển đổi một byte [ ] thành một chuỗi (trừ khi tất nhiên bạn biết từ ngữ cảnh rằng nó là hợp lệ UTF8) .Đối với một, nó sẽ reject invalid surogates. Một phương pháp đảm bảo luôn cung cấp cho bạn một chuỗi hợp lệ từ một byte [] là Convert.ToBase64String().

+0

Cảm ơn, bạn hoàn toàn đúng ở đó. Trong thực tế đó là những gì tôi luôn luôn làm, nhưng tôi đã ném xuống mẫu đó ra khỏi đầu của tôi và đã làm các byte đầu tiên [] - to-string mà đến tâm trí. –

+0

Cảm ơn những người đứng đầu Jonathan, cảm ơn vì đã chỉnh sửa Rex – johnc

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