JavaScript

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > wasm js获取md5

wasm+js实现文件获取md5示例详解

作者:大叔您好

这篇文章主要为大家介绍了wasm+js实现md5文件获取示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

在过去的几年里,wasm的话题那真是从早上聊到晚上,可以说处于异常兴奋的状态,但是几年过去了,它慢慢的被大多数人们忘记,原因比较简单——落地难

今天就wasm能给js加多少分这个问题,做一个小型的讨论,今天的专注点是,前端js获取一个文件的md5值,也就是上传文件时所需要的秒传功能的核心

简单来说,文件上传秒传不仅仅是网盘公司的专属,平时我们上传文件给后端也是很常用的,前端通过对目标文件md5计算后与后端进行对比,如果已经上传过,则直接返回已有地址,这样,大大节省了服务器空间。基本思路如下:

本文重点

今天的重点是如何快速获取一个文件的md5值,这里就涉及到小文件,大文件的问题了。所以,我将以下面文件体积为例来测试js与wasm对文件md5计算的速度对比。

wasm我使用golang进行开发,因为golang打包成wasm会把运行时也加进去,所以,打包的结果2.2M,我们暂时忽略这个体积,因为如果能落地,那么换成rust,换成c++都不是难事,如果不能落地,那么,golang不行,c++也照样不行。

准备工作

通过ffmeg 从一个2G+的文件上截取不同体积的文件,用于测试。

ffmpeg -i /path/sourch.mp4  -fs 1M -c:v copy -c:a copy /path/1M.mp4
ffmpeg -i /path/sourch.mp4  -fs 5M -c:v copy -c:a copy /path/5M.mp4
ffmpeg -i /path/sourch.mp4  -fs 20M -c:v copy -c:a copy /path/20M.mp4
ffmpeg -i /path/sourch.mp4  -fs 50M -c:v copy -c:a copy /path/50M.mp4
ffmpeg -i /path/sourch.mp4  -fs 100M -c:v copy -c:a copy /path/100M.mp4
ffmpeg -i /path/sourch.mp4  -fs 200M -c:v copy -c:a copy /path/200M.mp4
ffmpeg -i /path/sourch.mp4  -fs 400M -c:v copy -c:a copy /path/400M.mp4
ffmpeg -i /path/sourch.mp4  -fs 600M -c:v copy -c:a copy /path/500M.mp4
ffmpeg -i /path/sourch.mp4  -fs 800M -c:v copy -c:a copy /path/800M.mp4
ffmpeg -i /path/sourch.mp4  -fs 900M -c:v copy -c:a copy /path/900M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1024M -c:v copy -c:a copy /path/1024M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1280M -c:v copy -c:a copy /path/1280M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1536M -c:v copy -c:a copy /path/1536M.mp4
ffmpeg -i /path/sourch.mp4  -fs 1792M -c:v copy -c:a copy /path/1792M.mp4
ffmpeg -i /path/sourch.mp4  -fs 2048M -c:v copy -c:a copy /path/2048M.mp4

测试代码

纯js测试代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./SparkMD5.js"></script>
</head>
<body>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      const md5 = new SparkMD5();
      fileReader.readAsBinaryString(file);
      fileReader.onload = e => {
        md5.appendBinary(e.target.result);
        const md5Str = md5.end()
        usedTime += Date.now() - startTime
        console.log('usedTime', usedTime, 'ms')
        console.log('md5', md5Str)
      }
    });
  </script>
</body>
</html>

wasm(go)源码

请参考:

github.com/butoften/wa…

js+wasm测试代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./wasm_exec.js"></script>
</head>
<body>
  <script>
    function handleSayHello(message) {
      console.lof('str from go', message)
    }
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch('wasm/md5.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance);
      });
  </script>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      fileReader.readAsArrayBuffer(file);
      fileReader.onload = e => {
        const bytes = new Uint8Array(e.target.result)
        wasmMd5Add(bytes)
        const md5Hash = wasmMd5End()
        usedTime += Date.now() - startTime
        console.log('usedTime', usedTime, 'ms')
        console.log('md5', md5Hash)
      }
    });
  </script>
</body>
</html>

测试条件

测试目标

chrome (版本:103.0.5060.114)

序号纯js纯js分段js+wasmjs+wasm分段
137477 ms25638 ms31680 ms22898 ms
232926 ms28088 ms32516 ms25168 ms
333413 ms31412 ms33424 ms20547 ms
435054 ms35821 ms33906 ms23130 ms
535986 ms36895 ms29014 ms22011 ms
序号纯js纯js分段js+wasmjs+wasm分段
116298 ms19441 ms27322 ms19233 ms
211593 ms29424 ms28955 ms18602 ms
324589 ms28685 ms28192 ms18472 ms
424725 ms29892 ms28931 ms18260 ms
524695 ms31453 ms36166 ms19474 ms
序号纯js纯js分段js+wasmjs+wasm分段
119856 ms19591 ms21259 ms15920 ms
215119 ms26283 ms20821 ms15634 ms
321387 ms25861 ms22473 ms16893 ms
419550 ms25797 ms21793 ms17239 ms
520363 ms26402 ms20782 ms15786 ms
序号纯js纯js分段js+wasmjs+wasm分段
16449 ms12169 ms22856 ms16621 ms
214695 ms17558 ms19147 ms18014 ms
317792 ms20326 ms17203 ms14683 ms
418094 ms16452 ms18396 ms14399 ms
515830 ms19006 ms19241 ms14119 ms
序号纯js纯js分段js+wasmjs+wasm分段
15003 ms9441 ms16233 ms9252 ms
26240 ms14917 ms11145 ms9316 ms
38563 ms10849 ms12653 ms10963 ms
410261 ms12155 ms11607 ms9108 ms
58775 ms11138 ms9869 ms10451 ms
序号纯js纯js分段js+wasmjs+wasm分段
14632 ms7721 ms9590 ms7887 ms
25858 ms3312 ms7161 ms7963 ms
32859 ms10808 ms7646 ms7973 ms
43531 ms8614 ms7904 ms8197 ms
55744 ms7612 ms7131 ms10714 ms
序号纯js纯js分段js+wasmjs+wasm分段
13329 ms5884 ms9318 ms7270 ms
27222 ms9917 ms6897 ms7096 ms
32602 ms6066 ms6295 ms6908 ms
42757 ms6662 ms6551 ms8164 ms
52509 ms8730 ms7126 ms7039 ms
序号纯js纯js分段js+wasmjs+wasm分段
12721 ms2824 ms6557 ms5019 ms
23241 ms6867 ms4943 ms5026 ms
31803 ms3012 ms4902 ms5052 ms
41930 ms3010 ms5007 ms5022 ms
51807 ms2885 ms4881 ms5238 ms
序号纯jsjs+wasm
16406 ms3358 ms
26435 ms3599 ms
36450 ms3283 ms
46286 ms3952 ms
56408 ms3207 ms
序号纯jsjs+wasm
13497 ms1705 ms
23412 ms1643 ms
33263 ms1825 ms
43284 ms1710 ms
53376 ms1768 ms
序号纯jsjs+wasm
11873 ms923 ms
21776 ms928 ms
31772 ms913 ms
41682 ms923 ms
51742 ms898 ms
序号纯jsjs+wasm
11043 ms516 ms
2877 ms479 ms
3907 ms504 ms
4872 ms459 ms
5865 ms495 ms
序号纯jsjs+wasm
1487 ms209 ms
2387 ms209 ms
3410 ms225 ms
4512 ms268 ms
5399 ms225 ms
序号纯jsjs+wasm
1147 ms92 ms
2133 ms90 ms
3177 ms94 ms
4157 ms42 ms
5175 ms84 ms
序号纯jsjs+wasm
171 ms20 ms
266 ms24 ms
345 ms33 ms
480 ms30 ms
597 ms29 ms

firefox (版本号:103.0.1 (64 位))

序号纯js分段js+wasm分段
151398 ms17338 ms
241282 ms16385 ms
342358 ms16966 ms
443363 ms15843 ms
540802 ms16551 ms
序号纯js分段js+wasm分段
133690 ms13251 ms
237423 ms13636 ms
342903 ms13487 ms
432684 ms13662 ms
536691 ms14984 ms
序号纯js分段js+wasm分段
128051 ms11425 ms
227822 ms11337 ms
328331 ms12508 ms
430089 ms11520 ms
532890 ms11507 ms
序号纯js分段js+wasm分段
125680 ms9571 ms
223956 ms9549 ms
328829 ms10070 ms
423518 ms9449 ms
523200 ms9540 ms
序号纯jsjs+wasm
138277 ms7776 ms
240936 ms11254 ms
329861 ms7653 ms
425630 ms7517 ms
518934 ms11443 ms
624849 ms8039 ms
718214 ms7727 ms
818617 ms12987 ms
933281 ms7523 ms
1040757 ms8895 ms
序号纯jsjs+wasm
122752 ms8605 ms
216669 ms9313 ms
315716 ms6678 ms
416940 ms6521 ms
516732 ms9269 ms
615805 ms6582 ms
715718 ms6519 ms
815795 ms9377 ms
915641 ms6773 ms
1015622 ms7489 ms
序号纯jsjs+wasm
115181 ms8333 ms
214031 ms5880 ms
314214 ms5987 ms
433812 ms5935 ms
514167 ms8666 ms
614666 ms8031 ms
728640 ms5991 ms
813992 ms5840 ms
913926 ms6032 ms
1014216 ms6637 ms
序号纯jsjs+wasm
111418 ms4457 ms
211199 ms5370 ms
310717 ms4654 ms
410607 ms4436 ms
510611 ms4479 ms
610718 ms4368 ms
710560 ms5494 ms
811519 ms5044 ms
910802 ms4426 ms
1011779 ms4971 ms
序号纯jsjs+wasm
18362 ms2981 ms
27516 ms2999 ms
37335 ms3030 ms
47357 ms3150 ms
57444 ms3001 ms
68456 ms3223 ms
77376 ms3120 ms
87313 ms3072 ms
97349 ms3240 ms
107447 ms3352 ms
序号纯jsjs+wasm
14066 ms1525 ms
24440 ms1516 ms
34223 ms1510 ms
43916 ms1610 ms
53917 ms1509 ms
64028 ms1588 ms
73964 ms1514 ms
84037 ms1507 ms
93957 ms1506 ms
103987 ms1642 ms
序号纯jsjs+wasm
12280 ms761 ms
22331 ms820 ms
32193 ms798 ms
42242 ms777 ms
52197 ms752 ms
62330 ms769 ms
72236 ms758 ms
82364 ms798 ms
92278 ms783 ms
102384 ms785 ms
序号纯jsjs+wasm
11366 ms397 ms
21355 ms378 ms
31445 ms460 ms
41468 ms437 ms
51417 ms406 ms
61525 ms478 ms
71381 ms393 ms
81450 ms430 ms
91417 ms428 ms
101378 ms431 ms
序号纯jsjs+wasm
1921 ms168 ms
2871 ms162 ms
3859 ms163 ms
4864 ms162 ms
51025 ms177 ms
6910 ms158 ms
7904 ms150 ms
8931 ms187 ms
91014 ms182 ms
10871 ms159 ms
序号纯jsjs+wasm
1127 ms48 ms
2124 ms50 ms
3140 ms44 ms
4129 ms47 ms
5127 ms51 ms
6129 ms50 ms
7126 ms46 ms
8119 ms54 ms
9121 ms46 ms
10118 ms50 ms
序号纯jsjs+wasm
146 ms18 ms
241 ms22 ms
343 ms13 ms
440 ms15 ms
544 ms11 ms
647 ms15 ms
742 ms11 ms
842 ms20 ms
945 ms13 ms
1044 ms16 ms

分段计算测试代码

纯js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./SparkMD5.js"></script>
</head>
<body>
  <input id="file" type="file" />
  <script>
  document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      const md5 = new SparkMD5();
      let index = 0
      const chunkSize = 512 * 1024 * 1024;//file.size / count
      let count = Math.ceil(file.size / chunkSize)
      console.log('分几份', count)
      loadSliceFile();
      function loadSliceFile() {
        const sliceFile = file.slice(index * chunkSize, index * chunkSize + chunkSize)
        fileReader.readAsBinaryString(sliceFile);
      }
      fileReader.onload = e => {
        index += 1;
        md5.appendBinary(e.target.result);
        if (index < count) {
          loadSliceFile()
        }
        else {
          const md5Str = md5.end()
          usedTime += Date.now() - startTime
          console.log('usedTime', usedTime, 'ms')
          console.log('md5', md5Str)
        }
      }
    });
  </script>
</body>
</html>

js+wasm

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件md5</title>
  <script src="./wasm_exec.js"></script>
  <!-- <script src="./wasm_exec_tiny.js"></script> -->
</head>
<body>
  <script>
    function handleSayHello(message) {
      console.lof('str from go', message)
    }
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch('wasm/md5.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance); // 执行 golang里 main 方法
      });
  </script>
  <input id="file" type="file" />
  <script>
    document.querySelector('#file').addEventListener('change', e => {
      let startTime = Date.now()
      const file = e.target.files[0];
      const fileReader = new FileReader()
      console.log('size', file.size / 1024 / 1024 / 1024, "G")
      fileReader.onprogress = e => {
        console.log(`${Math.floor((e.loaded / e.total) * 100)}%`)
      }
      let usedTime = 0
      let index = 0
      const sliceSize = 512
      const chunkSize = sliceSize * 1024 * 1024;//file.size / count
      let count = Math.ceil(file.size / chunkSize)
      console.log('分几份', count)
      loadSliceFile();
      function loadSliceFile() {
        const sliceFile = file.slice(index * chunkSize, index * chunkSize + chunkSize)
        fileReader.readAsArrayBuffer(sliceFile);
      }
      fileReader.onload = e => {
        index += 1;
        const bytes = new Uint8Array(e.target.result)
        wasmMd5Add(bytes)
        if (index < count) {
          loadSliceFile()
        }
        else {
          const md5Hash = wasmMd5End()
          usedTime += Date.now() - startTime
          console.log('usedTime', usedTime, 'ms')
          console.log('md5', md5Hash)
        }
      }
    });
  </script>
</body>
</html>

测试结论

firefox

chrome

最终结论

wasm 还是可以使用的,众观全局,速度提升2-3倍。chrome可以针对性处理

以上就是wasm+js实现文件获取md5示例详解的详细内容,更多关于wasm js获取md5的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文