Skip to content

Instantly share code, notes, and snippets.

@bishil06
Created February 5, 2021 13:22
Show Gist options
  • Save bishil06/6c3a060b33f551ee9acc03188f964dcc to your computer and use it in GitHub Desktop.
Save bishil06/6c3a060b33f551ee9acc03188f964dcc to your computer and use it in GitHub Desktop.
Node.JS create md5 hash from file
const crypto = require('crypto');
function createMD5(filePath) {
return new Promise((res, rej) => {
const hash = crypto.createHash('md5');
const rStream = fs.createReadStream(filePath);
rStream.on('data', (data) => {
hash.update(data);
});
rStream.on('end', () => {
res(hash.digest('hex'));
});
})
}
@account0123
Copy link

Thanks for sharing

@weroro-sk
Copy link

weroro-sk commented Jan 29, 2025

Improved version.

import fs from "node:fs";
import crypto from "crypto";

/**
 * Computes the MD5 hash of a file specified by its path.
 *
 * This function reads the file in chunks and updates the MD5 hash incrementally.
 * It throws an error if the file does not exist, if the provided path is a directory, or if the file is not readable.
 *
 * @param {fs.PathLike} filePath - The path to the file for which to compute the MD5 hash. This can be a string or a Buffer.
 * @returns {Promise<string>} A promise that resolves to the MD5 hash of the file as a hexadecimal string.
 * @throws {Error} Throws an error if the file does not exist, if the path is a directory, or if the file is not readable.
 *
 * @example Example usage of createMD5 function
 * (async () => {
 *     try {
 *         const hash = await createMD5("path/to/file.txt");
 *         console.log(`MD5 Hash: ${hash}`);
 *     } catch (error) {
 *         console.error(error.message);
 *     }
 * })();
 */
const createMD5 = async (filePath: fs.PathLike) => {
    // Check if the file exists at the specified path
    if (!fs.existsSync(filePath))
        throw new Error(`The specified file "${filePath}" does not exist. Please check the path and try again.`);

    // Check if the specified path is a directory
    if (fs.statSync(filePath).isDirectory())
        throw new Error(`The path "${filePath}" points to a directory, not a file. Please provide a valid file path.`);

    // Check if the file is readable
    try {
        fs.accessSync(filePath, fs.constants.R_OK);
    } catch (e: any) {
        throw new Error(`The file "${filePath}" is not readable. Please check your permissions.`);
    }

    // Create an MD5 hash object
    const hash = crypto.createHash('md5');
    // Create a read stream for the file
    const rStream = fs.createReadStream(filePath);
    
    // Read the file in chunks
    let data = '';
    for await (const chunk of rStream)
        data += chunk;

    // Update the hash with data
    hash.update(data);

    // Return the final hash as a hexadecimal string
    return hash.digest('hex');
};

@milahu
Copy link

milahu commented Jul 16, 2025

data += chunk

the "improved" version fails on big files (bigger than RAM)

it wont get better than the original post

similar solutions:
https://stackoverflow.com/a/44643479/10440128
https://gist.github.com/F1LT3R/2e4347a6609c3d0105afce68cd101561
https://dev.to/saranshk/how-to-get-the-hash-of-a-file-in-nodejs-1bdk

one more!

import { createReadStream } from 'node:fs'
import crypto from 'crypto'
function md5sum(path) {
  // const md5 = await md5sum(path)
  // https://stackoverflow.com/a/44643479/10440128
  return new Promise((resolve, reject) => {
    const hash = crypto.createHash('md5')
    const stream = createReadStream(path)
    stream.on('error', err => reject(err))
    stream.on('data', chunk => hash.update(chunk))
    stream.on('end', () => resolve(hash.digest('hex')))
  })
}
async function main() {
  const path = process.argv[2]
  const md5 = await md5sum(path)
  console.log(md5, path)
}
main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment