hash.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /** 公共方法类 */
  2. import CryptoJs from 'crypto-js'
  3. import encHex from 'crypto-js/enc-hex'
  4. export function hashBlob(blob) {
  5. /**
  6. * 使用指定的算法计算hash值
  7. */
  8. function hashFileInternal(blob, alog) {
  9. let promise = Promise.resolve()
  10. promise = promise.then(() => hashBlob(blob))
  11. /**
  12. * 更新文件块的hash值
  13. */
  14. function hashBlob(blob) {
  15. return new Promise((resolve, reject) => {
  16. const reader = new FileReader()
  17. reader.onload = ({ target }) => {
  18. const wordArray = CryptoJs.lib.WordArray.create(target.result)
  19. // 增量更新计算结果
  20. alog.update(wordArray)
  21. resolve()
  22. }
  23. reader.readAsArrayBuffer(blob)
  24. })
  25. }
  26. // 使用promise返回最终的计算结果
  27. return promise.then(() => encHex.stringify(alog.finalize()))
  28. }
  29. // 同时计算文件的sha256和md5,并使用promise返回
  30. return Promise.all([hashFileInternal(blob, CryptoJs.algo.SHA256.create()),
  31. hashFileInternal(blob, CryptoJs.algo.MD5.create())])
  32. .then(([sha256sum, md5sum]) => ({
  33. sha256sum,
  34. md5sum
  35. }))
  36. }
  37. export function hashFile(file) {
  38. /**
  39. * 使用指定的算法计算hash值
  40. */
  41. function hashFileInternal(file, alog) {
  42. // 指定块的大小,这里设置为20MB,可以根据实际情况进行配置
  43. const chunkSize = 20 * 1024 * 1024
  44. let promise = Promise.resolve()
  45. // 使用promise来串联hash计算的顺序。因为FileReader是在事件中处理文件内容的,必须要通过某种机制来保证update的顺序是文件正确的顺序
  46. for (let index = 0; index < file.size; index += chunkSize) {
  47. promise = promise.then(() => hashBlob(file.slice(index, index + chunkSize)))
  48. }
  49. /**
  50. * 更新文件块的hash值
  51. */
  52. function hashBlob(blob) {
  53. return new Promise((resolve, reject) => {
  54. const reader = new FileReader()
  55. reader.onload = ({ target }) => {
  56. const wordArray = CryptoJs.lib.WordArray.create(target.result)
  57. // 增量更新计算结果
  58. alog.update(wordArray)
  59. resolve()
  60. }
  61. reader.readAsArrayBuffer(blob)
  62. })
  63. }
  64. // 使用promise返回最终的计算结果
  65. return promise.then(() => encHex.stringify(alog.finalize()))
  66. }
  67. // 同时计算文件的sha256和md5,并使用promise返回
  68. return Promise.all([hashFileInternal(file, CryptoJs.algo.SHA256.create()),
  69. hashFileInternal(file, CryptoJs.algo.MD5.create())])
  70. .then(([sha256sum, md5sum]) => ({
  71. sha256sum,
  72. md5sum
  73. }))
  74. }