使用JS Crypto库计算大型文件MD5时,浏览器会冻结(OOM?)

时间:2017-08-15 08:07:19

标签: javascript hash

我正在使用Webpack,编译捆绑的JS文件。

问题

我有一个工人,我正在卸载哈希工作。我传递一个文件并将其归档到它。我之前没有使用过工人。但是,当Chrome对散列大文件反应不佳时,我认为主线程被散列机制阻止了。这可能是一个错误的假设。

该代码适用于小文件。但是,对于大型文件,一旦到达生成最终哈希的部分,Chrome就会显示以下错误:

Chrome error message

Firefox更有帮助,并显示以下消息:

  

错误:未捕获,未指定的“错误”事件。 (内存不足)

但是,数据管道应该可以缓解这个问题。 fileReaderStream以1 MB的块读取数据。

代码

import Crypto from 'crypto'
import fileReaderStream from 'filereader-stream'
import concat from 'concat-stream'
var progress = require('progress-stream');

self.onmessage = (event) => {
    switch (event.data.topic) {
        case 'hash': {
            var file = event.data.file;
            var filesize = event.data.filesize;

            let p1 = progress({
                length: filesize,
                time: 100 /* ms */
            });
            let p2 = progress({
                length: filesize,
                time: 100 /* ms */
            });

            p1.on('progress', function(progress) {
                console.log('p1', progress);
            });
            p2.on('progress', function(progress) {
                console.log('p2', progress);
            });

            let md5 = Crypto.createHash('md5');

            console.log("START HASH");
            var reader = fileReaderStream(file);
            reader.pipe(p1).pipe(md5).pipe(p2).pipe(concat((data) => {
                console.log("DONE HASH");
                console.log(data);
            }));

            break;
        }
    }
}

小文件示例(5,248 KB)

Dev console log of uploading a small file

大文件示例(643 MB)

Dev console log of uploading a large file

其他信息

内存使用情况的屏幕截图。它在几秒钟内占用3 GB。

Memory issue chart

1 个答案:

答案 0 :(得分:0)

因此,如果在内存管理方面实施不当,可能值得使用不同的库。

这个javascript库由stanford实现 - https://bitwiseshiftleft.github.io/sjcl/

您可能还想考虑使用比md5更安全的散列算法,因为它很容易受到生日攻击的冲突。