在NodeJS中不断从stream中生成sha1哈希

我想从stream中读取数据时更新的stream不断生成SHA1哈希。

我需要但不会工作:

const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.update('abc'); console.log(hash.digest('hex')); // hash of abc hash.update('def'); console.log(hash.digest('hex')); // hash of abcdef 

这将不起作用,因为一旦调用了hash.digest(),就不能再次调用hash.update()。

每次添加块时,如何获得string的散列? 没有将整个string加载到内存中 …而不是将整个string再次写入哈希,而是重新使用已经写好的数据块加上新的数据块。

Node.js文档中的所有示例都要求stream在计算SHA1之前结束。 一旦发生这种情况,您不能再将数据写入stream中。

https://nodejs.org/api/crypto.html#crypto_class_hash

 const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.on('readable', () => { const data = hash.read(); if (data) { console.log(data.toString('hex')); // Prints: // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 } }); hash.write('some data to hash'); hash.end(); 

我想要:

 const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.on('readable', () => { const data = hash.read(); if (data) { console.log(data.toString('hex')); } }); hash.write('abc'); // generate hash of "abc" hash.write('def'); hash.end(); // generate hash of "abcdef" 

根据这个答案,你可以计算块的sha1。

SHA-1algorithm可以在stream上计算吗? 内存占用less?

所以你应该能够重新使用stream中以前的块计算,而不必重新计算整体?

来自维基百科的伪代码以512位块显示处理

https://en.wikipedia.org/wiki/SHA-1

 Note 1: All variables are unsigned 32-bit quantities and wrap modulo 232 when calculating, except for ml, the message length, which is a 64-bit quantity, and hh, the message digest, which is a 160-bit quantity. Note 2: All constants in this pseudo code are in big endian. Within each word, the most significant byte is stored in the leftmost byte position Initialize variables: h0 = 0x67452301 h1 = 0xEFCDAB89 h2 = 0x98BADCFE h3 = 0x10325476 h4 = 0xC3D2E1F0 ml = message length in bits (always a multiple of the number of bits in a character). Pre-processing: append the bit '1' to the message eg by adding 0x80 if message length is a multiple of 8 bits. append 0 ≤ k < 512 bits '0', such that the resulting message length in bits is congruent to −64 ≡ 448 (mod 512) append ml, the original message length, as a 64-bit big-endian integer. Thus, the total length is a multiple of 512 bits. Process the message in successive 512-bit chunks: break message into 512-bit chunks for each chunk break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 Extend the sixteen 32-bit words into eighty 32-bit words: for i from 16 to 79 w[i] = (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1 Initialize hash value for this chunk: a = h0 b = h1 c = h2 d = h3 e = h4 Main loop:[3][54] for i from 0 to 79 if 0 ≤ i ≤ 19 then f = (b and c) or ((not b) and d) k = 0x5A827999 else if 20 ≤ i ≤ 39 f = b xor c xor d k = 0x6ED9EBA1 else if 40 ≤ i ≤ 59 f = (b and c) or (b and d) or (c and d) k = 0x8F1BBCDC else if 60 ≤ i ≤ 79 f = b xor c xor d k = 0xCA62C1D6 temp = (a leftrotate 5) + f + e + k + w[i] e = d d = c c = b leftrotate 30 b = a a = temp Add this chunk's hash to result so far: h0 = h0 + a h1 = h1 + b h2 = h2 + c h3 = h3 + d h4 = h4 + e Produce the final hash value (big-endian) as a 160-bit number: hh = (h0 leftshift 128) or (h1 leftshift 96) or (h2 leftshift 64) or (h3 leftshift 32) or h4