java 對視頻和圖片進行加密解密[轉]


是時候回到文件加密與解密的具體實現這個主題上來了。后續的舉例均采用圖片(包括GIF動畫)類型,而其他類型資源的實現原理相同,就不一一給出了。首先來看對一幅JPG類型圖片進行異或加密的Java實現,由於是第一次給出代碼,所以貼上了Java文件“FileEncAndDec.java”的所有內容。

復制代碼
 1 import java.io.File;
 2 import java.io.InputStream;
 3 import java.io.OutputStream;
 4 import java.io.FileInputStream;
 5 import java.io.FileOutputStream;
 6 
 7 public class FileEncAndDec {
 8     private static final int numOfEncAndDec = 0x99; //加密解密秘鑰
 9     private static int dataOfFile = 0; //文件字節內容
10     public static void main(String[] args) {
11 
12         File srcFile = new File("桌面.jpg"); //初始文件
13         File encFile = new File("encFile.tif"); //加密文件
14         File decFile = new File("decFile.bmp"); //解密文件
15         
16         try {
17             EncFile(srcFile, encFile); //加密操作
18         } catch (Exception e) {
19             e.printStackTrace();
20         }  
21     }
22 
23     private static void EncFile(File srcFile, File encFile) throws Exception {
24         if(!srcFile.exists()){
25             System.out.println("source file not exixt");
26             return;
27         }
28         
29         if(!encFile.exists()){
30             System.out.println("encrypt file created");
31             encFile.createNewFile();
32         }
33         InputStream fis  = new FileInputStream(srcFile);
34         OutputStream fos = new FileOutputStream(encFile);
35         
36         while ((dataOfFile = fis.read()) > -1) {
37             fos.write(dataOfFile^numOfEncAndDec);
38         }
39         
40         fis.close();
41         fos.flush();
42         fos.close();
43     }
44 }
復制代碼

  從代碼可以看出,給定的加密秘鑰(異或數據,可以在合法范圍內隨便定義)為十六進制數0x99。圖片資源為以中文命名的“桌面.jpg”,加密文件為“encFile.png”,還有值為“decFile.bmp”的String類對象作為解密文件名稱。

  相對應地,解密的實現幾乎和加密相同,只是輸入與輸出文件不同,看下面代碼。

復制代碼
 1 private static void DecFile(File encFile, File decFile) throws Exception {
 2   if(!encFile.exists()){
 3     System.out.println("encrypt file not exixt");
 4     return;
 5   }
 6 
 7   if(!decFile.exists()){
 8     System.out.println("decrypt file created");
 9     decFile.createNewFile();
10   }
11 
12   InputStream fis  = new FileInputStream(encFile);
13   OutputStream fos = new FileOutputStream(decFile);
14 
15   while ((dataOfFile = fis.read()) > -1) {
16     fos.write(dataOfFile^numOfEncAndDec);
17   }
18 
19   fis.close();
20   fos.flush();
21   fos.close();
22 }
復制代碼

  由於加密后的圖片文件(保存為PNG類型)是不能直接在圖片查看器中打開的,因為其內容已經改變,所以其縮略圖標會顯示為兩朵不同顏色的花。對於其他類型的加密或損壞文件的縮略圖標:JPG為山水畫,BMP和TIF為畫刷塗鴉,GIF為三個不同顏色的幾何圖形。當然,這些默認的圖標應該會因系統而異。

  下面給出初始、加密及解密后的圖標截圖:

      

  和預想的一致,經測試發現以上方法對GIF動畫(不是GIF圖片,而是可以播放的動畫資源)的加密與解密同樣適用,代碼和截圖也就沒有區別了,不過還是貼上來:

1 File srcFile = new File("srcFile.gif"); //初始文件
2 File encFile = new File("encFile.gif"); //加密文件
3 File decFile = new File("decFile.gif"); //解密文件

      

  有兩點需要注意:

  1、在調用加密與解密方法時,必須加上異常處理塊(try{...}catch{...},否則編譯不通過)。

  2、對用來加密或解密的源文件進行打開(讀取)操作之前,最好判斷其是否存在,免得造成意想不到的錯誤和時間的浪費。因為若文件不存在,后續的操作都是沒有意義的。

  今天就先寫到這,總結一下吧。文件加密簡單地說就是對數據進行變換,雖然一千種方法可能會有一千種一種結果,但是思想是通用的。關鍵是加密所采用的算法的難易,有時間會對文中提到的算法用Java進行

---------------------------------------------------------------------------------------------------------

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;

public class FileEncryptAndDecrypt {

    public static void main(String[] args) throws Exception {

        String filename = "奔馬.avi";

        String flag = readFileLastByte("c:\\" + filename, 6);
        if (flag.indexOf("hello") > 0) {
            // 加密過了;
        } else {
            // 沒有加密
            new FileEncryptAndDecrypt().encrypt("c:\\" + filename, "hello");
        }
        System.out.println(new FileEncryptAndDecrypt().decrypt("c:\\"
                + filename, "c:\\" + filename, 6));
        // System.out.println(readFileLastByte("c:\\3.jpg", 6));
    }

    /**
     * 文件file進行加密
     * 
     * @param fileUrl
     *            文件路徑
     * @param key
     *            密碼
     * @throws Exception
     */
    public static void encrypt(String fileUrl, String key) throws Exception {
        File file = new File(fileUrl);
        String path = file.getPath();
        if (!file.exists()) {
            return;
        }
        int index = path.lastIndexOf("\\");
        String destFile = path.substring(0, index) + "\\" + "abc";
        System.out.println(destFile);
        File dest = new File(destFile);
        InputStream in = new FileInputStream(fileUrl);
        OutputStream out = new FileOutputStream(destFile);
        byte[] buffer = new byte[1024];
        int r;
        byte[] buffer2 = new byte[1024];
        while ((r = in.read(buffer)) > 0) {
            for (int i = 0; i < r; i++) {
                byte b = buffer[i];
                buffer2[i] = b == 255 ? 0 : ++b;
            }
            out.write(buffer2, 0, r);
            out.flush();
        }
        in.close();
        out.close();
        file.delete();
        dest.renameTo(new File(fileUrl));
        appendMethodA(fileUrl, key);
        System.out.println("加密成功");
    }

    /**
     * 
     * @param fileName
     * @param content
     *            密鑰
     */
    public static void appendMethodA(String fileName, String content) {
        try {
            // 打開一個隨機訪問文件流,按讀寫方式
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
            // 文件長度,字節數
            long fileLength = randomFile.length();
            // 將寫文件指針移到文件尾。
            randomFile.seek(fileLength);
            randomFile.writeBytes(content);
            randomFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解密
     * 
     * @param fileUrl
     *            源文件
     * @param tempUrl
     *            臨時文件
     * @param ketLength
     *            密碼長度
     * @return
     * @throws Exception
     */
    public static String decrypt(String fileUrl, String tempUrl, int keyLength)
            throws Exception {
        File file = new File(fileUrl);
        if (!file.exists()) {
            return null;
        }
        File dest = new File(tempUrl);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }

        InputStream is = new FileInputStream(fileUrl);
        OutputStream out = new FileOutputStream(tempUrl);

        byte[] buffer = new byte[1024];
        byte[] buffer2 = new byte[1024];
        byte bMax = (byte) 255;
        long size = file.length() - keyLength;
        int mod = (int) (size % 1024);
        int div = (int) (size >> 10);
        int count = mod == 0 ? div : (div + 1);
        int k = 1, r;
        while ((k <= count && (r = is.read(buffer)) > 0)) {
            if (mod != 0 && k == count) {
                r = mod;
            }

            for (int i = 0; i < r; i++) {
                byte b = buffer[i];
                buffer2[i] = b == 0 ? bMax : --b;
            }
            out.write(buffer2, 0, r);
            k++;
        }
        out.close();
        is.close();
        return tempUrl;
    }

    /**
     * 判斷文件是否加密
     * 
     * @param fileName
     * @return
     */
    public static String readFileLastByte(String fileName, int keyLength) {
        File file = new File(fileName);
        if (!file.exists())
            return null;
        StringBuffer str = new StringBuffer();
        try {
            // 打開一個隨機訪問文件流,按讀寫方式
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "r");
            // 文件長度,字節數
            long fileLength = randomFile.length();
            // 將寫文件指針移到文件尾。
            for (int i = keyLength; i >= 1; i--) {
                randomFile.seek(fileLength - i);
                str.append((char) randomFile.read());
            }
            randomFile.close();
            return str.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM