字節流運算實現文件的加密解密1.0

簡介

  • byte:Java中基本類型之一,值域爲-128~127

  • 在Java中所有文件都可以使用IO以字節流的方式進行讀寫;

  • 常見使用:文件複製

原理

  • 加密

    獲取文件的字節碼數組然後對其進行加鹽運算,將運算後的字節碼信息生成新的文件。因爲文件的字節信息已被修改,所以生成的文件跟原來的文件已經相差很遠,可稱其爲加密文件。

  • 解密

    讀取加密文件中的字節信息,進行去鹽運算,可以得出原文件的字節信息,然後輸出爲解密文件=原文件。

字節流讀取與寫入

使用FileInputStream讀取文件的字節數組

//實現代碼
public static void main(String[] args) {
   //普通文本文件
   File file = new File("E:\\test\\1.txt");
   System.out.println(Arrays.toString(readBytes(file)));
}
​
static byte[] readBytes(File file) {
   long len = file.length();
   byte[] bytes = new byte[(int) len];
   try (FileInputStream in = new FileInputStream(file)) {
      int readLength = in.read(bytes);
      if ((long) readLength < len) {
         throw new IOException("文件讀取失敗");
      }
   } catch (IOException e) {
      e.printStackTrace();
   }
   return bytes;
}

使用FileOutputStream根據字節數組生成文件,結合以上的讀取字節數組方法就可以實現文件的複製

//實現代碼
public static void main(String[] args) {
        //原文件
        File src = new File("E:\\test\\1.txt");
        //目標文件
        File dest = new File("E:\\test\\2.txt");
        //原文件的字節數組
        byte[] srcBytes = readBytes(src);
        System.out.println("原文件字節數組:" + Arrays.toString(srcBytes));
        //根據原字節數組生成目標文件,實現文件的複製
        writeBytes(srcBytes, dest);
    }
​
    /**
     * 根據字節流生成文件
     *
     * @param data
     * @param dest
     */
    static void writeBytes(byte[] data, File dest) {
        try (FileOutputStream out = new FileOutputStream(dest)) {
            out.write(data);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    static byte[] readBytes(File file) {
        long len = file.length();
        byte[] bytes = new byte[(int) len];
        try (FileInputStream in = new FileInputStream(file)) {
            int readLength = in.read(bytes);
            if ((long) readLength < len) {
                throw new IOException("文件讀取失敗");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

當然如果你只是要實現文件的複製,這只是其實現方式之一,還有:

  1. BufferedInputStream/BufferedOutputStream緩衝字節流進行復制文件,使用該方式可對以上方法進行優化;

  2. FileReader/FileWriter字符流進行文件複製,顧名思義只能針對字符文件進行操作;

  3. BufferedReader/BufferedWriter緩衝字符流進行文件複製,顧名思義只能針對字符文件進行操作。

Bingo

知道了字節流讀取與寫入的方法後,結合上述加解密原理,相信你已經知道後面要怎麼做了。

你猜的沒錯,就是對readBytes方法獲取的字節數組進行加鹽運算。

比如:

  • 加密就是對字節數組進行每一個字節加1,獲取到新的字節數組;

  • 解密就是對字節數組進行每一個字節減1,獲取到原來的字節數組。

當然這裏的加鹽運算也可以有其他的運算規則:

  1. 對字節數組部分字節進行加鹽運算;

  2. 倒序排列字節數組;

  3. 字節數組進行AES加密解密運算;

這個運算規則可玩性很高,生成的加密文件,如果別人不知道加密方式,應該是無法解密的,你可能會說這個世界上只要是雙向加密的信息就沒有不能破解的。嗯!這句話我認同。當然加密方式越複雜,解密時間只是指數增長了。

代碼稍多,請移步這個地址:https://gitee.com/mwk719/spring-learn/blob/master/src/main/java/com/mwk/encrypt/FileEncryptAndDecryptSalt_1.java

問題

因爲讀取文件方法使用的是FileInputStream獲取文件字節碼流的方式,所以不建議特別大的文件;

在文件讀取過程中會獲取文件的字節數組存在內存中,文件過大獲取到的數組也會很大,容易造成內存溢出,而且讀取字節數組的時間也會增長。

思考

因爲字節的範圍爲-128~127,在運算過程中肯定有超出範圍的數字127+1=128。爲什麼生成加密文件未出錯,而且被加密的文件還可以正常解密?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章