You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中使用AES-CBC算法加解密大文件并实现加密进度指示器

Node.js大文件加密新增进度指示器实现方案

核心逻辑是通过统计可读流已读取的字节数,和源文件总大小的比值计算实时进度,同时补充了原代码遗漏的初始向量(IV)存储逻辑,避免加密后无法解密的问题。

完整实现代码

import fs from 'fs';
import zlib from 'zlib';
import crypto from 'crypto';

// 配置参数
const SOURCE_FILE = 'X:/File.mp4';
const ENC_FILE = 'X:/File.mp4.enc';
const PASSWORD = 'SomePassword';
// 进度更新节流时间,避免频繁刷新控制台
const PROGRESS_UPDATE_INTERVAL = 500;

// 1. 获取源文件总大小
const { size: totalSize } = fs.statSync(SOURCE_FILE);
let processedSize = 0;
let lastUpdateTime = Date.now();

// 2. 生成加密所需参数
const initVect = crypto.randomBytes(16);
const hashedPassword = crypto.createHash('sha256').update(PASSWORD).digest();
const cipher = crypto.createCipheriv('aes-256-cbc', hashedPassword, initVect);

// 3. 创建读写流和压缩流
const fread = fs.createReadStream(SOURCE_FILE);
const fwrite = fs.createWriteStream(ENC_FILE);
const gzipStream = zlib.createGzip();

// 4. 先把IV写入加密文件开头(解密时需要先读取前16字节获取IV)
fwrite.write(initVect);

// 5. 监听可读流的data事件统计已处理大小,计算进度
fread.on('data', (chunk) => {
  processedSize += chunk.length;
  // 节流更新进度,避免控制台刷新过于频繁
  if (Date.now() - lastUpdateTime > PROGRESS_UPDATE_INTERVAL) {
    const progress = ((processedSize / totalSize) * 100).toFixed(2);
    // 用\r回到行首实现单行进度刷新,不会产生多行日志
    process.stdout.write(`\r加密进度: ${progress}% | 已处理: ${(processedSize / 1024 / 1024).toFixed(2)}MB / ${(totalSize / 1024 / 1024).toFixed(2)}MB`);
    lastUpdateTime = Date.now();
  }
});

// 6. 流处理完成回调
fwrite.on('finish', () => {
  // 最后输出100%进度,换行
  process.stdout.write(`\r加密进度: 100.00% | 已处理: ${(totalSize / 1024 / 1024).toFixed(2)}MB / ${(totalSize / 1024 / 1024).toFixed(2)}MB\n`);
  console.log('加密完成,IV已存储到加密文件开头');
});

// 7. 错误监听
fread.on('error', (err) => console.error('读取源文件失败:', err));
fwrite.on('error', (err) => console.error('写入加密文件失败:', err));
cipher.on('error', (err) => console.error('加密失败:', err));

// 启动流管道
fread.pipe(gzipStream).pipe(cipher).pipe(fwrite);

注意事项

  • 解密时需要先从加密文件读取前16个字节作为IV,剩下的内容才是加密后的压缩数据,按解密 -> 解压的顺序处理即可还原原文件
  • 如果你不需要单行刷新进度,把process.stdout.write里的\r去掉换成console.log即可,会逐行输出进度
  • 进度计算用的是源文件的已读取大小,和压缩、加密后的大小无关,进度统计准确,不会受压缩率影响

内容的提问来源于stack exchange,提问作者masamune756

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:36:06