LZMA2 压缩技术解析与高性能加密压缩脚本模块化解读

LZMA2 压缩技术解析与高性能加密压缩脚本模块化解读

一、LZMA2 压缩技术核心介绍

LZMA2 是 LZMA 算法的升级版本,是目前工业界压缩比和压缩效率兼具的主流无损压缩算法之一,广泛应用于数据归档、文件分发等场景,其核心特性如下:

1.1 核心优势

  • 超高压缩比:基于 LZ77 字典压缩 + Range 编码,压缩比远超 ZIP、GZIP 等传统算法,对于文本、文档、代码等结构化数据,压缩比可提升 30%-50%;
  • 灵活的参数配置:支持字典大小(1MB~1536MB)、压缩级别(0-9)自定义,级别越高 / 字典越大,压缩比越高(但耗时略增);
  • 硬件友好性:算法可拆分数据块并行处理,适配多核心 CPU 加速,兼顾压缩效率与性能;
  • 标准化支持:是 XZ 格式的默认压缩算法,跨平台兼容性强(Windows/macOS/Linux 均原生支持)。

1.2 适用场景

LZMA2 尤其适合 "一次压缩、多次读取" 的场景,如:

  • 办公文件归档(文档、表格、报销凭证等);
  • 代码 / 日志文件压缩;
  • 敏感数据加密压缩(结合 AES 加密);
  • 大文件 / 文件夹的高压缩比存储。

二、高性能 LZMA2 加密压缩脚本模块化解析

本文解析的脚本是基于 Python 实现的 "硬件加速 + AES-256 加密"LZMA2 压缩工具,兼顾高压缩比、多核心加速、数据加密三大核心能力,整体采用模块化设计,各模块职责清晰、可复用性强。

2.1 脚本整体架构

脚本核心分为基础配置模块硬件适配模块加密模块压缩核心模块文件夹 / 文件处理模块解压模块命令行交互模块七大核心模块,整体架构如下:

复制代码
├── 基础配置模块:全局参数、信号处理
├── 硬件适配模块:CPU核心/内存字典大小自动计算
├── 加密模块:AES-256-CBC加密/解密实现
├── 压缩核心模块:多进程分块压缩、进度统计
├── 文件/文件夹处理模块:单文件/文件夹差异化压缩逻辑
├── 解压模块:加密压缩包解密+解压
└── 命令行交互模块:用户输入解析、操作执行

2.2 各模块功能与核心代码解析

模块 1:基础配置模块(全局参数与信号处理)

核心职责:定义全局常量、处理程序中断信号、提供通用工具函数,是脚本的基础支撑层。

复制代码
import os
import signal
import multiprocessing
from datetime import datetime

# 1. 全局核心配置(常量定义)
ENCRYPT_PASSWORD = b"xxxxxx"  # 加密固定密码
g_output_path = None  # 全局输出路径(用于中断清理)
total_original_size = 0  # 原始文件总大小
CPU_CORES = multiprocessing.cpu_count()  # 自动获取CPU核心数

# 2. 中断信号处理(优雅终止+清理临时文件)
def handle_interrupt(signal_num, frame):
    """捕获Ctrl+C等终止信号,清理未完成的压缩文件"""
    print("\n⚠️  接收到终止信号,正在清理...")
    if g_output_path and os.path.exists(g_output_path):
        os.remove(g_output_path)
    print("✅ 清理完成,已终止压缩")
    exit(1)
signal.signal(signal.SIGINT, handle_interrupt)  # 注册信号处理

# 3. 通用工具函数(复用性强)
def get_file_size(path):
    """递归计算文件/文件夹总大小(字节),适配文件/文件夹两种输入"""
    if os.path.isfile(path):
        return os.path.getsize(path)
    total = 0
    for root, _, files in os.walk(path):
        for file in files:
            try:
                total += os.path.getsize(os.path.join(root, file))
            except OSError:
                print(f"⚠️  无法获取文件大小:{file_path}")
    return total

def format_size(size_bytes):
    """字节数转易读格式(B/KB/MB/GB),全局复用"""
    for unit in ['B', 'KB', 'MB', 'GB']:
        if size_bytes < 1024.0:
            return f"{size_bytes:.2f} {unit}"
        size_bytes /= 1024.0
    return f"{size_bytes:.2f} TB"

关键说明

  • 全局常量集中定义,便于后续维护(如修改密码、调整默认参数);
  • 信号处理保证程序异常终止时不残留无效文件;
  • 工具函数解耦,可单独复用(如其他脚本需计算文件大小、格式化字节数)。
模块 2:硬件适配模块(CPU / 内存智能适配)

核心职责:根据运行环境自动计算最优硬件参数,最大化压缩性能,体现 "硬件加速" 核心特性。

复制代码
import subprocess
import ctypes

def get_optimal_dict_size():
    """根据物理内存自动计算LZMA2最优字典大小(≤内存1/4),平衡压缩比与内存占用"""
    try:
        # 区分macOS/Linux/Windows获取总内存
        if os.name == 'posix':
            if os.uname().sysname == 'Darwin':  # macOS
                mem_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']).strip())
            else:  # Linux
                mem_bytes = int(subprocess.check_output(['grep', 'MemTotal', '/proc/meminfo']).split()[1]) * 1024
        elif os.name == 'nt':  # Windows
            class MEMORYSTATUSEX(ctypes.Structure):
                _fields_ = [("dwLength", ctypes.c_ulong), ("dwMemoryLoad", ctypes.c_ulong),
                            ("ullTotalPhys", ctypes.c_ulonglong), ("ullAvailPhys", ctypes.c_ulonglong)]
            stat = MEMORYSTATUSEX()
            stat.dwLength = ctypes.sizeof(MEMORYSTATUSEX)
            ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat))
            mem_bytes = stat.ullTotalPhys
        else:
            mem_bytes = 8 * 1024 * 1024 * 1024  # 默认8GB
        
        # 字典大小限制:1MB~1536MB(LZMA2最大支持)
        dict_size = min(mem_bytes // 4, 1536 * 1024 * 1024)
        dict_size = max(dict_size, 1 * 1024 * 1024)
        return dict_size
    except:
        return 64 * 1024 * 1024  # 异常时默认64MB

# 预计算最优字典大小(全局复用)
OPTIMAL_DICT_SIZE = get_optimal_dict_size()

关键说明

  • 字典大小是 LZMA2 压缩比的核心参数,自动适配内存避免 "内存不足" 或 "内存浪费";
  • 跨平台兼容,适配不同操作系统的内存获取方式;
  • 预计算字典大小,避免重复计算,提升性能。
模块 3:加密模块(AES-256-CBC 加密 / 解密)

核心职责:实现工业级 AES-256-CBC 加密,保证压缩后数据的安全性,与压缩逻辑解耦。

复制代码
import hashlib
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding

# 预生成Key/IV(避免重复计算,提升加密性能)
key = hashlib.pbkdf2_hmac('sha256', ENCRYPT_PASSWORD, b"LZMA2_SALT_2025", 10000, dklen=32)
iv = hashlib.md5(ENCRYPT_PASSWORD + b"IV_DERIVE_2025").digest()

def encrypt_data_fast(data):
    """高速AES-256-CBC加密(预生成Key/IV,批量处理数据)"""
    if not data:
        return b""
    # PKCS7填充(AES要求数据长度为16字节倍数)
    padder = padding.PKCS7(128).padder()
    padded_data = padder.update(data) + padder.finalize()
    # 加密核心逻辑
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(padded_data) + encryptor.finalize()

def decrypt_data_fast(encrypted_data):
    """AES-256-CBC解密(与加密逻辑对称,供解压使用)"""
    if not encrypted_data:
        return b""
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    padded_data = decryptor.update(encrypted_data) + decryptor.finalize()
    # 去除填充
    unpadder = padding.PKCS7(128).unpadder()
    return unpadder.update(padded_data) + unpadder.finalize()

关键说明

  • 采用 PBKDF2_HMAC 生成 32 字节 AES-256 密钥,提升密码安全性(避免硬编码密钥);
  • 预生成 Key/IV,避免每次加密 / 解密重复计算哈希,大幅提升性能;
  • 加密 / 解密函数解耦,仅依赖输入数据,可单独测试 / 复用。
模块 4:压缩核心模块(多进程分块压缩)

核心职责:实现 LZMA2 多进程并行压缩,是 "硬件加速" 的核心逻辑,适配单文件压缩场景。

复制代码
import lzma

CHUNK_SIZE = 1024 * 1024 * 16  # 16MB分块(平衡并行效率与内存)

def compress_chunk(args):
    """单数据块压缩(供多进程调用),独立函数便于进程间分发"""
    data, level, dict_size = args
    # LZMA2核心配置(仅用filter chain,避免preset与filter冲突)
    filters = [{'id': lzma.FILTER_LZMA2, 'dict_size': dict_size, 'preset': level}]
    return lzma.compress(data, format=lzma.FORMAT_XZ, filters=filters)

def compress_file_fast(input_path, output_path, level):
    """单文件高速压缩+加密:多进程压缩→批量加密→进度统计"""
    global processed_size
    processed_size = 0
    dict_size_mb = OPTIMAL_DICT_SIZE // (1024*1024)
    print(f"💻 硬件配置:{CPU_CORES}核 | 字典{dict_size_mb}MB | 分块{CHUNK_SIZE//1024//1024}MB")
    
    # 多进程池(复用CPU核心)
    pool = multiprocessing.Pool(CPU_CORES)
    if os.path.exists(output_path):
        os.remove(output_path)

    with open(input_path, 'rb') as f_in, open(output_path, 'wb') as f_out:
        f_out.write(b"LZMA2_ENCRYPTED\x00")  # 加密标识(供解压识别)
        while True:
            # 批量读取数据块(数量=CPU核心数,最大化并行)
            chunks = []
            for _ in range(CPU_CORES):
                chunk = f_in.read(CHUNK_SIZE)
                if not chunk:
                    break
                chunks.append(chunk)
            if not chunks:
                break

            # 1. 多进程并行压缩(硬件加速核心)
            compressed_chunks = pool.map(compress_chunk, [(c, level, OPTIMAL_DICT_SIZE) for c in chunks])
            # 2. 批量加密(减少加密调用次数)
            encrypted_chunks = [encrypt_data_fast(cc) for cc in compressed_chunks]

            # 3. 写入数据+进度统计
            for ec in encrypted_chunks:
                f_out.write(ec)
            processed_size += sum(len(c) for c in chunks)
            # 实时进度显示
            progress = min(processed_size/total_original_size*100, 100.0)
            elapsed = time.time() - start_time
            speed = processed_size/elapsed if elapsed > 0 else 0
            print(f"\r📊 进度: {progress:.2f}% | 速度: {format_size(speed)}/s", end="", flush=True)

    pool.close()
    pool.join()

关键说明

  • 分块压缩 + 多进程池,最大化利用多核心 CPU(如 8 核 CPU 同时处理 8 个数据块);
  • 压缩与加密解耦:先批量压缩,再批量加密,避免小数据块频繁加密的性能损耗;
  • 进度统计实时化,提升用户体验,且进度计算基于原始数据大小(更符合用户感知)。
模块 5:文件夹处理模块(Tar 打包 + 压缩 + 加密)

核心职责:适配文件夹压缩场景,先 Tar 打包(统一格式),再复用压缩 / 加密逻辑。

复制代码
import tarfile
import io

def compress_folder_fast(input_path, output_path, level):
    """文件夹高速压缩:内存Tar打包→多进程压缩→整体加密(避免逐块操作性能损耗)"""
    global processed_size
    processed_size = 0
    print(f"📦 正在打包文件夹...")
    # 1. 内存Tar打包(避免临时文件,提升速度)
    tar_buffer = io.BytesIO()
    with tarfile.open(fileobj=tar_buffer, mode='w') as tar:
        tar.add(input_path, arcname=os.path.basename(input_path))
    tar_buffer.seek(0)
    tar_data = tar_buffer.read()
    print(f"📦 打包完成:{format_size(len(tar_data))}")

    # 2. 多进程压缩(复用单文件压缩逻辑)
    pool = multiprocessing.Pool(CPU_CORES)
    chunks = [tar_data[i:i+CHUNK_SIZE] for i in range(0, len(tar_data), CHUNK_SIZE)]
    compressed_chunks = pool.map(compress_chunk, [(c, level, OPTIMAL_DICT_SIZE) for c in chunks])
    compressed_data = b''.join(compressed_chunks)
    pool.close()
    pool.join()

    # 3. 整体加密+写入文件
    print("🔐 正在加密...")
    encrypted_data = encrypt_data_fast(compressed_data)
    with open(output_path, 'wb') as f_out:
        f_out.write(b"LZMA2_ENCRYPTED\x00")
        f_out.write(encrypted_data)
    # 进度统计
    processed_size = total_original_size
    progress = 100.0
    print(f"\r📊 进度: {progress:.2f}% | 完成压缩+加密", end="", flush=True)

关键说明

  • 先内存 Tar 打包,再整体处理,避免逐文件打包 + 压缩的频繁 IO 操作;
  • 复用压缩核心模块的compress_chunk函数,保证压缩逻辑一致性;
  • 整体加密大幅减少加密调用次数(26MB 文件夹仅需 1 次加密),解决小文件加密速度慢的问题。
模块 6:解压模块(解密 + 解压)

核心职责:与压缩逻辑对称,实现加密压缩包的解密 + 解压,保证功能闭环。

复制代码
def decompress_lzma2_encrypted(input_path, output_path=None):
    """解密+解压核心逻辑:验证标识→解密→LZMA2解压→Tar解包"""
    if not os.path.exists(input_path):
        raise FileNotFoundError(f"❌ 文件不存在:{input_path}")
    # 输出路径处理
    if output_path is None:
        output_path = os.path.splitext(os.path.basename(input_path))[0]
    os.makedirs(output_path, exist_ok=True)

    print(f"🔐 解密解压:{input_path}")
    with open(input_path, 'rb') as f_in:
        # 1. 验证加密标识(避免解压非加密文件)
        magic = f_in.read(16)
        if magic != b"LZMA2_ENCRYPTED\x00":
            raise ValueError("❌ 不是加密的LZMA2压缩包")
        # 2. 读取并解密
        encrypted_data = f_in.read()
        compressed_data = decrypt_data_fast(encrypted_data)
        # 3. LZMA2解压
        decompressed_data = lzma.decompress(compressed_data, format=lzma.FORMAT_XZ)
        # 4. Tar解包
        tar_buffer = io.BytesIO(decompressed_data)
        with tarfile.open(fileobj=tar_buffer, mode='r') as tar:
            tar.extractall(output_path)
    print(f"✅ 解压完成!输出:{output_path}")

关键说明

  • 加密标识验证,避免错误解压非加密文件;
  • 解密→解压→解包流程与压缩流程完全对称,保证数据完整性;
  • 内存缓冲区解包,避免临时文件,提升解压速度。
模块 7:命令行交互模块(用户输入解析)

核心职责:解析用户命令行输入,分发到压缩 / 解压逻辑,是脚本的 "入口层"。

复制代码
import argparse

def main():
    """脚本入口:解析命令行参数,执行压缩/解压操作"""
    parser = argparse.ArgumentParser(description='LZMA2 高速压缩+加密脚本(硬件加速)')
    subparsers = parser.add_subparsers(dest='command', help='命令:compress/decompress')

    # 压缩子命令
    compress_parser = subparsers.add_parser('compress', help='压缩+加密文件/文件夹')
    compress_parser.add_argument('input', help='待压缩路径')
    compress_parser.add_argument('-o', '--output', help='输出路径')
    compress_parser.add_argument('-l', '--level', type=int, default=9, help='压缩级别0-9')

    # 解压子命令
    decompress_parser = subparsers.add_parser('decompress', help='解密+解压压缩包')
    decompress_parser.add_argument('input', help='加密压缩包路径')
    decompress_parser.add_argument('-o', '--output', help='输出路径')

    args = parser.parse_args()
    global g_output_path, start_time, total_original_size
    try:
        if args.command == 'compress':
            # 压缩前初始化
            g_output_path = args.output
            total_original_size = get_file_size(args.input)
            start_time = time.time()
            # 执行压缩
            compress_with_lzma2(args.input, args.output, args.level)
        elif args.command == 'decompress':
            # 执行解压
            decompress_lzma2_encrypted(args.input, args.output)
        else:
            parser.print_help()
    except Exception as e:
        print(f"\n❌ 操作失败:{str(e)}")
        if g_output_path and os.path.exists(g_output_path):
            os.remove(g_output_path)
        exit(1)

# 脚本入口
if __name__ == "__main__":
    main()

关键说明

  • 子命令模式解析输入,逻辑清晰(compress/decompress 区分操作);
  • 异常捕获 + 错误清理,避免残留无效文件;
  • 压缩前初始化全局参数,保证进度统计、硬件适配等模块正常工作。

2.3 脚本核心设计亮点

  1. 模块化解耦:各模块职责单一,可独立修改 / 复用(如加密模块可单独用于其他脚本);
  2. 硬件自适应:无需手动配置 CPU 核心 / 字典大小,脚本自动适配运行环境;
  3. 性能优化:内存操作替代磁盘 IO、批量处理替代逐块操作、多进程并行压缩,大幅提升速度;
  4. 安全保障:AES-256-CBC 加密 + 密码派生 Key/IV,保证敏感数据(如差旅报销文件)安全;
  5. 用户体验:实时进度显示、易读的大小格式化、异常友好提示,提升使用体验。

三、总结

LZMA2 作为高性能压缩算法,结合多核心硬件加速与 AES-256 加密后,成为敏感办公数据归档的理想选择。本文解析的脚本通过模块化设计,实现了 "高压缩比 + 高性能 + 高安全" 的统一,各模块解耦且可复用,既保证了功能完整性,又便于后续维护与扩展(如新增压缩格式、调整加密算法等)。

相关推荐
RisunJan6 小时前
Linux命令-gpasswd命令(管理用户组的重要工具)
linux·运维·服务器
where happens7 小时前
centos创建目录并授予权限
linux·运维·服务器·centos
liebe1*17 小时前
第七章 防火墙地址转换
运维·服务器·网络
好好学操作系统7 小时前
autodl 保存 数据 跨区
linux·运维·服务器
dbitc7 小时前
WIN11把WSL2移动安装目录
linux·运维·ubuntu·wsl
旺仔Sec7 小时前
2026年度河北省职业院校技能竞赛“Web技术”(高职组)赛项竞赛任务
运维·服务器·前端
BullSmall7 小时前
linux 根据端口查看进程
linux·运维·服务器
嘻哈baby8 小时前
Ansible自动化运维入门:从手工到批量部署
运维·自动化·ansible
Hard but lovely8 小时前
linux:----进程守护化(Daemon)&&会话的原理
linux·运维·服务器