对应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环境变量

    右键单击计算机--->属性 点击 “高级系统设置”--->"环境变量",出现环境变量设置窗口 系统变量--->新建 JAVA_HOME变量,变量值填写jdk安装路 ...

  2. 【BZOJ1011】遥远的行星(???)

    题面 BZOJ 洛谷 题解 大概就是分个块,然后每块取平均数算贡献啥的. BZOJ上过不去??? #include<iostream> #include<cstdio> usi ...

  3. 洛谷 P1939 【模板】矩阵加速(数列) 解题报告

    P1939 [模板]矩阵加速(数列) 题目描述 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值 ...

  4. Linux系统启动详解(三)

    上节已系统initramfs已启动完成,将系统控制权交给了真正的rootfs的/sbin/init,下面就是/sbin/init干活的时间了. 4       /sbin/init initramfs ...

  5. Android 程序架构: MVC、MVP、MVVM、Unidirectional、Clean...

    摘选自:GUI 应用程序架构的十年变迁:MVC.MVP.MVVM.Unidirectional.Cleanhttps://zhuanlan.zhihu.com/p/26799645 MV* in An ...

  6. adb server version (32) doesn't match this client (36); killing...

    http://blog.csdn.net/seaker_/article/details/55107598 FAQ: adb server version (36) doesn't match thi ...

  7. 微软工程师主讲的SqlServer2005视频教程

    http://www.cnblogs.com/slcfhr/archive/2008/11/24/1340283.html SQL Server 2005盛宴系列之一:SQL Server 2005产 ...

  8. IEEE 754浮点数表示标准

    二进制数的科学计数法 C++中使用的浮点数包括采用的是IEEE标准下的浮点数表示方法.我们知道在数学中可以将任何十进制的数写成以10为底的科学计数法的形式,如下 其中显而易见,因为如果a比10大或者比 ...

  9. 【题解】Willem, Chtholly and Seniorious Codeforces 896C ODT

    Prelude ODT这个东西真是太好用了,以后写暴力骗分可以用,写在这里mark一下. 题目链接:ヽ(✿゚▽゚)ノ Solution 先把原题解贴在这里:(ノ*・ω・)ノ 简单地说,因为数据是全部随 ...

  10. ElasticStack系列之十三 & 联想补全策略

    业务需求 1. 实现搜索引擎前缀搜索功能(中文,拼音前缀查询及简拼前缀查询功能) 2. 实现摘要全文检索功能,及标题加权处理功能(按照标题权值高内容权值相对低的权值分配规则,按照索引的相关性进行排序, ...