从 AES-128 原型出发,经历目录协议设计、Huffman 树序列化、压缩/解压主链路、CLI 稳定化,到 Qt GUI、策略模式重构和单文件发布。
929~930:项目初始化
创建基础文件结构和 Git 仓库,编写策划文档。最早一批提交包含 src/Aes.cpp、src/Aes.h,项目起点是加密算法实验。
1001~1005:AES-128 原型
实现完整 AES-128 加密,支持 ECB 模式。密码入口采用 SHA-256 派生,截取前 16 字节作为密钥。密钥扩展生成 44 个轮密钥字,10 轮加密包含 SubBytes、ShiftRows、MixColumns、AddRoundKey。预计算 GF(2^8) 乘法表,查表替代运行时计算。
void SubBytes(state_t &state);void ShiftRows(state_t &state);void MixColumns(state_t &state);void AddRoundKey(state_t &state);1011~1030:架构设计与并发框架
项目从单文件实验转向模块化。策划文档确定”压缩、加密、调度、数据交互”四层关系。
1021:重构文件结构,目录按职责拆分为 CompressionModules、EncryptionModules、DataStream。10231024:1030:优化线程池任务调度,实现任务队列管程。添加 ThreadPool 实现工作线程管理和任务分发,TaskQueue 封装条件变量,线程安全的入队/出队。补上 IModule 抽象、命名空间与数据块类型定义。策略模式接口 CompressionStrategy、EncryptionStrategy、DataInteraction 落位。1026:绘制压缩流程图,设计解压流程。1028Locator 定位器——封装所有 seekg/seekp,负责在文件头、目录块和数据区之间定位。
class IModule {public: virtual void work(block_t* data) = 0; virtual ~IModule() = default;};1101~1113:HeaderReader 原型与路径兼容性
HeaderReader 从 Day6 原型迭代到 v0.1.5,逐步补齐位流读取、filesystem 接入、读取流程修正。抛弃 POSIX,使用标准库 filesystem。引入 MyQueue 等辅助结构,为文件队列、目录队列和目录块解析打前站。首次尝试宽字符方案处理 Windows 路径。
1117~1121:HeaderLoader、DirectoryReader 与压缩主链路
引入 HeaderLoader、FileLibrary,统一文件头字段、目录读取入口与归档元数据。HeaderReader 按职责演化为 DirectoryReader。Huffman 频率统计模块完成,开始接入 encode 压缩模块,压缩主链路首次成型。
1123~1130:HeaderWriter、Huffman 编码表与 AES-CFB
HeaderWriter v0.1.2~v0.1.4:文件头写入框架、编码表数据类 EntryDetails、编码表生成/加载模块。编码树序列化固定为先序遍历——叶子 'l' + 字节值,内部节点 'r'。std::map 替换为 std::unordered_map 提升哈希查找性能。修复 sizeof 返回值类型问题和偏移量计算边界。
HeaderLoader v0.0.1~v0.0.5:文件头读取、AES-CFB 模式适配、IV 支持和目录块加载解析。AES 从 ECB 改为 CFB——CFB 不改变数据长度,便于在分割标准中记录 IV。
struct Header { SizeOfMagicNum magicNum_1 = 0; // 0xDEADBEEF CompressStrategy strategy = 0; CompressorVersion version = 0; HeaderOffsetSize headerOffset = 0; DirectoryOffsetSize directoryOffset = 0; SizeOfMagicNum magicNum_2 = 0; // 0xDEADBEEF}; // 共 19 字节1201~1206:数据块表示与压缩侧联通
压缩模块、加密模块、DataLoader、DataExporter 统一使用 DataBlock = std::vector<uint8_t>。模块只接收字节数据,不关心上游来源。整理 Y_flib 命名空间,HeaderLoader 分块读取采用迭代器混合状态机模式。
HeaderWriter v0.1.5 扩展:目录协议增加符号链接标准,Separated 标准扩展为”块大小 + IV + 分块标识”。输出流程:写文件头 → 写目录块 → 读目录块 → 按块处理 → 目录块加密 → 回填大小。
1208~1209:AES 模块补齐
AES 从独立算法代码转成归档流程模块。添加乘法表 GF_MUL_2、GF_MUL_3、GF_MUL_9、GF_MUL_11、GF_MUL_13、GF_MUL_14,查表减少运行时 GF(2^8) 乘法计算耗时。
1210~1212:BFS 目录遍历与逻辑根目录
EntryProcessor BFS 目录遍历。输入文件和目录先挂到逻辑根目录下,再由队列按层序遍历。目录块每写满 16KB 插入一条分割标准。BFS 直接服务目录恢复——解压器只按目录标准和 childCount 推进队列,不需要外部目录描述文件。逻辑根目录解决多文件/多文件夹的森林合并问题。
void EntryProcessor::flowScanner(...){ // 1. 写入逻辑根节点 // 2. 处理用户指定的文件/目录列表 // 3. 循环从队列取出目录,处理其内容 // 4. 遇到子目录时加入队列继续遍历}1213~1217:解压流程
解压主体是 BinaryStandardLoader。内部维护 fileQueue、entryQueue、directoryQueueReady、blockPosition。读取器先验证魔数、读取文件头、定位 directoryOffset,逐块读取目录块,再交给 EntryParser 解析。
读取 .sy 文件 → 验证魔数 → 跳转到目录块偏移 → 按需解密目录块 → 解析文件队列和目录队列 → 创建目录结构 → 逐块读取数据区 → 解密 Huffman 树 → 重建树 → 解密压缩数据 → Huffman 解码 → 写回文件1218~1225:工程整理与 CLI 交互
std::map 替换为 std::unordered_map,CLI 相关代码整理。采用耦合设计:目录块、树数据、压缩数据、加密过程全部写进压缩/解压主循环。
1230~1231:Huffman 单字符边界问题
数据块全部由同一字节组成时,Huffman 树只有一个叶子节点,常规构造失效。处理方式:叶子节点数为 1 时,编码直接写成 {0},长度记为 1。单字符文件和单字符数据块纳入标准流程。
if (countLeaves(treeroot) == 1) { hashtab[onlyChar].code = {0}; hashtab[onlyChar].codelen = 1;}260101~260106:首个 CLI 预览版本
v1.0.0 Preview 发布。CLI 加密压缩与解压全流程完成。偏移量类型统一为 uint64_t,目录缓冲区大小固定为 16KB,constexpr const 历史写法清理,README 补全。
260302~260315:CLI 稳定化
FlagType 改成强类型枚举,目录接口、工具类接口和文件已存在时的处理方式同步整理。目录块边界写入问题修复——目录条目恰好落在分块边界时产生空分块或解析错位。长路径尝试(\\?\ 前缀)因 API 限制放弃,保留 UTF-8 中文路径和常规 Windows 路径。移除 OpenSSL 依赖,改用 Windows CryptoAPI。
enum class FlagType : char{ Directory = '0', File = '1', Separated = '2', LogicalRoot = '3', SymbolLink = '4'};260401:构建系统迁移
从 GCC 迁移到 MSVC + CMake。关闭 CMAKE_INTERPROCEDURAL_OPTIMIZATION,目的是使用 VS 性能分析报告。
260412~260415:GUI 工程建立
代码清理,开始编写 Qt Widgets。Y_Manager_GUI 工程建立,CMake 配置和后台任务执行框架完成。GUI 设计隔离:Y_Manager 和 CompressorFileSystem 负责主逻辑,GUI 负责参数录入、结果展示和线程调度。修复 directoryOffset 写入时机问题。
260416:Qt GUI 主体
GUI 主体围绕 MainWindow、CompressionWorker、QThread 组织。MainWindow 收集源路径、输出目录、模式和密码,CompressionWorker 在后台线程调用主流程,进度通过信号送回 UI 线程。
MainWindow (UI线程) → QThread → CompressionWorker → CompressionLoop / DecompressionLoop ← detailedProgress / finished进度信号双层节流:MainLoop 控制核心层回调频率,CompressionWorker 按时间和百分比变化量再做一层。窗口关闭时通过 std::atomic<bool> m_stopRequested 请求停止,析构阶段等待线程退出。
文件句柄和缓冲区释放:BinaryStandardLoader::setAllLoopDone()、DecompressionLoop::createFile()、std::vector 缓冲复用、Heffman::merge_ttabs() 容量释放都进入正式代码。
中文路径与编码处理
GUI 接入后暴露路径编码差异。Qt 层传入 UTF-8,std::filesystem 在 Windows 下可能关联本地代码页。修正规则集中在 EncodingUtils:Qt 边界处统一 UTF-8,进入核心层前转 UTF-8,进入文件系统前用 pathFromUtf8(),回到日志或 GUI 时用 pathToUtf8()。目录遍历和文件名序列化统一 u8string()。输出目录乱码修复:UTF-8 文本先转路径对象,再交给 DecompressionLoop。
Qt 工具链与系统兼容性
GUI 发布收敛到 Qt 6.2.4 LTS。MSYS2 MinGW 15.x 构建版本出现过 nanosleep64 缺失,Qt 6.10.1 部分在旧版 Windows 10 不稳定。Qt 6.2.4 统一图形界面、路径转换、线程模型和静态发布环境。兼容 Windows 10 1809+。
260417:多策略支持与发布形态调整
主流程原本把 Huffman + AES 写死。重构后引入 CompressionMode 枚举、StrategyFactory、ICompression/IEncryption、NullCompression、NullEncryption,压缩和加密组合改由运行时装配。CompressionLoop、DecompressionLoop 和 BinaryStandardLoader 由依赖具体类改为依赖接口。解压侧通过 Header.strategy 还原模式,策略号 0 继续映射 HuffmanAES,旧归档保持兼容。
enum class CompressionMode : uint8_t{ HuffmanAES = 0, HuffmanOnly = 1, AESOnly = 2, PackOnly = 3};发布形态调整:动态部署约 57MB,静态发布改用 Qt 6.2.4 静态库,构建开关 USE_STATIC_QT,翻译文件和图片资源内嵌,背景图从 PNG 改 JPEG。默认发布体积约 16MB,不携带额外依赖。
260418~260419:编码整理、翻译与工程清理
编码规则固定:GUI 输入统一转 UTF-8,核心层字符串按 UTF-8 组织,接触文件系统时转 std::filesystem::path。编码转换职责全部归入 EncodingUtils。
GUI 多语言规则:界面文案统一 tr() 包装,翻译资源通过 resources.qrc 内嵌,语言选择优先 SFC_GUI_LANGUAGE,未指定时按 QLocale::system()。单 exe 发布下翻译不依赖外部目录。日志和技术状态文本保持英文。
工程整理:头文件、命名空间、.gitignore 和临时验证目录清理。代码布局与功能布局对齐。
结果
从 AES 算法实验到完整桌面归档工具。处理的问题:AES-128 + CFB 模式、Huffman 编码树序列化、BFS 目录遍历与逻辑根目录、目录块边界、BinaryStandardLoader 和 EntryParser 目录恢复、Huffman 单字符边界、UTF-8 编码统一、GUI 线程模型与进度节流、策略模式重构、Qt 静态链接与单文件发布。
部分信息可能已经过时
粤公网安备44011102484817号