現在項目里面有一個需求,本項目里面下載的視頻和文檔都不允許通過其他的播放器播放,在培訓機構里面這樣的需求很多。防止有人交一份錢,把所有的課件就拷給了別人。這樣的事情培訓機構肯定是不願意的。現在我項目里面也出了這么個需求。下面介紹一下我的實現。
思路:
首先下載文件,這個就不說了,java代碼寫個下載管理器。
下載完成后存儲文件的時候不是直接存儲,要加密存儲,加密方法是將文件的每個字節與這個字節在流中的下標做異或運算。
在我們項目里面播放的時候要解密,方法也是將文件的每個字節與這個字節在流中的下標做異或運算。兩次異或得到的就是沒有加密的值。
- /**
- * 加密解密管理類
- *
- * 加密算法 : 將文件的數據流的每個字節與該字節的下標異或.
- * 解密算法 : 已經加密的文件再執行一次對文件的數據流的每個字節與該字節的下標異或
- *
- * @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;
- }
- }
代碼就是這么多,都有注釋。以后再有這種需求可以直接用。