如何使用javascript计算文件的md5哈希?

时间:2022-10-28 18:24:47

Is there a way to calculate the MD5 hash of a file before the upload to the server using Javascript?

在使用Javascript上传到服务器之前,是否有方法计算文件的MD5哈希?

13 个解决方案

#1


82  

While there are JS implementations of the MD5 algorithm, older browsers are generally unable to read files from the local filesystem.

虽然MD5算法有JS实现,但老的浏览器一般无法从本地文件系统读取文件。

I wrote that in 2009. So what about new browsers?

我是在2009年写的。那么新的浏览器呢?

With a browser that supports the FileAPI, you *can * read the contents of a file - the user has to have selected it, either with an <input> element or drag-and-drop. As of Jan 2013, here's how the major browsers stack up:

使用支持FileAPI的浏览器,您可以*读取文件的内容——用户必须选择它,或者使用 <输入> 元素或拖放。截至2013年1月,主要的浏览器是这样的:

#2


23  

I've made a library that implements incremental md5 in order to hash large files efficiently. Basically you read a file in chunks (to keep memory low) and hash it incrementally. You got basic usage and examples in the readme.

我已经创建了一个实现增量md5的库,以便有效地处理大型文件。基本上,您会以块读取一个文件(以保持内存低)并以增量的方式散列。在readme中有一些基本的用法和例子。

Be aware that you need HTML5 FileAPI, so be sure to check for it. There is a full example in the test folder.

请注意,您需要HTML5 FileAPI,所以一定要检查它。在测试文件夹中有一个完整的示例。

https://github.com/satazor/SparkMD5

https://github.com/satazor/SparkMD5

#3


19  

it is pretty easy to calculate the MD5 hash using the MD5 function of CryptoJS and the HTML5 FileReader API. The following code snippet shows how you can read the binary data and calculate the MD5 hash from an image that has been dragged into your Browser:

使用CryptoJS和HTML5 FileReader API的MD5函数计算MD5哈希是相当容易的。下面的代码片段展示了如何读取二进制数据,并从拖进浏览器的图像中计算MD5散列:

var holder = document.getElementById('holder');

holder.ondragover = function() {
  return false;
};

holder.ondragend = function() {
  return false;
};

holder.ondrop = function(event) {
  event.preventDefault();

  var file = event.dataTransfer.files[0];
  var reader = new FileReader();

  reader.onload = function(event) {
    var binary = event.target.result;
    var md5 = CryptoJS.MD5(binary).toString();
    console.log(md5);
  };

  reader.readAsBinaryString(file);
};

I recommend to add some CSS to see the Drag & Drop area:

我建议添加一些CSS来查看拖放区域:

#holder {
  border: 10px dashed #ccc;
  width: 300px;
  height: 300px;
}

#holder.hover {
  border: 10px dashed #333;
}

More about the Drag & Drop functionality can be found here: File API & FileReader

关于拖放功能的更多信息可以在这里找到:File API和FileReader。

I tested the sample in Google Chrome Version 32.

我在谷歌chrome32中测试了样品。

#4


6  

You need to to use FileAPI. It is available in the latest FF & Chrome, but not IE9. Grab any md5 JS implementation suggested above. I've tried this and abandoned it because JS was too slow (minutes on large image files). Might revisit it if someone rewrites MD5 using typed arrays.

您需要使用FileAPI。它可以在最新的FF和Chrome中使用,但不是IE9。获取上面建议的任何md5 JS实现。我已经尝试过了,因为JS太慢(在大型图像文件上的时间太长)。如果有人使用类型化数组重写MD5,可能会重新考虑它。

Code would look something like this:

代码看起来是这样的:

HTML:     
<input type="file" id="file-dialog" multiple="true" accept="image/*">

JS (w JQuery)

$("#file-dialog").change(function() {
  handleFiles(this.files);
});

function handleFiles(files) {
    for (var i=0; i<files.length; i++) {
        var reader = new FileReader();
        reader.onload = function() {
        var md5 = binl_md5(reader.result, reader.result.length);
            console.log("MD5 is " + md5);
        };
        reader.onerror = function() {
            console.error("Could not read the file");
        };
        reader.readAsBinaryString(files.item(i));
     }
 }

#5


3  

Apart from the impossibility to get file system access in JS, I would not put any trust at all in a client-generated checksum. So generating the checksum on the server is mandatory in any case. – Tomalak Apr 20 '09 at 14:05

除了在JS中获取文件系统访问的不可能性之外,我不会对客户机生成的校验和完全信任。因此,在任何情况下,都必须在服务器上生成校验和。- Tomalak apr20 '09在14:05。

Which is useless in most cases. You want the MD5 computed at client side, so that you can compare it with the code recomputed at server side and conclude the upload went wrong if they differ. I have needed to do that in applications working with large files of scientific data, where receiving uncorrupted files were key. My cases was simple, cause users had the MD5 already computed from their data analysis tools, so I just needed to ask it to them with a text field.

这在大多数情况下是没用的。您需要在客户端计算MD5,这样您就可以将它与服务器端重新计算的代码进行比较,并得出结论,如果它们不同,上传就会出错。在使用大量科学数据的应用程序中,我需要这样做,在那里接收未被损坏的文件是关键。我的例子很简单,因为用户已经从他们的数据分析工具中计算出MD5,所以我只需要向他们提出一个文本字段。

#6


3  

To get the hash of files, there are a lot of options. Normally the problem is that it's really slow to get the hash of big files.

要获取文件的散列,有很多选项。通常的问题是,获取大文件的散列速度很慢。

I created a little library that get the hash of files, with the 64kb of the start of the file and the 64kb of the end of it.

我创建了一个小库,它获取文件的散列,文件的开头是64kb,最后是64kb。

Live example: http://marcu87.github.com/hashme/ and library: https://github.com/marcu87/hashme

Live example: http://marcu87.github.com/hashme/和library: https://github.com/marcu87/hashme。

#7


3  

HTML5 + spark-md5 and Q

Assuming your'e using a modern browser (that supports HTML5 File API), here's how you calculate the MD5 Hash of a large file (it will calculate the hash on variable chunks)

假设您使用的是一个现代浏览器(支持HTML5文件API),下面是您如何计算一个大文件的MD5哈希(它将计算变量块的哈希值)

function calculateMD5Hash(file, bufferSize) {
  var def = Q.defer();

  var fileReader = new FileReader();
  var fileSlicer = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
  var hashAlgorithm = new SparkMD5();
  var totalParts = Math.ceil(file.size / bufferSize);
  var currentPart = 0;
  var startTime = new Date().getTime();

  fileReader.onload = function(e) {
    currentPart += 1;

    def.notify({
      currentPart: currentPart,
      totalParts: totalParts
    });

    var buffer = e.target.result;
    hashAlgorithm.appendBinary(buffer);

    if (currentPart < totalParts) {
      processNextPart();
      return;
    }

    def.resolve({
      hashResult: hashAlgorithm.end(),
      duration: new Date().getTime() - startTime
    });
  };

  fileReader.onerror = function(e) {
    def.reject(e);
  };

  function processNextPart() {
    var start = currentPart * bufferSize;
    var end = Math.min(start + bufferSize, file.size);
    fileReader.readAsBinaryString(fileSlicer.call(file, start, end));
  }

  processNextPart();
  return def.promise;
}

function calculate() {

  var input = document.getElementById('file');
  if (!input.files.length) {
    return;
  }

  var file = input.files[0];
  var bufferSize = Math.pow(1024, 2) * 10; // 10MB

  calculateMD5Hash(file, bufferSize).then(
    function(result) {
      // Success
      console.log(result);
    },
    function(err) {
      // There was an error,
    },
    function(progress) {
      // We get notified of the progress as it is executed
      console.log(progress.currentPart, 'of', progress.totalParts, 'Total bytes:', progress.currentPart * bufferSize, 'of', progress.totalParts * bufferSize);
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/2.0.2/spark-md5.min.js"></script>

<div>
  <input type="file" id="file"/>
  <input type="button" onclick="calculate();" value="Calculate" class="btn primary" />
</div>

#8


2  

There is a couple scripts out there on the internet to create an MD5 Hash.

在internet上有一些脚本可以创建MD5散列。

The one from webtoolkit is good, http://www.webtoolkit.info/javascript-md5.html

来自webtoolkit的一个很好,http://www.webtoolkit.info/javascript-md5.html。

Although, I don't believe it will have access to the local filesystem as that access is limited.

尽管如此,我认为它不会访问本地文件系统,因为访问是有限的。

#9


0  

With current HTML5 it should be possible to calculate the md5 hash of a binary file, But I think the step before that would be to convert the banary data BlobBuilder to a String, I am trying to do this step: but have not been successful.

使用当前的HTML5,应该可以计算二进制文件的md5哈希,但我认为之前的步骤是将banary数据BlobBuilder转换为字符串,我正在尝试做这一步:但是没有成功。

Here is the code I tried: Converting a BlobBuilder to string, in HTML5 Javascript

下面是我尝试过的代码:在HTML5 Javascript中将BlobBuilder转换为字符串。

#10


-1  

I don't believe there is a way in javascript to access the contents of a file upload. So you therefore cannot look at the file contents to generate an MD5 sum.

我不认为javascript中有一种方法可以访问文件上传的内容。因此,您不能查看文件内容来生成MD5和。

You can however send the file to the server, which can then send an MD5 sum back or send the file contents back .. but that's a lot of work and probably not worthwhile for your purposes.

但是,您可以将文件发送到服务器,然后可以发送MD5和返回或将文件内容发送回来。但那是很多工作,可能不值得你做。

#11


-1  

Well its possible to read files with HTML5 File API (see the Blob interface). Not tested but you could do it maybe.

可以使用HTML5文件API读取文件(参见Blob接口)。没有经过测试,但你可以这么做。

#12


-1  

Also, you should never trust the client. You'll just have to redo the hash once it's uploaded.

而且,你永远不应该信任客户。你只需要在上传之后重做哈希。

#13


-3  

Without a plugin you can't access that binary data. You should look into using a Flash-based upload tool. I have colleagues who have used SWFUpload, but I don't know how to get access to the file content itself. You might have to alter the SWF itself to allow this.

没有插件,你无法访问二进制数据。你应该使用基于flash的上传工具。我有同事使用过SWFUpload,但我不知道如何访问文件内容本身。你可能需要改变SWF来允许这个。

#1


82  

While there are JS implementations of the MD5 algorithm, older browsers are generally unable to read files from the local filesystem.

虽然MD5算法有JS实现,但老的浏览器一般无法从本地文件系统读取文件。

I wrote that in 2009. So what about new browsers?

我是在2009年写的。那么新的浏览器呢?

With a browser that supports the FileAPI, you *can * read the contents of a file - the user has to have selected it, either with an <input> element or drag-and-drop. As of Jan 2013, here's how the major browsers stack up:

使用支持FileAPI的浏览器,您可以*读取文件的内容——用户必须选择它,或者使用 <输入> 元素或拖放。截至2013年1月,主要的浏览器是这样的:

#2


23  

I've made a library that implements incremental md5 in order to hash large files efficiently. Basically you read a file in chunks (to keep memory low) and hash it incrementally. You got basic usage and examples in the readme.

我已经创建了一个实现增量md5的库,以便有效地处理大型文件。基本上,您会以块读取一个文件(以保持内存低)并以增量的方式散列。在readme中有一些基本的用法和例子。

Be aware that you need HTML5 FileAPI, so be sure to check for it. There is a full example in the test folder.

请注意,您需要HTML5 FileAPI,所以一定要检查它。在测试文件夹中有一个完整的示例。

https://github.com/satazor/SparkMD5

https://github.com/satazor/SparkMD5

#3


19  

it is pretty easy to calculate the MD5 hash using the MD5 function of CryptoJS and the HTML5 FileReader API. The following code snippet shows how you can read the binary data and calculate the MD5 hash from an image that has been dragged into your Browser:

使用CryptoJS和HTML5 FileReader API的MD5函数计算MD5哈希是相当容易的。下面的代码片段展示了如何读取二进制数据,并从拖进浏览器的图像中计算MD5散列:

var holder = document.getElementById('holder');

holder.ondragover = function() {
  return false;
};

holder.ondragend = function() {
  return false;
};

holder.ondrop = function(event) {
  event.preventDefault();

  var file = event.dataTransfer.files[0];
  var reader = new FileReader();

  reader.onload = function(event) {
    var binary = event.target.result;
    var md5 = CryptoJS.MD5(binary).toString();
    console.log(md5);
  };

  reader.readAsBinaryString(file);
};

I recommend to add some CSS to see the Drag & Drop area:

我建议添加一些CSS来查看拖放区域:

#holder {
  border: 10px dashed #ccc;
  width: 300px;
  height: 300px;
}

#holder.hover {
  border: 10px dashed #333;
}

More about the Drag & Drop functionality can be found here: File API & FileReader

关于拖放功能的更多信息可以在这里找到:File API和FileReader。

I tested the sample in Google Chrome Version 32.

我在谷歌chrome32中测试了样品。

#4


6  

You need to to use FileAPI. It is available in the latest FF & Chrome, but not IE9. Grab any md5 JS implementation suggested above. I've tried this and abandoned it because JS was too slow (minutes on large image files). Might revisit it if someone rewrites MD5 using typed arrays.

您需要使用FileAPI。它可以在最新的FF和Chrome中使用,但不是IE9。获取上面建议的任何md5 JS实现。我已经尝试过了,因为JS太慢(在大型图像文件上的时间太长)。如果有人使用类型化数组重写MD5,可能会重新考虑它。

Code would look something like this:

代码看起来是这样的:

HTML:     
<input type="file" id="file-dialog" multiple="true" accept="image/*">

JS (w JQuery)

$("#file-dialog").change(function() {
  handleFiles(this.files);
});

function handleFiles(files) {
    for (var i=0; i<files.length; i++) {
        var reader = new FileReader();
        reader.onload = function() {
        var md5 = binl_md5(reader.result, reader.result.length);
            console.log("MD5 is " + md5);
        };
        reader.onerror = function() {
            console.error("Could not read the file");
        };
        reader.readAsBinaryString(files.item(i));
     }
 }

#5


3  

Apart from the impossibility to get file system access in JS, I would not put any trust at all in a client-generated checksum. So generating the checksum on the server is mandatory in any case. – Tomalak Apr 20 '09 at 14:05

除了在JS中获取文件系统访问的不可能性之外,我不会对客户机生成的校验和完全信任。因此,在任何情况下,都必须在服务器上生成校验和。- Tomalak apr20 '09在14:05。

Which is useless in most cases. You want the MD5 computed at client side, so that you can compare it with the code recomputed at server side and conclude the upload went wrong if they differ. I have needed to do that in applications working with large files of scientific data, where receiving uncorrupted files were key. My cases was simple, cause users had the MD5 already computed from their data analysis tools, so I just needed to ask it to them with a text field.

这在大多数情况下是没用的。您需要在客户端计算MD5,这样您就可以将它与服务器端重新计算的代码进行比较,并得出结论,如果它们不同,上传就会出错。在使用大量科学数据的应用程序中,我需要这样做,在那里接收未被损坏的文件是关键。我的例子很简单,因为用户已经从他们的数据分析工具中计算出MD5,所以我只需要向他们提出一个文本字段。

#6


3  

To get the hash of files, there are a lot of options. Normally the problem is that it's really slow to get the hash of big files.

要获取文件的散列,有很多选项。通常的问题是,获取大文件的散列速度很慢。

I created a little library that get the hash of files, with the 64kb of the start of the file and the 64kb of the end of it.

我创建了一个小库,它获取文件的散列,文件的开头是64kb,最后是64kb。

Live example: http://marcu87.github.com/hashme/ and library: https://github.com/marcu87/hashme

Live example: http://marcu87.github.com/hashme/和library: https://github.com/marcu87/hashme。

#7


3  

HTML5 + spark-md5 and Q

Assuming your'e using a modern browser (that supports HTML5 File API), here's how you calculate the MD5 Hash of a large file (it will calculate the hash on variable chunks)

假设您使用的是一个现代浏览器(支持HTML5文件API),下面是您如何计算一个大文件的MD5哈希(它将计算变量块的哈希值)

function calculateMD5Hash(file, bufferSize) {
  var def = Q.defer();

  var fileReader = new FileReader();
  var fileSlicer = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
  var hashAlgorithm = new SparkMD5();
  var totalParts = Math.ceil(file.size / bufferSize);
  var currentPart = 0;
  var startTime = new Date().getTime();

  fileReader.onload = function(e) {
    currentPart += 1;

    def.notify({
      currentPart: currentPart,
      totalParts: totalParts
    });

    var buffer = e.target.result;
    hashAlgorithm.appendBinary(buffer);

    if (currentPart < totalParts) {
      processNextPart();
      return;
    }

    def.resolve({
      hashResult: hashAlgorithm.end(),
      duration: new Date().getTime() - startTime
    });
  };

  fileReader.onerror = function(e) {
    def.reject(e);
  };

  function processNextPart() {
    var start = currentPart * bufferSize;
    var end = Math.min(start + bufferSize, file.size);
    fileReader.readAsBinaryString(fileSlicer.call(file, start, end));
  }

  processNextPart();
  return def.promise;
}

function calculate() {

  var input = document.getElementById('file');
  if (!input.files.length) {
    return;
  }

  var file = input.files[0];
  var bufferSize = Math.pow(1024, 2) * 10; // 10MB

  calculateMD5Hash(file, bufferSize).then(
    function(result) {
      // Success
      console.log(result);
    },
    function(err) {
      // There was an error,
    },
    function(progress) {
      // We get notified of the progress as it is executed
      console.log(progress.currentPart, 'of', progress.totalParts, 'Total bytes:', progress.currentPart * bufferSize, 'of', progress.totalParts * bufferSize);
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/2.0.2/spark-md5.min.js"></script>

<div>
  <input type="file" id="file"/>
  <input type="button" onclick="calculate();" value="Calculate" class="btn primary" />
</div>

#8


2  

There is a couple scripts out there on the internet to create an MD5 Hash.

在internet上有一些脚本可以创建MD5散列。

The one from webtoolkit is good, http://www.webtoolkit.info/javascript-md5.html

来自webtoolkit的一个很好,http://www.webtoolkit.info/javascript-md5.html。

Although, I don't believe it will have access to the local filesystem as that access is limited.

尽管如此,我认为它不会访问本地文件系统,因为访问是有限的。

#9


0  

With current HTML5 it should be possible to calculate the md5 hash of a binary file, But I think the step before that would be to convert the banary data BlobBuilder to a String, I am trying to do this step: but have not been successful.

使用当前的HTML5,应该可以计算二进制文件的md5哈希,但我认为之前的步骤是将banary数据BlobBuilder转换为字符串,我正在尝试做这一步:但是没有成功。

Here is the code I tried: Converting a BlobBuilder to string, in HTML5 Javascript

下面是我尝试过的代码:在HTML5 Javascript中将BlobBuilder转换为字符串。

#10


-1  

I don't believe there is a way in javascript to access the contents of a file upload. So you therefore cannot look at the file contents to generate an MD5 sum.

我不认为javascript中有一种方法可以访问文件上传的内容。因此,您不能查看文件内容来生成MD5和。

You can however send the file to the server, which can then send an MD5 sum back or send the file contents back .. but that's a lot of work and probably not worthwhile for your purposes.

但是,您可以将文件发送到服务器,然后可以发送MD5和返回或将文件内容发送回来。但那是很多工作,可能不值得你做。

#11


-1  

Well its possible to read files with HTML5 File API (see the Blob interface). Not tested but you could do it maybe.

可以使用HTML5文件API读取文件(参见Blob接口)。没有经过测试,但你可以这么做。

#12


-1  

Also, you should never trust the client. You'll just have to redo the hash once it's uploaded.

而且,你永远不应该信任客户。你只需要在上传之后重做哈希。

#13


-3  

Without a plugin you can't access that binary data. You should look into using a Flash-based upload tool. I have colleagues who have used SWFUpload, but I don't know how to get access to the file content itself. You might have to alter the SWF itself to allow this.

没有插件,你无法访问二进制数据。你应该使用基于flash的上传工具。我有同事使用过SWFUpload,但我不知道如何访问文件内容本身。你可能需要改变SWF来允许这个。