Как вычислить md5 хэш файла с помощью javascript



есть ли способ вычислить MD5 хэш файла перед загрузкой на сервер с помощью Javascript?

764   11  

11 ответов:

хотя есть реализации JS алгоритма MD5, старые браузеры обычно не могут читать файлы из локальной файловой системы.

Я написал это в 2009 году. Так что насчет новых браузеров?

с браузером, который поддерживает FileAPI, вы * можете * прочитать содержимое файла - пользователь должен был выбрать его, либо с <input> элемент и перетащите. По состоянию на январь 2013 года, вот как майор браузеры складываются:

Я создал библиотеку, которая реализует инкрементный md5 для эффективного хэширования больших файлов. В основном Вы читаете файл в кусках (чтобы сохранить память низкой) и хешировать его постепенно. Вы получили основное использование и примеры в readme.

имейте в виду, что вам нужен HTML5 FileAPI, поэтому не забудьте проверить его. В тестовой папке есть полный пример.

https://github.com/satazor/SparkMD5

это довольно легко вычислить MD5-хэш с помощью MD5 функция CryptoJS и HTML5 FileReader API. Следующий фрагмент кода показывает, как вы можете прочитать двоичные данные и вычислить хэш 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);
};

Я рекомендую добавить некоторые CSS, чтобы увидеть область перетаскивания:

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

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

подробнее о функции перетаскивания можно найти здесь:File API & FileReader

Я тестировал образец в Google Chrome версии 32.

вам нужно использовать FileAPI. Он доступен в последней версии FF & Chrome, но не IE9. Возьмите любую реализацию md5 JS, предложенную выше. Я пробовал это и отказался от него, потому что JS был слишком медленным (минуты на больших файлах изображений). Может вернуться к нему, если кто-то переписывает MD5 с помощью типизированных массивов.

код будет выглядеть примерно так:

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));
     }
 }

кроме невозможности получить доступ к файловой системе в JS, я бы не стал доверяй на все в контрольная сумма, сгенерированная клиентом. Так генерация контрольной суммы на сервере является обязательным в любом случае. – Tomalak 20 апреля '09 в 14:05

что в большинстве случаев бесполезно. Вы хотите, чтобы MD5 вычислялся на стороне клиента, чтобы вы могли сравнить его с кодом, пересчитанным на стороне сервера, и заключить, что загрузка пошла не так, если они отличаются. Мне нужно было сделать что в приложениях, работающих с большими файлами научных данных, где получение неповрежденных файлов были ключевыми. Мои случаи были простыми, потому что пользователи уже вычисляли MD5 из своих инструментов анализа данных, поэтому мне просто нужно было спросить их с помощью текстового поля.

HTML5 + spark-md5 и Q

предполагая, что вы используете современный браузер (который поддерживает HTML5 File API), вот как вы вычисляете MD5 Hash большого файла (он будет вычислять хэш на переменных кусках)

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>

чтобы получить хэш файлов, есть много вариантов. Обычно проблема заключается в том, что очень медленно получить хэш больших файлов.

Я создал небольшую библиотеку, которая получает хэш файлов, с 64kb начала файла и 64kb конца его.

живой пример:http://marcu87.github.com/hashme/ и библиотека:https://github.com/marcu87/hashme

в интернете есть несколько сценариев для создания хэша MD5.

один из webtoolkit хорош,http://www.webtoolkit.info/javascript-md5.html

хотя я не верю, что у него будет доступ к локальной файловой системе, поскольку этот доступ ограничен.

с текущим HTML5 должно быть возможно вычислить хэш md5 двоичного файла, но я думаю, что шаг перед этим должен был бы преобразовать banary data BlobBuilder в строку, я пытаюсь сделать этот шаг: но не был успешным.

вот код, который я пробовал: преобразование BlobBuilder в строку, в HTML5 Javascript

Я не верю, что в javascript есть способ получить доступ к содержимому загрузки файла. Поэтому вы не можете посмотреть содержимое файла, чтобы сгенерировать сумму MD5.

однако вы можете отправить файл на сервер, который затем может отправить сумму MD5 обратно или отправить содержимое файла обратно .. но это много работы и, наверное, не стоит для ваших целей.

без плагина вы не можете получить доступ к этим двоичным данным. Вы должны изучить использование инструмента загрузки на основе Flash. У меня есть коллеги, которые использовали SWFUpload, но я не знаю как получить доступ к самому содержимому файла. Возможно, вам придется изменить сам SWF, чтобы разрешить это.

Comments

    Ничего не найдено.