zoukankan      html  css  js  c++  java
  • 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;
        }

    }

  • 相关阅读:
    Using Resource File on DotNet
    C++/CLI VS CSharp
    JIT VS NGen
    [Tip: disable vc intellisense]VS2008 VC Intelisense issue
    UVa 10891 Game of Sum(经典博弈区间DP)
    UVa 10723 Cyborg Genes(LCS变种)
    UVa 607 Scheduling Lectures(简单DP)
    UVa 10401 Injured Queen Problem(简单DP)
    UVa 10313 Pay the Price(类似数字分解DP)
    UVa 10635 Prince and Princess(LCS N*logN)
  • 原文地址:https://www.cnblogs.com/fx2008/p/5681930.html
Copyright © 2011-2022 走看看