我的问题是这样的
现在呢 我做一个文件的加密解密操作
实际上加密就是将文件以byte数组读取出对每一个元素和一个特定的数异或
再将这个byte数组写入这个文件
解密也是一样的意思现在我发现 如果文件太大就会比较慢....
因为我这个主要针对是pdf文件 大的有好几十M
我试过一个5M不到的文件 加密要19秒 解密也一样
所以我就想 能不能跳跃性的读取文件中的字节 将这些特定的字节异或一个数
然后再将这些字节 写入它们在原文件中的位置覆盖原字节
这样也就是加密了 解密也是一样的思路 不知道IO流中有什么可以实现我的思路...
有没有人能帮我想想代码如下:import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;/***
* 简单的文件加密解密工具类
* @author gaobiaoqing
*
*/
public class EndeUtil {
static final byte[] KEYVALUE = "6^)(9-p35@%3#4S!4S0)$Y%%^&5(j.&^&o(*0)$Y%!#O@*GpG@=+@j.&6^)(0-=+"
.getBytes();
static final int BUFFERLEN = 1024;
public static void main(String[] args) {
// TODO Auto-generated method stub
try { String oldFile = new String("D:\\aaa\\2009.pdf");
//encryptFile(oldFile, "123456"); System.out.println("ok");
decryptFile(oldFile,"123456");
System.out.println("good");
} catch (Exception e) {
e.printStackTrace();
} }
/**
* 加密方法 将文件内容做加密 加密内容覆盖原内容
* @param file
* @param password
*/
public static void encryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
for (int i = 0; i < c; i++) {
buffer[i] ^= KEYVALUE[pos];
baos.write(buffer[i]);
pos++;
if (pos == keylen)
pos = 0;
}
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
for (int i = 0; i < c; i++) {
out.write(temp[i]);
}
}
//关闭打开的流
bais.close();
out.flush();
out.close();
} /***
* 解密方法 将加密后的文件内容做解密 解密后的内容覆盖原内容
* @param file
* @param password
* @throws Exception
*/
public static void decryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
for (int i = 0; i < c; i++) {
buffer[i] ^= KEYVALUE[pos];
baos.write(buffer[i]);
pos++;
if (pos == keylen)
pos = 0;
}
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
for (int i = 0; i < c; i++) {
out.write(temp[i]);
}
}
//关闭打开的流
bais.close();
out.flush();
out.close();
}
}
关键就在读取和写入上
现在呢 我做一个文件的加密解密操作
实际上加密就是将文件以byte数组读取出对每一个元素和一个特定的数异或
再将这个byte数组写入这个文件
解密也是一样的意思现在我发现 如果文件太大就会比较慢....
因为我这个主要针对是pdf文件 大的有好几十M
我试过一个5M不到的文件 加密要19秒 解密也一样
所以我就想 能不能跳跃性的读取文件中的字节 将这些特定的字节异或一个数
然后再将这些字节 写入它们在原文件中的位置覆盖原字节
这样也就是加密了 解密也是一样的思路 不知道IO流中有什么可以实现我的思路...
有没有人能帮我想想代码如下:import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;/***
* 简单的文件加密解密工具类
* @author gaobiaoqing
*
*/
public class EndeUtil {
static final byte[] KEYVALUE = "6^)(9-p35@%3#4S!4S0)$Y%%^&5(j.&^&o(*0)$Y%!#O@*GpG@=+@j.&6^)(0-=+"
.getBytes();
static final int BUFFERLEN = 1024;
public static void main(String[] args) {
// TODO Auto-generated method stub
try { String oldFile = new String("D:\\aaa\\2009.pdf");
//encryptFile(oldFile, "123456"); System.out.println("ok");
decryptFile(oldFile,"123456");
System.out.println("good");
} catch (Exception e) {
e.printStackTrace();
} }
/**
* 加密方法 将文件内容做加密 加密内容覆盖原内容
* @param file
* @param password
*/
public static void encryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
for (int i = 0; i < c; i++) {
buffer[i] ^= KEYVALUE[pos];
baos.write(buffer[i]);
pos++;
if (pos == keylen)
pos = 0;
}
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
for (int i = 0; i < c; i++) {
out.write(temp[i]);
}
}
//关闭打开的流
bais.close();
out.flush();
out.close();
} /***
* 解密方法 将加密后的文件内容做解密 解密后的内容覆盖原内容
* @param file
* @param password
* @throws Exception
*/
public static void decryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
for (int i = 0; i < c; i++) {
buffer[i] ^= KEYVALUE[pos];
baos.write(buffer[i]);
pos++;
if (pos == keylen)
pos = 0;
}
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
for (int i = 0; i < c; i++) {
out.write(temp[i]);
}
}
//关闭打开的流
bais.close();
out.flush();
out.close();
}
}
关键就在读取和写入上
看看PDF文件格式随便修改几个字段就让它无法打开来的快。
你的想法很不错 我来试一试 只要能找到表示pdf的格式的几个字段能修改就好了
但是也要确保所有的软件都不能打开看到里面的内容
/**
* 加密方法 将文件内容做加密 加密内容覆盖原内容
* @param file
* @param password
*/
public static void encryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte[] tempByte = null;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
tempByte = new byte[c];
System.arraycopy(buffer, 0, tempByte, 0, c);
for (int i = 0; i < c; i+=10) {
tempByte[i] ^= KEYVALUE[pos];
pos++;
if (pos == keylen)
pos = 0;
}
baos.write(tempByte);
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
/* for (int i = 0; i < c; i++) {
out.write(temp[i]);
}*/
out.write(temp);
}
//关闭打开的流
bais.close();
out.flush();
out.close();
} /***
* 解密方法 将加密后的文件内容做解密 解密后的内容覆盖原内容
* @param file
* @param password
* @throws Exception
*/
public static void decryptFile(String file,String password)throws Exception{
//密码的字节数组 用来异或操作
byte[] PASSVALUE=password.getBytes();
int papos=0;
for(int i=0;i<KEYVALUE.length;i++){
KEYVALUE[i]^=PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte[] tempByte = null;
byte buffer[] = new byte[BUFFERLEN];
while ((c = in.read(buffer)) != -1) {
tempByte = new byte[c];
System.arraycopy(buffer, 0, tempByte, 0, c);
for (int i = 0; i < c; i+=10) {
tempByte[i] ^= KEYVALUE[pos];
pos++;
if (pos == keylen)
pos = 0;
}
baos.write(tempByte);
}
//关闭打开的流
in.close();
baos.close();
//缓冲区的有效内容已复制到该数组中
buffer = baos.toByteArray();
FileOutputStream out = new FileOutputStream(file);
// 将位数组内容存回文件
ByteArrayInputStream bais=new ByteArrayInputStream(buffer);
byte [] temp= new byte[BUFFERLEN];
while((c =bais.read(temp))!=-1){
/* for (int i = 0; i < c; i++) {
out.write(temp[i]);
}*/
out.write(temp);
}
//关闭打开的流
bais.close();
out.flush();
out.close();
}
这是我新的方法 用了一个临时数组 发现自己太二了 这个方法都没想到....基本上40M的pdf文件都可以在1S内搞定 可是拿了一个70M的pdf文件实验 java heap space... 报错如下:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at java.io.OutputStream.write(Unknown Source)
at EndeUtil.encryptFile(EndeUtil.java:71)
at TestEndeUtil.main(TestEndeUtil.java:10)就在baos.write的地方 不知道该怎么优化了
关键是 这个方法以后还要可能再android机器上跑 不知道android的虚拟机能有什么配置....
-------------------------四楼的想法楼主可以试试,就是将文件指定位置的一段数据进行加密就可以了,其效率比全部加密肯定要高!
用了一个新的方式 加密解密都快也不会OutOfMemory 了 附上代码:public static void encryptFile(String file, String password)
throws Exception { // 密码的字节数组 用来异或操作
byte[] PASSVALUE = password.getBytes();
int papos = 0;
for (int i = 0; i < KEYVALUE.length; i++) {
KEYVALUE[i] ^= PASSVALUE[papos];
papos++;
if (papos == PASSVALUE.length)
papos = 0;
}
//每次跳跃的字节数
long skippos = 5 * BUFFERLEN; RandomAccessFile raf = new RandomAccessFile(file, "rw"); int c, pos, keylen;
pos = 0;
keylen = KEYVALUE.length;
byte buffer[] = new byte[BUFFERLEN];
/*读取c个字节后,再将指针回退到读取前的位置,将读取的字节进行操作后重新
* 从该指针出写入 覆盖原内容,接着指针seek到下一位置 重复循环*/
while ((c = raf.read(buffer)) != -1) {
raf.seek(raf.getFilePointer() - c);
//跳跃性异或字节 减小花费时间
for (int i = 0; i < c; i+=10) {
buffer[i] ^= KEYVALUE[pos];
pos++;
if (pos == keylen)
pos = 0;
}
//写入c个字节 舍弃write(buffer)方法是因为小文件的大小不是整数KB 导致写入字节过多
raf.write(buffer,0,c);
if (raf.length() > skippos) {
raf.seek(skippos);
skippos += (5 * BUFFERLEN);
}
}
// 关闭打开的流
raf.close();
}
这些数值还可以调整 让速度更快