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;
        }

    }

  • 相关阅读:
    Yii调试插件yii-debug-toolbar的使用
    IE8不支持indexOf的解决办法
    使用wkhtmltopdf的一些事情
    mac sourcetree 启用 Beyond compare
    Java基础学习之(5)--impact和package
    Java基础学习之(3)--面向对象2--重载
    Java基础学习之(4)--面向对象3--this+static关键字
    Java基础学习之(2)--面向对象1
    Java基础学习之(1)--标识符、关键字、数据类型
    java学习(7)iterator迭代器
  • 原文地址:https://www.cnblogs.com/fx2008/p/5681930.html
Copyright © 2011-2022 走看看