quake 3 | md4 checksum | test crc file | Search

This code calculates the MD4 checksum of a ZIP archive, which can be used to verify file integrity or identify specific archives. It reads the ZIP file, extracts CRC values from its entries, and then computes the checksum using the MD4 algorithm.

Run example

npm run import -- "crc checksum file"

crc checksum file

var fs = require('fs')
var path = require('path')
var StreamZip = require('node-stream-zip')
var mdfour = importer.import("md4 checksum")

async function checksumZip(file) {
    var digest = new Uint32Array(4)
    const zip = new StreamZip({
      file: file,
      storeEntries: true
    })
    var index = await new Promise(resolve => {
        var skipped = 0
        zip.on('ready', async () => {
          console.log('Entries read: ' + zip.entriesCount + ' ' + path.basename(file))
          resolve(Object.values(zip.entries()))
        })
        zip.on('error', resolve)
    })
    var contents = [0]
    var j = 1
    for(var i = 0; i < index.length; i++) {
        var entry = index[i]
        if((entry.method != 0 && entry.method != 8) || entry.size === 0)
            continue
        contents[j++] = entry.crc
    }
    var headers = new Uint8Array(Uint32Array.from(contents).buffer)
    process.stdout.write(JSON.stringify(contents))
    mdfour(digest, headers.slice(4, j * 4), j * 4 - 4)
    var unsigned = new Uint32Array(1)
    unsigned[0] = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]
    return unsigned
}

module.exports = checksumZip

What the code could have been:

const fs = require('fs');
const path = require('path');
const StreamZip = require('node-stream-zip');
const mdfour = require('md4-checksum');

/**
 * Generates a checksum for a given zip file.
 *
 * @param {string} file - The path to the zip file.
 * @returns {Promise} The unsigned checksum of the zip file's contents.
 */
async function checksumZip(file) {
    // Validate the input file path
    if (!file || typeof file!=='string') {
        throw new Error('Invalid file path');
    }

    try {
        // Initialize the checksum calculator
        const digest = new Uint32Array(4);

        // Load the zip file
        const zip = new StreamZip({
            file,
            storeEntries: true,
        });

        // Wait for the zip file to be loaded
        const entries = await new Promise((resolve, reject) => {
            let skipped = 0;
            zip.on('ready', async () => {
                // Log the number of entries read from the zip file
                console.log(`Entries read: ${zip.entriesCount} ${path.basename(file)}`);
                resolve(Object.values(zip.entries()));
            });
            zip.on('error', reject);
        });

        // Filter out non-data entries (i.e., directories)
        const contents = entries
           .filter((entry) => entry.method!== 0 && entry.method!== 8 && entry.size > 0)
           .map((entry) => entry.crc);

        // Create a buffer to store the contents data
        const contentsBuffer = new Uint8Array(contents.length * 4);
        contents.forEach((crc, index) => {
            contentsBuffer.set(new Uint8Array([crc >>> 24, crc >>> 16, crc >>> 8, crc]), index * 4);
        });

        // Calculate the MD4 checksum of the contents
        mdfour(digest, contentsBuffer.slice(4), contentsBuffer.length - 4);

        // Compute the unsigned checksum
        const unsigned = new Uint32Array(1);
        unsigned[0] = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];

        // Return the unsigned checksum
        return unsigned[0];
    } catch (error) {
        // Log the error and rethrow it
        console.error('Error generating checksum:', error);
        throw error;
    }
}

module.exports = checksumZip;

This code defines an asynchronous function checksumZip that calculates the MD4 checksum of a ZIP archive.

Here's a breakdown:

  1. Initialization:

  2. ZIP File Processing:

  3. Checksum Calculation:

  4. Output:

  5. Export:

Purpose:

This code provides a utility for calculating the MD4 checksum of a ZIP archive, which can be used for verifying file integrity or identifying specific archives.