写点什么

Qt 解压带有密码的加密文件

  • 2022 年 10 月 01 日
    河北
  • 本文字数:1795 字

    阅读完需:约 6 分钟

Qt解压带有密码的加密文件

上一章节中介绍了如何使用 Qt 编译 quazip 库以及对文件加解密的简单应用,那么,今天我们继续深挖关于解密操作的功能吧!

简单的解密一个压缩包,可以使用#include "JlCompress.h"中的函数进行静态操作。如果你只是需要简单的应用那么,这个文件中的功能就基本可以满足了。

在我们开发过程中,为了资料的保密性期间,一般情况下都会对压缩包进行加密,那么我们还要使用静态函数的方式进行解密那就不支持了。那么,我们该如何解密带有密码的加密文件呢?

这也是当前文章中的重点啦!

根据官网上给出的结果,一般我们会采取 QuaZipFile 类来进行非静态的解密方式,该方式也支持了带有密码的压缩包文件。

接下来我来具体讲述该如何实现带有密码的压缩包解密方法吧!

开发环境:VS2017 + Qt5.14.2 x64 win10 系统


功能讲解

第一步:指定 zip 压缩包状态

在我们操作压缩包的时候,首先要做的就是指明当前是需要压缩还是解压缩文件。

当前,我们实现的功能是解压缩文件,代码实现

QuaZip zip(qsZipFiles);zip.open(QuaZip::mdUnzip); //解压模式打开
复制代码

打开 Zip 文件的方式有以下几种

第二步:创建解压文件

当我们成功打开压缩文件后的第一步需要创建解压文件,否则解压的文件无法存储。

QString dstPath = qsUnzipFiles;if (!dstPath.endsWith("/") && !dstPath.endsWith("\\")){	dstPath += "/";}
QDir dir(qsUnzipFiles);if (!dir.exists()){ dir.mkpath(qsUnzipFiles);}
复制代码

第三步:获取实际的压缩数量

int nCount = zip.getEntriesCount(); //压缩实体数量
复制代码

第四步:遍历方式创建解压缩文件

这也是解压缩文件的重点了。

QuaZip::goToFirstFile:将当前文件设置为存档中的第一个文件

QuaZip::goToNextFile:将当前文件设置为存档中的下一个文件

以 for 循环遍历的方式进行查询,在这里与之前的 for 循环不同的是以上两个函数的返回值都是 bool 值,这里我们也需要遍历 bool 值

for (bool suc = zip.goToFirstFile(); suc; suc = zip.goToNextFile()){    //实际的文件处理}
复制代码

这个文件查找方式是如何操作的呢?

在实际运行过程中,goToFirstFile 函数会从当前文件夹中的第一个文件夹进行遍历,一直遍历到该文件夹下面没有子文件为止。然后才会访问第二个文件夹。


在 for 循环中的实际处理是如何呢?


4.1:设置解压文件的参数

1:设置压缩包的名称

QuaZipFile zipFile;QString qsTempZipName = zip.getZipName();zipFile.setZipName(qsTempZipName);
复制代码

2:设置当前需要解压的文件

QString filename = zip.getCurrentFileName();zipFile.setFileName(filename);
复制代码

代码解析:获取当前正在访问的文件夹,并设置需要读取的文件夹名称

在后来的几天里我也继续再用这个解密功能,发现了这样一个问题,当解密出来的文件有中文时,居然是乱码!!是乱码!!

经过资料查阅,发现,这是 Quazip 的一个 bug,但是我也不能带着乱码去创建文件,也尝试各种 QString 中文乱码的问题,我只能说,别尝试了放弃吧,都不行的。

我的解决方法:将 QString 字符串转换成 std::string 字符串,再有 string 转成 unicode 类型字符串,就可以实现乱码转换了。

经过代码调试之后发现,此时将中文 utf-8 格式字符串转成 unicode 之后,4.2 步骤时,总是返回 false,所以 getCurrentFileName()函数返回的字符串此时还不能进行类型转换,最好的方式需要在实际创建解压文件时再次做出,也就是 4.4 步骤中。

虽然实现起来比较坎坷,但是确实好用,具体的转换,可以看我的这篇文章:unicode与utf8转换

4.2:以读的方式打开加密文件

bool bOpen = zipFile.open(QIODevice::ReadOnly, chPassword);if(bOpen == false)    return false;
复制代码

代码解析:只有在返回值 bOpen 是 true 的情况下才代表了读取成功。

如果返回值是 false,在路径没有问题的情况下,基本上是密码错误。

注意!!!

在这里需要强烈注意的一点是:输入的密码一定是const char*类型,否则返回值一直是 false。这个坑真的是让我特别无语!


4.3:获取当前文件的所有内容

QByteArray data = zipFile.readAll();zipFile.close();
复制代码

使用 readAll 的方式读取文件,这个方法就不再过多说明了,很简单,一定要记得,读取文件之后一定要关闭文件!

4.4:创建解压缩后的同名文件

if (filename.endsWith("/")){	dir.mkpath(filename);}else{	dstFile.setFileName(dstPath + filename);	if (!dstFile.open(QIODevice::WriteOnly))	{		return false;	}	dstFile.write(data);	dstFile.close();
}
复制代码

第五步:关闭 zip 压缩包

zip.close();
复制代码


用户头像

书山有路勤为径,学海无涯苦作舟 2022.07.01 加入

擅长语言:C++ 涉及语言:Python

评论

发布
暂无评论
Qt解压带有密码的加密文件_c++_中国好公民st_InfoQ写作社区