我想從內存中讀取文件並將其分割爲1KB塊。使用java讀取文件爲1KB塊
該程序的功能是從內存中讀取文件(視頻文件),然後將其分割爲1KB的塊。然後使用SHA-256對最後一個塊進行散列並將散列追加到最後一個塊。然後它將第二個最後一個塊和附加散列的散列計算在一起,然後將該散列附加到其前一個塊。這繼續下去,直到第一個塊,它將有第二個塊的散列附加到它。
我只需要第一個塊和它的附加散列的散列。我試圖用兩種方式來實現這一點,但我認爲我做錯了。有人能告訴我我做錯了什麼嗎?我一直堅持6天沒有解決方案。我在下面粘貼了兩個我的實現。任何幫助,將不勝感激。
我已經讀取了整個文件,並嘗試在下面的嘗試中手動將字節數組拆分爲1KB塊。
package com.test;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ReadFileByteByByte {
public static void main(String[] args) throws Exception {
InputStream inStream = null;
BufferedInputStream bis = null;
try{
inStream = new FileInputStream("C:\\a.mp4");
bis = new BufferedInputStream(inStream);
int numByte = bis.available();
byte[] buf = new byte[numByte];
bis.read(buf, 0, numByte);
System.out.println(numByte/1024);
ArrayList<byte[]> a = new ArrayList<>();
ArrayList<byte[]> b = new ArrayList<>();
for(int i=0,j=0;i<buf.length;i++,j++){
byte[] buf2 = new byte[1057];
buf2[j] = buf[i];
if(i%1024==1023){
a.add(buf2);
j=0;
}
}
for(int i=a.size()-1,j=-1;i>=0;i--,j++){
MessageDigest digest = MessageDigest.getInstance("SHA-256");
if(i==a.size()-1){
byte[] hash = digest.digest(a.get(i));
byte[] dest = new byte[a.get(i).length+hash.length];
System.arraycopy(a.get(i-1), 0, dest, 0, a.get(i-1).length);
System.arraycopy(hash, 0, dest, a.get(i-1).length, hash.length);
b.add(dest);
}
else{
byte[] hash = digest.digest(b.get(0));
if(i!=0){
byte[] dest = new byte[a.get(i-1).length+hash.length];
System.arraycopy(a.get(i-1), 0, dest, 0, a.get(i-1).length);
System.arraycopy(hash, 0, dest, a.get(i-1).length, hash.length);
b.clear();
b.add(dest);
}else{
System.out.println(bytesToHex(hash));}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(inStream!=null)
inStream.close();
if(bis!=null)
bis.close();
}
}
final protected static char[] hexArray = "ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
我在這次嘗試中直接讀取了1KB的塊。在這種嘗試中,出於某種原因哈希需要很長時間。
package com.test;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ReadFileByteByByte2 {
public static void main(String[] args) throws Exception {
InputStream inStream = null;
BufferedInputStream bis = null;
try{
inStream = new FileInputStream("C:\\aa.mp4");
bis = new BufferedInputStream(inStream);
int numByte = bis.available();
System.out.println(numByte/1024);
ArrayList<byte[]> a = new ArrayList<>();
ArrayList<byte[]> b = new ArrayList<>();
byte[] buf = new byte[numByte];
int ii=0;
while(bis.read(buf, ii, 1024)!=-1){
a.add(buf);
}
System.out.println(a.size());
for(int i=a.size()-1,j=-1;i>=0;i--,j++){
MessageDigest digest = MessageDigest.getInstance("SHA-256");
if(i==a.size()-1){
System.out.println(a.get(i).toString());
byte[] hash = digest.digest(a.get(i));
byte[] dest = new byte[a.get(i).length+hash.length];
System.arraycopy(a.get(i-1), 0, dest, 0, a.get(i-1).length);
System.arraycopy(hash, 0, dest, a.get(i-1).length, hash.length);
b.add(dest);
}
else{
System.out.println(i);
byte[] hash = digest.digest(b.get(0));
if(i!=0){
byte[] dest = new byte[a.get(i-1).length+hash.length];
System.arraycopy(a.get(i-1), 0, dest, 0, a.get(i-1).length);
System.arraycopy(hash, 0, dest, a.get(i-1).length, hash.length);
b.clear();
b.add(dest);
}else{
System.out.println(bytesToHex(hash));}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(inStream!=null)
inStream.close();
if(bis!=null)
bis.close();
}
}
final protected static char[] hexArray = "ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
任何幫助真的很感激。提前致謝。
嗨EJP,首先感謝您的快速回復。您建議的readFully()不適用於我,因爲我試圖散列最後一個塊,因爲它沒有任何填充。無論如何,我實施它的方式是錯誤的,我能弄明白。我無法理解摘要的update()方法,如果您可以提供一個代碼示例,那就太好了。最後,正向散列的思想對我不起作用,因爲我不使用密鑰交換,因此如果整個塊和散列都改變了,那麼用戶就無法區分這種差異。再次感謝您的快速回復。 – anirudh
如上所述,您需要在最後一個塊上使用'readFully()'*除*。 'update()'方法可以在最後的'doFinal()'方法之前調用任意次數。 'digest()'方法只是一個簡寫。 – EJP
噢......好吧......我想我沒有正確閱讀......謝謝.. – anirudh