现在项目里面有一个需求,本项目里面下载的视频和文档都不允许通过其他的播放器播放,在培训机构里面这样的需求很多。防止有人交一份钱,把所有的课件就拷给了别人。这样的事情培训机构肯定是不愿意的。现在我项目里面也出了这么个需求。下面介绍一下我的实现。
思路:
首先下载文件,这个就不说了,java代码写个下载管理器。
下载完成后存储文件的时候不是直接存储,要加密存储,加密方法是将文件的每个字节与这个字节在流中的下标做异或运算。
在我们项目里面播放的时候要解密,方法也是将文件的每个字节与这个字节在流中的下标做异或运算。两次异或得到的就是没有加密的值。
[java] view plaincopy
- /**
- * 加密解密管理类
- *
- * 加密算法 : 将文件的数据流的每个字节与该字节的下标异或.
- * 解密算法 : 已经加密的文件再执行一次对文件的数据流的每个字节与该字节的下标异或
- *
- * @author Administrator
- *
- */
- public class FileEnDecryptManager {
- private FileEnDecryptManager() {
- }
- private static FileEnDecryptManager instance = null;
- public static FileEnDecryptManager getInstance() {
- synchronized (FileEnDecryptManager.class) {
- if (instance == null)
- instance = new FileEnDecryptManager();
- }
- return instance;
- }
- /**
- * 记录上次解密过的文件名
- */
- private final String LastDecryptFile = Framework
- .getModule(DownloadModule.class).getDownloadDir().getAbsolutePath()
- + "/LastDecryptFilename.ttt";
- /**
- * LastDecryptFilename.ttt 文件是否被清空
- */
- private boolean isClear = false;
- /**
- * 加密入口
- *
- * @param fileUrl
- * 文件绝对路径
- * @return
- */
- public boolean InitEncrypt(String fileUrl) {
- encrypt(fileUrl);
- return true;
- }
- private final int REVERSE_LENGTH = 56;
- /**
- * 加解密
- *
- * @param strFile
- * 源文件绝对路径
- * @return
- */
- private boolean encrypt(String strFile) {
- int len = REVERSE_LENGTH;
- try {
- File f = new File(strFile);
- RandomAccessFile raf = new RandomAccessFile(f, "rw");
- long totalLen = raf.length();
- if (totalLen < REVERSE_LENGTH)
- len = (int) totalLen;
- FileChannel channel = raf.getChannel();
- MappedByteBuffer buffer = channel.map(
- FileChannel.MapMode.READ_WRITE, 0, REVERSE_LENGTH);
- byte tmp;
- for (int i = 0; i < len; ++i) {
- byte rawByte = buffer.get(i);
- tmp = (byte) (rawByte ^ i);
- buffer.put(i, tmp);
- }
- buffer.force();
- buffer.clear();
- channel.close();
- raf.close();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
- /**
- * 解密入口
- *
- * @param fileUrl
- * 源文件绝对路径
- */
- public void Initdecrypt(String fileUrl) {
- try {
- if (isDecripted(fileUrl)) {
- decrypt(fileUrl);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private void decrypt(String fileUrl) {
- encrypt(fileUrl);
- }
- /**
- * fileName 文件是否已经解密了
- *
- * @param fileName
- * @return
- * @throws IOException
- */
- private boolean isDecripted(String fileName) throws IOException {
- // 上次加密的文件
- File lastDecryptFile = new File(LastDecryptFile);
- if (lastDecryptFile.exists() && isClear == false) {
- String lastDecryptfilepath = getLastDecryptFilePath(LastDecryptFile);
- if (lastDecryptfilepath != null
- && lastDecryptfilepath.equals(fileName)) {
- return false;
- } else {
- clear();
- }
- }
- StringBufferWrite(fileName);
- return true;
- }
- /**
- * 将需要加密的文件绝对路径写入LastDecryptFile
- *
- * @param filePath
- * 需要加密的文件绝对路径
- * @param content
- * @throws IOException
- */
- private void StringBufferWrite(String filePath) throws IOException {
- File lastDecryptFile = new File(LastDecryptFile);
- if (!lastDecryptFile.exists())
- lastDecryptFile.createNewFile();
- FileOutputStream out = new FileOutputStream(lastDecryptFile, true);
- StringBuffer sb = new StringBuffer();
- sb.append(filePath);
- out.write(sb.toString().getBytes("utf-8"));
- out.close();
- }
- /**
- * 清空加密记录
- */
- public synchronized void clear() {
- isClear = true;
- File decryptTempFile = new File(LastDecryptFile);
- if (decryptTempFile.exists()) {
- try {
- String fileName = getLastDecryptFilePath(LastDecryptFile);
- decrypt(fileName);
- new File(LastDecryptFile).delete();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- isClear = false;
- }
- /**
- * 从LastDecryptFile中读取记录
- *
- * @param filePath
- * @return
- * @throws IOException
- */
- private String getLastDecryptFilePath(String filePath) throws IOException {
- BufferedReader br = new BufferedReader(new FileReader(filePath));
- String str = br.readLine();
- br.close();
- return str;
- }
- }
代码就是这么多,都有注释。以后再有这种需求可以直接用。
时间: 2024-10-29 19:09:40