我有一个加密和解密代码,用于加密和解密视频文件(mp4)。我正在尝试加快解密过程,因为加密过程与我的情况不相关。这是我对解密过程的代码:
private static void decryptFile() throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException
{
//int blockSize = cipher.getBlockSize();
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
System.out.println("outputsize: " + outputSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
in= new FileInputStream(inputFile);
out=new FileOutputStream(outputFile);
BufferedInputStream inStream = new BufferedInputStream(in);
int inLength = 0;;
boolean more = true;
while (more)
{
inLength = inStream.read(inBytes);
if (inLength == blockSize)
{
int outLength
= cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
}
else more = false;
}
if (inLength > 0)
outBytes = cipher.doFinal(inBytes, 0, inLength);
else
outBytes = cipher.doFinal();
out.write(outBytes);
}
我的问题是如何加快此代码中的解密过程。我试过解密一个10MB的mp4文件,然后在6-7秒内解密。但是,我的目标是< 1秒我想知道的另一件事是,我对FileOutputStream的写入实际上是在减慢进程而不是解密进程本身。关于如何在这里加快速度的任何建议。
我正在使用AES进行加密/解密。
在找到解决方案之前,我将使用ProgressDialog告诉用户等待视频解密(显然,我不会使用“解密”这个词。
答案 0 :(得分:4)
为什么仅以blockSize
增量解密数据?您没有显示对象cipher
的类型,但我猜这是一个javax.crypto.Cipher
实例。它可以通过任意长度的数组处理update()
调用,如果使用更长的数组,您将获得更少的开销。您应该按照8192字节的块处理数据(这是缓冲区的传统长度,它与CPU内部缓存的交互性相当好。)
答案 1 :(得分:1)
bytebiscuit,你的问题给了我过去6天尝试的解决方案。我刚刚修改了你的代码,我的52 mb视频文件在4秒内就被解密了。以前的解密技术需要45秒,这是一个不同的逻辑(不是你的)。这是一个巨大的差异45秒到4秒。我在哪里做了修改我正在修改//修改注释行。我相信如果您的视频是10mb视频,它肯定会在1秒内解密。尝试应用它,它应该可以解决。
private static void decryptFile() throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException
{
//int blockSize = cipher.getBlockSize();
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
System.out.println("outputsize: " + outputSize);
byte[] inBytes = new byte[blockSize*1024]; //modified
byte[] outBytes = new byte[outputSize * 1024]; //modified
in= new FileInputStream(inputFile);
out=new FileOutputStream(outputFile);
BufferedInputStream inStream = new BufferedInputStream(in);
int inLength = 0;;
boolean more = true;
while (more)
{
inLength = inStream.read(inBytes);
if (inLength/1024 == blockSize) //modified
{
int outLength
= cipher.update(inBytes, 0, blockSize*1024, outBytes);//modified
out.write(outBytes, 0, outLength);
}
else more = false;
}
if (inLength > 0)
outBytes = cipher.doFinal(inBytes, 0, inLength);
else
outBytes = cipher.doFinal();
out.write(outBytes);
}
答案 2 :(得分:-1)
我建议你使用android sdk中提供的分析工具。它会告诉你你花费最多的时间(即:文件写入或解码)。
请参阅http://developer.android.com/guide/developing/debugging/debugging-tracing.html
这可以在模拟器上以及在实际设备上进行。
答案 3 :(得分:-1)
考虑使用NDK。在Froyo之前的设备上(甚至是Froyo本身),由于缺少JIT(或者在Froyo中非常简单),它会非常慢。即使使用JIT,本机架构优化的加密代码也总是超过Dalvik。
顺便说一句,如果您直接使用AES,则可能是doing something wrong。如果这是努力做DRM的一部分,请确保您充分认识到反编译Android应用程序是微不足道的。您的密钥不会是安全的,根据定义,它会使加密失败。
答案 4 :(得分:-1)
您应该考虑使用流式解决方案,而不是花费精力来改进不适当的架构:它有很大的优势来分散解密的计算时间,使其变得不再明显。我的意思是:不要从您的视频源生成另一个文件,而是使用本地http服务器生成流。遗憾的是,SDK中没有这样的组件,您必须自己实现或搜索现有的组件。