[javascript] 자바 스크립트를 사용하여 파일의 md5 해시를 계산하는 방법

Javascript를 사용하여 서버에 업로드하기 전에 파일의 MD5 해시를 계산하는 방법이 있습니까?



답변

MD5 알고리즘의 JS 구현 이 있지만 이전 브라우저는 일반적으로 로컬 파일 시스템에서 파일을 읽을 수 없습니다 .

2009 년에 썼습니다. 그렇다면 새 브라우저는 어떻습니까?

FileAPI 를 지원하는 브라우저를 사용하면 파일의 내용을 * 읽을 수 * 있습니다 . 사용자가 <input>요소 또는 드래그 앤 드롭 으로 파일 을 선택해야합니다 . 2013 년 1 월 현재 주요 브라우저가 누적되는 방식은 다음과 같습니다.


답변

대용량 파일을 효율적으로 해시하기 위해 증분 md5를 구현하는 라이브러리를 만들었습니다. 기본적으로 파일을 청크 단위로 읽고 (메모리를 낮게 유지하기 위해) 점진적으로 해시합니다. Readme에 기본적인 사용법과 예제가 있습니다.

HTML5 FileAPI가 필요하므로 확인해야합니다. 테스트 폴더에 전체 예제가 있습니다.

https://github.com/satazor/SparkMD5


답변

CryptoJSMD5 함수HTML5 FileReader API를 사용하여 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);
};

드래그 앤 드롭 영역을 보려면 CSS를 추가하는 것이 좋습니다.

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

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

끌어서 놓기 기능에 대한 자세한 내용은 여기에서 찾을 수 있습니다. File API 및 FileReader

Google Chrome 버전 32에서 샘플을 테스트했습니다.


답변

HTML5 + spark-md5Q

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>


답변

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 2009 년 4 월 20 일 14:05

대부분의 경우 쓸모가 없습니다. 클라이언트 측에서 MD5를 계산하여 서버 측에서 재 계산 된 코드와 비교하여 서로 다른 경우 업로드가 잘못되었다고 결론을 내릴 수 있습니다. 나는 손상되지 않은 파일을받는 것이 중요한 과학 데이터의 대용량 파일로 작업하는 응용 프로그램에서이를 수행해야했습니다. 제 경우는 간단했습니다. 사용자는 이미 데이터 분석 도구에서 MD5를 계산했기 때문에 텍스트 필드로 요청하면되었습니다.


답변

파일의 해시를 얻으려면 많은 옵션이 있습니다. 일반적으로 문제는 큰 파일의 해시를 가져 오는 것이 정말 느리다는 것입니다.

파일의 시작 부분이 64kb이고 끝 부분이 64kb 인 파일 해시를 가져 오는 작은 라이브러리를 만들었습니다.

라이브 예 : http://marcu87.github.com/hashme/ 및 라이브러리 : https://github.com/marcu87/hashme