2011-04-15 40 views
5

Tôi là một chút của một newbie trong Java và tôi đang cố gắng thực hiện tính toán MAC trên một tệp. Vì kích thước của tệp không được biết trong thời gian chạy nên tôi không thể tải tất cả tệp vào bộ nhớ. Vì vậy, tôi đã viết mã để nó sẽ đọc trong bit (4k trong trường hợp này). Sự cố tôi gặp phải là tôi đã thử tải toàn bộ tệp vào bộ nhớ để xem liệu cả hai phương pháp có tạo ra cùng một giá trị băm hay không. Tuy nhiên họ dường như được sản xuất băm khác nhauTập tin đọc Java vào bộ nhớ và cách không làm nổ bộ nhớ

Dưới đây là các bit theo mã bit:

FileInputStream fis = new FileInputStream("sbs.dat"); 
byte[] file = new byte[4096]; 
m = Mac.getInstance("HmacSHA1"); 
int i=fis.read(file); 
m.init(key); 
while (i != -1) 
{ 
    m.update(file); 
    i=fis.read(file); 
} 
mac = m.doFinal(); 

Và đây là tất cả cùng một lúc tiếp cận:

File f = new File("sbs.dat"); 
long size = f.length(); 
byte[] file = new byte[(int) size]; 
fis.read(file); 
m = Mac.getInstance("HmacSHA1"); 
m.init(key); 
m.update(file); 
mac = m.doFinal(); 

nên không cả hai đều tạo ra cùng bảng băm ?

Tuy nhiên, câu hỏi là chung chung hơn. Mã số 1 có đúng cách để tải một tệp vào bộ nhớ thành các phần và thực hiện bất cứ điều gì chúng ta muốn làm bên trong chu kỳ trong khi không? (socket gửi, mật mã một tập tin, vv ...). Câu hỏi này hữu ích vì mọi hướng dẫn tôi đã thấy chỉ tải mọi thứ cùng một lúc ...

Cập nhật: Làm việc :-D. Cách tiếp cận này có hoạt động đúng cách để gửi một tập tin theo từng phần thông qua một ổ cắm?

Trả lời

4

Chức năng read sẽ không nhất thiết phải lấp đầy toàn bộ mảng của bạn. Vì vậy, bạn cần kiểm tra xem có bao nhiêu byte đã trở về từ hàm read và chỉ sử dụng nhiều byte trong bộ đệm của bạn.

5

No. Bạn không đảm bảo rằng trong fis.read(file) sẽ đọc file.length byte. Đây là lý do tại sao read() trả về một int để cho bạn biết số byte thực sự đã đọc.

Bạn thay vào đó nên làm điều này:

m.init(key); 
int i=fis.read(file); 

while (i != -1) 
{ 
    m.update(file, 0, i); 
    i=fis.read(file); 
} 

lợi dụng Mac.update(byte[] data, int offset, int len) phương pháp cho phép bạn chỉ định chiều dài của dữ liệu thực tế ở trong mảng byte [].

+0

Doh. Tôi cảm thấy như một thằng ngốc, tôi hoàn toàn quên rằng có 3 phương thức cập nhật trong các lớp Mac. Tuy nhiên, tôi vẫn sẽ mất nhiều giờ xung quanh một cái gì đó đơn giản. Gonna thử nó, nhưng nó có vẻ đúng. – ptguy

1

Giống như Jason LeBrun nói - Phương pháp đọc sẽ không phải lúc nào cũng đọc số byte được chỉ định. Ví dụ: Bạn nghĩ điều gì sẽ xảy ra nếu tệp không chứa bội số của 4096 byte?

tôi sẽ đi cho một cái gì đó như thế này:

 FileInputStream fis = new FileInputStream(filename); 
     byte[] buffer = new byte[buffersize]; 
     Mac m = Mac.getInstance("HmacSHA1"); 
     m.init(key); 

     int n; 
     while ((n = fis.read(buffer)) != -1) 
     { 
      m.update(buffer, 0, n); 
     } 
     byte[] mac = m.doFinal(); 
Các vấn đề liên quan