2014-09-04 33 views
-1

我想創建一個非常簡單的加密/解密項目。但起初,我想讀的JPG文件,並將其寫入與給定的密碼文件,然後再次讀取該文件與文件和所提供的密碼檢查密碼,但我得到:圖像讀寫java.lang.IllegalArgumentException

Exception in thread "main" java.lang.IllegalArgumentException: im == null! 
    at javax.imageio.ImageIO.write(Unknown Source) 
    at javax.imageio.ImageIO.write(Unknown Source) 
    at GSM.AES.deccryption(AES.java:105) 
    at GSM.AES.main(AES.java:27) 

我的代碼:

public static void main(String args[]) 
     { 
      myWrite(); 
      String encryptedFilePath = System.getProperty("user.dir")+ "\\"+"Encrypted"+".mmlooloo"; 
      String destinationFilePath = System.getProperty("user.dir") + "\\"; 
      try { 
       myRead(encryptedFilePath,destinationFilePath,"123456"); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return; 
     } 

我的加密:

public static void myWrite() { 

      try { 

       System.out.println("Plesase Enter Number Of Pages !!!!!"); 
       BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); 
       int numberOfPage = Integer.valueOf(bufferRead.readLine().toString()); 

       String dirName= System.getProperty("user.dir")+"\\"; 


       byte[] base64StringEnc; 
       ByteArrayOutputStream baos=new ByteArrayOutputStream(1000); 
       FileOutputStream myMatLabFileEnc = null; 

       String filePath = System.getProperty("user.dir")+ "\\"+"Encrypted"+".mmlooloo"; 
       myMatLabFileEnc = new FileOutputStream (filePath); 
       String imagFileName; 
       String imgPathString; 
       String password = "123456"; 
       myMatLabFileEnc.write(password.getBytes()); 
       myMatLabFileEnc.write("\n".getBytes()); 

       for(int i = 1 ; i<=numberOfPage ;i++) 
       {  

        imagFileName = Integer.toString(i) +".jpg";   
        BufferedImage img=ImageIO.read(new File(dirName,imagFileName)); 
        ImageIO.write(img, "jpg", baos); 
        baos.flush(); 

        myMatLabFileEnc.write(baos.toByteArray()); 
        myMatLabFileEnc.write("\n".getBytes()); 

        baos.reset(); 
        imgPathString = dirName + imagFileName; 
        File f = new File(imgPathString); 
        f.delete(); 

       } 
        myMatLabFileEnc.close(); 
        baos.close(); 
        return; 

       } catch (FileNotFoundException ex) { 
        System.out.println(ex.toString()); 
      }catch(IOException ex){ 
       System.out.println(ex.toString()); 
      } 
     } 

和我的解密:

public static int myRead(String encryptedfilePath,String encryptedFileDir,String inputPassword) throws FileNotFoundException, IOException{ 

      FileReader encryptedFile=new FileReader(encryptedfilePath); 
      BufferedReader reader = new BufferedReader(encryptedFile); 
      String encryptedImag; 
      String encryptedSavesdPassword = reader.readLine(); 
      byte []encryptedInputPassword = inputPassword.getBytes(); 
      byte []temp = encryptedSavesdPassword.getBytes(); 
      if(!Arrays.equals(temp,encryptedInputPassword)){ 
       return -1; 
      } 
      int i = 1; 

      while((encryptedImag = reader.readLine()) != null){ 

       byte[] bytearray = encryptedImag.getBytes(); 
       BufferedImage imagRecover=ImageIO.read(new ByteArrayInputStream(bytearray)); 
       String outputRecoverdFileName = Integer.toString(i)+"_recoverd.jpg"; 
       ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName)); 
       ++i; 
      } 

      return 1; 

     } 

和AES.java:105是:

ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName)); 

我檢查imagRecover爲空,但我不知道爲什麼?我認爲你可以嘗試它只是命名您的圖像文件,如1.jpg,2.jpg等...

+0

你寫binnary數據。你不能保證圖像的二元組沒有結束。可能有很多carre返回和線內行結束......你期望的每個linea是完全conatructed圖像使imageio.read失敗並返回null,如javadoc中針對該方法所述。在寫入之前,我要求你對base64進行編碼,並將這個文件作爲文本文件與printwriter對待。否則,你應該嘗試一種類似thoae的WAD文件在good'ol厄運,節省每個文件的poaition和長度。 – eduyayo 2014-09-04 22:06:44

+0

Btw ...你有沒有讀過java.util.zip? – eduyayo 2014-09-04 22:07:17

+0

@eduyayo謝謝它的作品,但爲什麼我會失去質量?例如我的原始圖像是551kB,但我的恢復是181KB。我用Baase64編碼解碼方法來寫和讀。 – mmlooloo 2014-09-05 02:36:37

回答

2

免責聲明:這不是完整的答案,但它太長的評論。

這就是我的意思由註釋:

不解碼/圖像中的第一位置進行編碼。只需複製字節。

使用此代碼,您不會重新壓縮JPEG,因此不會失去質量。

,而不是下面的代碼:

imagFileName = Integer.toString(i) +".jpg";   
BufferedImage img=ImageIO.read(new File(dirName,imagFileName)); 
ImageIO.write(img, "jpg", baos); 
baos.flush(); 

就在字節從文件複製到baos這樣的:

imagFileName = Integer.toString(i) +".jpg";   
InputStream input = new FileInputStream(new File(dirName, imagFileName)); 
try { 
    copy(input, baos); 
} 
finally { 
    input.close(); 
} 

複製方法:

public void copy(InputStream input, OutputStream output) throws IOException { 
    byte[] buffer = new byte[1024]; 
    int len; 

    while ((len = input.read(buffer, 0, buffer.length)) >= 0) { 
     output.write(buffer, 0, len); 
    } 
} 

同樣,在解密部分,替換:

byte[] bytearray = encryptedImag.getBytes(); 
BufferedImage imagRecover=ImageIO.read(new ByteArrayInputStream(bytearray)); 
String outputRecoverdFileName = Integer.toString(i)+"_recoverd.jpg"; 
ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName)); 

有了:

byte[] bytearray = encryptedImag.getBytes(); 
InputStream input = new ByteArrayInputStream(bytearray)); 
String outputRecoverdFileName = Integer.toString(i) + "_recoverd.jpg"; 
OutputStream output = new FileOutputStream(new File(encryptedFileDir, outputRecoverdFileName))); 
try { 
    copy(input, output); 
} 
finally { 
    output.close(); 
} 
+0

非常感謝你,現在我認爲我可以實現任何加密算法來包裝我是嗎? – mmlooloo 2014-09-05 14:09:53

+0

只要你可以在解密後重現相同的字節,你應該很好。 :-) – haraldK 2014-09-05 14:12:53

+1

很好,特別是關於'byte []'不使用'String'。 Java的特殊之處在於,字符串是Unicode能夠將文本中的所有腳本組合在一起的。因此,總是存在向二進制數據的轉換(在給定的編碼中,或者默認爲操作系統)。該轉換在純二進制數據上無法正常工作。 – 2014-09-05 14:13:40