Как рассчитать хэш md5 файла с помощью javascript - PullRequest
89 голосов
/ 20 апреля 2009

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

Ответы [ 10 ]

86 голосов
/ 20 апреля 2009

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

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

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

26 голосов
/ 17 января 2012

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

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

https://github.com/satazor/SparkMD5

25 голосов
/ 30 января 2014

довольно просто вычислить хеш 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;
}

Подробнее о функциональности Drag & Drop можно найти здесь: File API & FileReader

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

7 голосов
/ 18 июля 2016

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>
7 голосов
/ 20 апреля 2011

Вам необходимо использовать 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));
     }
 }
4 голосов
/ 04 июня 2010

Помимо невозможности получить Доступ к файловой системе в JS я бы не стал доверять вообще в сгенерированная клиентом контрольная сумма. Так генерация контрольной суммы на сервере обязательно в любом случае. - Томалак 20 апреля 2009 года в 14: 05

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

3 голосов
/ 29 ноября 2012

Чтобы получить хеш файлов, существует множество опций. Обычно проблема в том, что получить хеш больших файлов очень медленно.

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

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

2 голосов
/ 20 апреля 2009

В Интернете существует пара сценариев для создания хеша MD5.

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

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

0 голосов
/ 31 июля 2011

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

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

0 голосов
/ 20 апреля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...