In Node.js, how can I create a sha512 asynchronous hash?

var crypto = require('crypto');
var sha = crypto.createHash('sha512').update(String(s));
var result = sha.digest('hex');

What is my current code.

How to do async? I plan to do sha512 100,000 times.

+4
source share
3 answers

If you cannot find the best solutions, this trick can help you:

You can create a standalone SHA-512 generator application that receives the standard String "s", generates a hash, and writes it to standard output.

From your application, you can execute it through a module child_processand catch the response with an event handler. There is another stackoverflow thread that can come in handy in child_process:

.:)

+1

Node crypto SHA512 , createHash() , .

: https://github.com/nodejs/node/issues/678

@ronomon/crypto-async SHA512 , , - .

+1

Node.js , , , :

  • , ;
  • Node.js.

.

Node.js API cluster, , , C.

(, ) , . , -, .

node , , . , .

, :

node parhash

Intel Core i5 4670 8 DDR3.

100'000 , 1 450 , 10 350 .

1 4,5 , 10 - 3,5 .

:

parhash.js

var
    crypto = require('crypto'),
    cluster = require('cluster');

var
    STRING_COUNT = 1000000,
    STRINGS_PER_WORKER = 100000,
    WORKER_COUNT = Math.ceil(STRING_COUNT / STRINGS_PER_WORKER),
    chunks = [],
    nextChunkId = 0,
    results = [],
    startTime,
    pendingWorkers = WORKER_COUNT;

/**
 * Generates strings partitioned in WORKER_COUNT chunks.
 * Each of these chunks will later be passed to a child process to be parsed asynchronously.
 *
 * You should replace this with your working data.
 */
function generateDemoStringChunks() {
    var
        si, wi,
        chunk;

    for (wi = 0; wi < WORKER_COUNT; wi++) {
        chunk = [];
        for (si = STRINGS_PER_WORKER * wi; (si < STRINGS_PER_WORKER * (wi + 1)) && (si < STRING_COUNT); si++) {
            chunk.push(si.toString());
        }
        chunks.push(chunk);
    }
}

/**
 * After all workers finish processing, this will be executed.
 *
 * Here you should do whatever you want to process the resulting hashes.
 */
function mergeResults() {

    results.sort(function compare(a, b) {
        return a.id - b.id;
    });

    console.info('Summary:');
    results.forEach(function (result) {
        console.info('\tChunk %d: %d hashes (here is the first hash: "%s")', result.id, result.data.length, result.data[0]);
    });
}

/**
 * This will be called on the master side every time a worker finishes working.
 *
 * @param {object} worker the Worker that finished
 * @param {{id: number, data: [string]}} result the result
 */
function processWorkerResult(worker, result) {

    console.info('Worker %d finished computing %d hashes.', worker.id, result.data.length);
    results.push(result);
    worker.kill();

    if (--pendingWorkers == 0) {
        console.info('Work is done. Whole process took %d seconds.', process.hrtime(startTime)[0]);
        mergeResults();
    }
}

/**
 * Gets a chunk of data available for processing.
 *
 * @returns {{id: number, data: [string]}} the chunk to be passed to the worker
 */
function getNextAvailableChunk() {
    var chunk = {
        id: nextChunkId,
        data: chunks[nextChunkId]
    };

    nextChunkId++;

    return chunk;
}

/**
 * The master node will send a chunk of data every time a worker node
 * signals it ready to work.
 */
function waitForWorkers() {

    cluster.on('online', function (worker) {
        console.info('Worker %d is online.', worker.id);
        worker.on('message', processWorkerResult.bind(null, worker));
        worker.send(getNextAvailableChunk());
    });
}

/**
 * Start workers.
 */
function spawnWorkers() {
    var wi;

    for (wi = 0; wi < WORKER_COUNT; wi++) {
        cluster.fork();
    }
}

/**
 * The hash function.
 *
 * @param {string} s a string to be hashed
 * @returns {string} the hash string
 */
function hashString(s) {
    return crypto.createHash('sha512').update(s).digest('hex');
}

/**
 * A worker will wait for the master to send a chunk of data and will
 * start processing as soon as it arrives.
 */
function processChunk() {
    cluster.worker.on('message', function(chunk) {
        var
            result = [];

        console.info('Worker %d received chunk %d with a load of %d strings.', cluster.worker.id, chunk.id, chunk.data.length);

        chunk.data.forEach(function processChunk(s) {
            result.push(hashString(s));
        });

        cluster.worker.send({
            id: chunk.id,
            data: result
        });
    });
}

function main() {

    if (cluster.isMaster) {

        /*
            The master node will instantiate all required workers
            and then pass a chunk of data for each one.
            It will then wait for all of them to finish so it can
            merge the results.
         */
        startTime = process.hrtime();
        generateDemoStringChunks();
        spawnWorkers();
        waitForWorkers();

    } else {

        /*
            A worker node will wait for a chunk to arrive and
            then will start processing it. When finished, it will
            send a message back to the master node with the
            resulting hashes.
         */
        console.info('Worker %d is starting.', cluster.worker.id);
        processChunk();
    }
}

main();

, , , . " WebWorker" , (: WebWorkers, t , - ).

0

All Articles