2012-03-27 59 views
1

嘗試一些能部分加密文件的東西。除了這個小問題,一切都很好。因爲某些原因。 flush方法一直工作到n> 52,其中n是循環數。你可以在解密方法中看到它。如果我將n fomr < 10更改爲< 53,它會刷新。我通過查看文件來測試它。直到53年才添加新的內容。但應該有。輸出流的刷新方法什麼都不做

public class DesEncrypter { 
Cipher ecipher; 
Cipher dcipher; 

DesEncrypter(SecretKey key) { 
    // Create an 8-byte initialization vector 
    byte[] iv = new byte[]{ 
     (byte)0x8E, 0x12, 0x39, (byte)0x9C, 
     0x07, 0x72, 0x6F, 0x5A 
    }; 
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); 
    try { 
     ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 
     dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 

     // CBC requires an initialization vector 
     ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); 
     dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); 
    } catch (java.security.InvalidAlgorithmParameterException e) { 
    } catch (javax.crypto.NoSuchPaddingException e) { 
    } catch (java.security.NoSuchAlgorithmException e) { 
    } catch (java.security.InvalidKeyException e) { 
    } 
} 

// Buffer used to transport the bytes from one stream to another 
byte[] buf = new byte[1024]; 

public void encrypt(InputStream in, OutputStream out) { 
    try { 
     // Bytes written to out will be encrypted 
     AppendableOutputStream out_append = new AppendableOutputStream(out); 

     OutputStream out_c = new CipherOutputStream(out_append, ecipher); 

     // Read in the cleartext bytes and write to out to encrypt 
     int numRead = 0; 
     int count = 0; 
     int max = 1024; 
     boolean first = true; 

     while ((numRead = in.read(buf, 0, max)) > 0) {     
      System.out.println("running Total: " + count); 
      count += numRead; 
      // if this read puts as at less than a meg, encrypt 
      if(count <= 1024*1024){ 
       System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count); 
       out_c.write(buf, 0, numRead); 
       // last encryption pass, close buffer and fix max 
       if(count == 1024*1024){ 
        // fix reading 1k in case max was decreased 
        max = 1024; 
        out_c.close(); 
       } 
       // if next read will go over a meg, read less than 1k 
       else if(count + max > 1024*1024) 
        max = 1024*1024 - count; 
      } 
      // past the first meg, don't encrypt 
      else{ 
       System.out.println("processed " + numRead + " of " + max +" bytes : total " + count); 
       out.write(buf, 0, numRead); 
      } 

     } 
     out.close(); 

    } catch (java.io.IOException e) {} 

} 

// Movies encrypt only 1 MB 128 passes. 

public void decrypt(InputStream in, OutputStream out) { 
    try { 
     // Bytes read from in will be decrypted 
     InputStream in_c = new CipherInputStream(in, dcipher); 

     // Read in the decrypted bytes and write the cleartext to out 
     int numRead = 0; 
     int count = 0; 
     int max = 1024; 

     while ((numRead = in_c.read(buf, 0, max)) > 0) { 
      count += numRead; 
      System.out.println("decrypted " + numRead + " of " + max +" bytes : total " + count); 
      out.write(buf, 0, numRead); 
      if(count + max > 1024*1024){ 
       max = 1024*1024 - count; 
      } 
      if(count == 1024*1024) 
       max = 0; 
     } 

     //in.skip(count); 
     int n = 0; 
     while((numRead = in.read(buf)) > 0 && n < 10){ 
     count += numRead; 
     System.out.println("processed " + numRead + " of 1024 bytes : total " + count); 
      out.write(buf,0,numRead); 
      //System.out.println("buf"+buf.length +" numered" + numRead+ " n"+n); 
      // If i look at the file after anything under n < 51 the file doesn't change. 
      n++; 

     } 
     out.flush(); 
     out.close(); 
    } catch (java.io.IOException e) { 
     System.out.println("AHHHHHHHH!!!!!!"); 
    } 
} 
+4

這絕不是一個好主意:catch(java.io.IOException e){}。空抓塊意味着你永遠不會知道是否有問題。至少打印堆棧跟蹤。我不喜歡看到這個:System.out.println(「AHHHHHHHH !!!!!!」);信息較少;打印堆棧跟蹤。 – duffymo 2012-03-27 18:28:28

+0

調試器是你的朋友。您應該使用它並查看該方法正在發生的情況。 – 2012-03-27 18:31:04

+0

我真誠地不明白這個問題。你說flush方法在n> 52之前工作,但直到53時才刷新,flush調用完全在循環之外,直到循環結束纔會運行。你能否澄清實際問題是什麼? – 2012-03-27 18:38:32

回答

1

由於給出的信息我只能推測。如果您在調用decrypt方法時指定了哪種類型的OutputStreamout,至少會非常有幫助。 flush()方法的行爲在不同的具體實現之間有所不同。

例如,如果輸出流剛好是一個CipherOutputStream,或連接到該類型的流的一些其他流,那麼對於其flush()方法的文檔指出以下(由我強調重要的部分):

通過強制將已封裝的密碼對象已經處理的任何緩衝輸出字節寫出來刷新此輸出流。 由封裝密碼緩衝並等待由其處理的任何字節都不會被寫出。例如,如果封裝密碼是分組密碼,並且使用其中一種寫入方法寫入的總字節數小於密碼的分組大小,則不會寫出字節,例如

這聽起來可能是你的問題的原因。但是,正如我所說的,瞭解有關您的特定類型的流的更多詳細信息會非常有幫助。

0

嗯,我在做什麼似乎解密方法中的輸入流與數據混亂。而不是在它被讀回時解密它,而是在它被處理回去時解密它。填充也弄亂了它。必須在解密方法中向1024 * 1024代碼添加額外的8個字節。 如果有人在意這裏是修改後的方法 謝謝大家的幫助。

public void encrypt(InputStream in, OutputStream out) { 
    try { 
     // Bytes written to out will be encrypted 
     AppendableOutputStream out_append = new AppendableOutputStream(out); 

     OutputStream out_c = new CipherOutputStream(out_append, ecipher); 

     // Read in the cleartext bytes and write to out to encrypt 
     int numRead = 0; 
     int count = 0; 
     int max = 1024; 
     boolean first = true; 

     while ((numRead = in.read(buf, 0, max)) > 0) {     
      //System.out.println("running Total: " + count); 
      count += numRead; 
      // if this read puts as at less than a meg, encrypt 
      if(count <= 1024*1024){ 
       //System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count); 
       out_c.write(buf, 0, numRead); 
       // last encryption pass, close buffer and fix max 
       if(count == 1024*1024){ 
        // fix reading 1k in case max was decreased 
        max = 1024; 
        out_c.close(); 
       } 
       // if next read will go over a meg, read less than 1k 
       else if(count + max > 1024*1024) 
        max = 1024*1024 - count; 
      } 
      // past the first meg, don't encrypt 
      else{ 
       //System.out.println("processed " + numRead + " of " + max +" bytes : total " + count); 
       out.write(buf, 0, numRead); 
      } 

     } 
     out.flush(); 

     out.close(); 

    } catch (java.io.IOException e) { 

     System.out.println("AHHHHHHHH!!!!!!111"); 

    } 

} 

// Movies encrypt only 1 MB 128 passes. 

public void decrypt(InputStream in, OutputStream out) { 
    try { 
     // Bytes written to out will be decrypted 
     AppendableOutputStream out_append = new AppendableOutputStream(out); 
     System.out.println(ecipher.getOutputSize(1024*1024)); 
     OutputStream out_d = new CipherOutputStream(out_append, dcipher); 

     // Read in the decrypted bytes and write the cleartext to out 
     int numRead = 0; 
     int count = 0; 
     int max = 1024; 

     while ((numRead = in.read(buf, 0, max)) > 0) { 
      count += numRead; 
      if(count <= ecipher.getOutputSize(1024*1024)){ 
       out_d.write(buf, 0, numRead); 
       // last encryption pass, close buffer and fix max 
       if(count == ecipher.getOutputSize(1024*1024)){ 
        // fix reading 1k in case max was decreased 
        max = 1024; 
        out_d.close(); 
       } 
       // if next read will go over a meg, read less than 1k 
       else if(count + max > ecipher.getOutputSize(1024*1024)) 
        max = ecipher.getOutputSize(1024*1024) - count; 
      } 
      // past the first meg, don't decrypt 
      else{ 
       out.write(buf, 0, numRead); 
      } 

     } 
     out.close(); 
    } catch (java.io.IOException e) { 
    } 
}