I'm using nodejs built-in crypto, zlib and fs package to encrypt a large file using these codes.
import fs from 'fs';
import zlib from 'zlib';
import crypto from 'crypto';
const initVect = crypto.randomBytes(16);
const fread = fs.createReadStream('X:/File.mp4');
const fwrite = fs.createWriteStream('X:/File.mp4.enc');
const gzipStream = zlib.createGzip();
const hashedPassword = crypto.createHash('sha256').update('SomePassword').digest();
const cipher = crypto.createCipheriv(
'aes-256-cbc',
hashedPassword,
initVect
);
fread.pipe(gzipStream).pipe(cipher).pipe(fwrite);
But I don't know how to add an encryption progress/status indicator, since a large file will take a lot of time to encrypt I want to show encryption progress to the user in the console.
Can you guys tell me how to achieve this?
CodePudding user response:
You can achieve this using stream Transform()
. Create a new stream Transform()
, get the processed chunk length in it, then simply calculate progress with chunk length and file size, then add this new transform to your existing pipe.
Like this:-
import fs from 'fs';
import zlib from 'zlib';
import crypto from 'crypto';
import { TransformCallback, Transform } from 'stream';
const initVect = crypto.randomBytes(16);
const fread = fs.createReadStream('X:/File.mp4');
const fwrite = fs.createWriteStream('X:/File.mp4.enc');
const gzipStream = zlib.createGzip();
const hashedPassword = crypto.createHash('sha256').update('SomePassword').digest();
const cipher = crypto.createCipheriv(
'aes-256-cbc',
hashedPassword,
initVect
);
const fileSize = fs.statSync(fread.path).size;
let processedBytes = 0;
const progressPipe = new Transform({
transform(
chunk: Buffer,
_encoding: BufferEncoding,
callback: TransformCallback
) {
processedBytes = chunk.length;
console.log(
`${Math.floor((processedBytes / fileSize) * 100)}%`
);
this.push(chunk);
callback();
},
});
fread.pipe(progressPipe).pipe(gzipStream).pipe(cipher).pipe(fwrite);