2012-02-17 19 views
7

Tôi đang sử dụng Java để tạo hàm băm MD5 cho một số tệp. Tôi cần phải tạo một MD5 cho một số tệp với tổng kích thước khoảng 1 gigabyte. Dưới đây là mã của tôi:Rất chậm để tạo MD5 cho tệp lớn bằng cách sử dụng Java

private String generateMD5(SequenceInputStream inputStream){ 
    if(inputStream==null){ 
     return null; 
    } 
    MessageDigest md; 
    try { 
     int read =0; 
     byte[] buf = new byte[2048]; 
     md = MessageDigest.getInstance("MD5"); 
     while((read = inputStream.read(buf))>0){ 
      md.update(buf,0,read); 
     } 
     byte[] hashValue = md.digest(); 
     return new String(hashValue); 
    } catch (NoSuchAlgorithmException e) { 
     return null; 
    } catch (IOException e) { 
     return null; 
    }finally{ 
     try { 
      if(inputStream!=null)inputStream.close(); 
     } catch (IOException e) { 
      // ... 
     } 
    } 

}

Điều này dường như chạy mãi mãi. Tôi làm cách nào để hiệu quả hơn?

+1

Pssh, 'inputStream' có thể không thể là' null' trong khối 'finally'. – BalusC

+1

IO không bị xáo trộn chậm, tin tức ở mức 11. –

Trả lời

18

Bạn có thể muốn sử dụng thư viện Fast MD5. Nó nhanh hơn nhiều so với nhà cung cấp MD5 tích hợp của Java và nhận được một băm đơn giản như:

String hash = MD5.asHex(MD5.getHash(new File(filename))); 

Hãy lưu ý rằng tốc độ chậm cũng có thể là do tệp I/O chậm.

11

Tôi viết lại mã của bạn với nio, mã có phần giống như dưới đây:

private static String generateMD5(FileInputStream inputStream){ 
    if(inputStream==null){ 

     return null; 
    } 
    MessageDigest md; 
    try { 
     md = MessageDigest.getInstance("MD5"); 
     FileChannel channel = inputStream.getChannel(); 
     ByteBuffer buff = ByteBuffer.allocate(2048); 
     while(channel.read(buff) != -1) 
     { 
      buff.flip(); 
      md.update(buff); 
      buff.clear(); 
     } 
     byte[] hashValue = md.digest(); 
     return new String(hashValue); 
    } 
    catch (NoSuchAlgorithmException e) 
    { 
     return null; 
    } 
    catch (IOException e) 
    { 
     return null; 
    } 
    finally 
    { 
     try { 
      if(inputStream!=null)inputStream.close(); 
     } catch (IOException e) { 

     } 
    } 
} 

Trên máy tính của tôi, nó mất khoảng 30 để tạo ra mã md5 cho một tập tin lớn, và dĩ nhiên tôi kiểm tra mã của bạn như tốt, kết quả chỉ ra rằng nio không cải thiện hiệu suất của chương trình.

Sau đó, tôi cố gắng dành thời gian cho io và md5 tương ứng, số liệu thống kê cho biết rằng tệp io chậm là nút cổ chai vì khoảng 5/6 thời gian được thực hiện cho io.

Bằng cách sử dụng thư viện MD5 nhanh được đề cập bởi @Sticky, chỉ mất 15 giây để tạo mã md5, cải tiến đáng chú ý.

0

Bất cứ khi nào tốc độ là sự cố và bạn tải xuống tệp từ URL muốn tính MD5 của nó cùng một lúc (tức là không lưu tệp, mở lại và đọc lại chỉ để lấy MD5), giải pháp của tôi tại https://stackoverflow.com/a/11189634/1082681 có thể hữu ích. Nó dựa trên đoạn mã của Bloodwulf ở đây trong chủ đề này (cảm ơn!) Và chỉ mở rộng nó một chút.