对应Python版:加密文件之Python版
Java版比Python版要快得多,两个版本不在一个量级上。在加密解密1G大文件时,Java版花费的时间是秒级,而Python版花费的时间是10分钟级。

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset; /**
* Script: Encode.java Encode file or decode file. Java implementation and
* upgrade Encoding: UTF-8 Version: 0.2 Java version: 1.8 Usage: java Encode
* [encode | decode] filename [key]
*
*/
public class Encode { private static final String DEFAULT_KEY = "TESTKEY";
private static final String DEFAULT_CHARSET = "UTF-8";
private static final long SLEEP_TIME = 100; public boolean isEncode;
public MappedByteBuffer mappedBuffer; private String filename;
private String charset;
private byte[] keyBytes; private EncodeThread[] workThreads; public Encode(boolean isEncode, String filename, String key) {
this.isEncode = isEncode;
this.filename = filename;
this.charset = DEFAULT_CHARSET;
this.keyBytes = key.getBytes(Charset.forName(charset));
} public void run() {
try {
// read file
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
FileChannel channel = raf.getChannel();
long fileLength = channel.size();
int bufferCount = (int) Math.ceil((double) fileLength / (double) Integer.MAX_VALUE);
if (bufferCount == 0) {
channel.close();
raf.close();
return;
}
int bufferIndex = 0;
long preLength = 0;
// repeat part
long regionSize = Integer.MAX_VALUE;
if (fileLength - preLength < Integer.MAX_VALUE) {
regionSize = fileLength - preLength;
}
mappedBuffer = channel.map(FileChannel.MapMode.READ_WRITE, preLength, regionSize);
preLength += regionSize; // create work threads
int threadCount = keyBytes.length; System.out.println(
"File size: " + fileLength + ", buffer count: " + bufferCount + ", thread count: " + threadCount);
long startTime = System.currentTimeMillis();
System.out.println("Start time: " + startTime + "ms");
System.out.println("Buffer " + bufferIndex + " start ..."); workThreads = new EncodeThread[threadCount];
for (int i = 0; i < threadCount; i++) {
workThreads[i] = new EncodeThread(this, keyBytes[i], keyBytes.length, i);
workThreads[i].start();
} // loop
while (true) {
Thread.sleep(SLEEP_TIME); // wait until all threads completed
boolean completed = true;
for (int i = 0; i < workThreads.length; i++) {
if (!workThreads[i].isCompleted()) {
completed = false;
break;
}
}
if (!completed) {
continue;
} // check if finished
bufferIndex++;
if (bufferIndex >= bufferCount) {
// stop threads
for (int i = 0; i < workThreads.length; i++) {
workThreads[i].flag = false;
}
break;
} // repeat part
regionSize = Integer.MAX_VALUE;
if (fileLength - preLength < Integer.MAX_VALUE) {
regionSize = fileLength - preLength;
}
mappedBuffer = channel.map(FileChannel.MapMode.READ_WRITE, preLength, regionSize);
preLength += regionSize; // restart threads
System.out.println("Buffer " + bufferIndex + " start ...");
for (int i = 0; i < workThreads.length; i++) {
workThreads[i].restart();
}
} // over loop
while (true) {
Thread.sleep(SLEEP_TIME); boolean isOver = true;
for (int i = 0; i < workThreads.length; i++) {
if (workThreads[i].isAlive()) {
isOver = false;
break;
}
}
if (isOver) {
break;
}
} // close file relatives
channel.close();
raf.close(); long endTime = System.currentTimeMillis();
System.out.println("End time: " + endTime + "ms, use time: " + (endTime - startTime) + "ms");
System.out.println("ok!");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
String usage = "Usage: java -jar encode.jar [encode | decode] filename [key]";
// parse args
if (args.length < 2) {
System.out.println("There must be two or more arguments!");
System.out.println(usage);
return;
}
if (!args[0].equals("encode") && !args[0].equals("decode")) {
System.out.println("The first argument must be \"encode\" or \"decode\"");
System.out.println(usage);
return;
}
boolean isEncode = (args[0].equals("encode"));
String filename = args[1];
File file = new File(filename);
if (!file.isFile()) {
System.out.println("The file doesn't exist!");
System.out.println(usage);
return;
}
String key = DEFAULT_KEY;
if (args.length > 2) {
key = args[2];
} // encode or decode
new Encode(isEncode, filename, key).run();
} } class EncodeThread extends Thread { private static final long SLEEP_TIME = 50; public boolean flag; private Encode encoder;
private int key;
private long dataIndex;
private int interval;
private int regionSize;
private boolean completed; public EncodeThread(Encode encoder, byte key, int interval, int index) {
this.encoder = encoder;
this.key = key & 0xff;
this.dataIndex = index;
this.interval = interval;
this.regionSize = encoder.mappedBuffer.limit();
this.completed = false;
this.flag = true;
} public void restart() {
this.dataIndex -= regionSize;
regionSize = encoder.mappedBuffer.limit();
completed = false;
} public boolean isCompleted() {
return completed;
} @Override
public void run() {
try {
if (encoder.isEncode) {
encode();
} else {
decode();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void encode() throws InterruptedException {
while (flag) {
// completed here ensure restart() synchronized
if (completed) {
Thread.sleep(SLEEP_TIME);
continue;
}
if (dataIndex >= regionSize) {
completed = true;
System.out.println("Encode thread " + this.getName() + " is completed!");
continue;
} // do encode
byte b = encoder.mappedBuffer.get((int) dataIndex);
// added as unsigned byte
b = (byte) (((b & 0xff) + key) % 256);
encoder.mappedBuffer.put((int) dataIndex, b);
dataIndex += interval;
}
} private void decode() throws InterruptedException {
while (flag) {
// completed here ensure restart() synchronized
if (completed) {
Thread.sleep(SLEEP_TIME);
continue;
}
if (dataIndex >= regionSize) {
completed = true;
System.out.println("Encode thread " + this.getName() + " is completed!");
continue;
} // do decode
byte b = encoder.mappedBuffer.get((int) dataIndex);
// substracted as unsigned byte
b = (byte) (((b & 0xff) + 256 - key) % 256);
encoder.mappedBuffer.put((int) dataIndex, b);
dataIndex += interval;
}
} }

加密文件之Java改进版的更多相关文章

  1. java基础IO流 复制键盘录入的目录,复制其中的.java文件到指定目录,指定目录中有重名,则改名 对加密文件计算字母个数

    package com.swift.jinji; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; im ...

  2. (iOS)Base64加密和DES加密、以及JAVA和iOS中DES加密统一性问题

    我们在项目中为了安全方面的考虑,通常情况下会选择一种加密方式对需要安全性的文本进行加密,而Base64加密和DES64加密是常用的加密算法.我记得我在前一个项目中使用的就是这两种加密算法的结合:Bas ...

  3. 运用加密技术保护Java源代码/定制ClassLoader

    为什么要加密? 对于传统的C或C++之类的语言来说,要在Web上保护源代码是很容易的,只要不发布它就可以.遗憾的是,Java程序的源代码很容易被别人偷看.只要有一个反编译器,任何人都可以分析别人的代码 ...

  4. 破解Zip加密文件常用的几种方法

    前言 在互联网的浪潮中,大家也许碰到过这种情况: 从网络上下载了一个zip文件,最后却发现它是用密码保护的,或者自己用密码加密了一个很重要zip文件,但是一段时间后忘记了密码,无法打开.这个时候,我们 ...

  5. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  6. Des加密(js+java结果一致)【原创】

    des加密算法,javascript版本和java版本 目录: 1.资源文件下载 2.JavaScript文件(des.js) 3.html文件(des.html) 4.java文件(des.java ...

  7. 运用加密技术保护Java源代码(转)

    出处:运用加密技术保护Java源代码 为什么要加密? 对于传统的C或C++之类的语言来说,要在Web上保护源代码是很容易的,只要不发布它就可以.遗憾的是,Java程序的源代码很容易被别人偷看.只要有一 ...

  8. web主题公园版权信息破解:script.js加密文件

    很多人会使用web主题公园网站的免费worldpress主题,但它的主题又都被加了版权信息,故意让人找不到版权信息的修改位置. 你如果去footer.php里面删除版权信息(技术支持:web主题公园) ...

  9. 使用 gpg 加密文件 - 通过 shell 或 php

    使用 gpg 加密文件 - 通过 shell 或 php 背景:客户提供私钥,并要求我方通过php把加密后的文件传输给他们. 环境 macOS Sierra 10.12.1 php 7.0.8 0.安 ...

随机推荐

  1. 链表java实现

    链表是用指针将多个节点联系在一起,通过头节点和尾节点还有节点数量,可以对链表进行一系列的操作.是线性表的链式存储实现. 1.链表是多个不连续的地址组成在一起根据指针链接在一起的,由多个节点组成,每个节 ...

  2. BZOJ5302 HAOI2018奇怪的背包(动态规划)

    由裴蜀定理,子集S有解当且仅当gcd(S,P)|w. 一个显然的dp是设f[i][j]为前i个数gcd为j的选取方案.注意到这里的gcd一定是P的约数,所以状态数是n√P的.然后可以通过这个得到gcd ...

  3. BZOJ 4316: 小C的独立集 解题报告

    4316: 小C的独立集 Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点, ...

  4. SpringBoot 中使用redis以及redisTemplate

    1.首先在pom.xml中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <art ...

  5. ---web模型 --mvc和模型--struts2 入门

    关于web模型: 早期的web 应用主要是静态页丽的浏览〈如新闻的制监),随着Internet的发展,web应用也变得越来越复杂,不仅要 和数据库进行交互 ,还要和用户进行交互,由此衍生了各种服务器端 ...

  6. android studio 卡慢的问题(android studio 3.0)

    http://www.jianshu.com/p/0228b7d017bb 想体验一下android studio 3.0的canary版,主要是学习Kotlin.创建项目后,下载相关文件一直不成功. ...

  7. LGP4577【JSOI2018】战争

    题解: 求出$A$ 和$-B$ 的$Minkowsiki$和再$O(logn)$判断一个点是否在凸包内: $Minkowsiki$的求法比较容易忘,要多多温习才可以: #include<bits ...

  8. 旧题新做:从idy的视角看数据结构

    “今天你不写总结……!!!” 额…… 还是讲我的吧.这些考试都是idy出的题. 20170121:DFS序. ST表.线段树练习 这是第一次考数据结构. Problem 1. setsum 1 sec ...

  9. PHP正则表达式函数学习

    正则表达式是在日常开发中经常用到的,通常一些使用频率过高的正则表达式都是直接粘贴复制,对于基础正则的使用还是要铭记于心的,今天抽时间整理一些php正则表达式的用法. 一.php中常用的正则表达式函数 ...

  10. C++模版详解(-)

    C++模版:       模版时C++支持多参数多态的工具,使用模版可以为用户为类或函数声明一般模式,使得类的数据成员,或者成员函数的参数,返回值取得任意类型. 模版是一种对类型进行参数化的工具: 通 ...