जावास्क्रिप्ट का उपयोग करके किसी फ़ाइल के md5 हैश की गणना कैसे करें


104

क्या जावास्क्रिप्ट का उपयोग करके सर्वर पर अपलोड करने से पहले किसी फ़ाइल के एमडी 5 हैश की गणना करने का एक तरीका है?


1
दृढ़ता से संबंधित: [कैसे चेकसम उत्पन्न करने के लिए और बहुत बड़ी फ़ाइलों के लिए जावास्क्रिप्ट में 64 बिट कन्वर्ट करने के लिए RAM बह निकला बिना? ] ( stackoverflow.com/q/51987434/514235 )
iammilind

जवाबों:


92

जबकि MD5 एल्गोरिथ्म के JS कार्यान्वयन हैं , पुराने ब्राउज़र आमतौर पर स्थानीय फ़ाइल सिस्टम से फ़ाइलों को पढ़ने में असमर्थ हैं

मैंने लिखा है कि 2009 में। तो नए ब्राउज़रों के बारे में क्या?

FileAPI का समर्थन करने वाले ब्राउज़र के साथ , आप एक फ़ाइल की सामग्री को * * * पढ़ सकते हैं - उपयोगकर्ता को इसका चयन करना होगा, या तो एक <input>तत्व या ड्रैग-एंड-ड्रॉप के साथ। जनवरी 2013 तक, यहां बताया गया है कि प्रमुख ब्राउज़र कैसे स्टैक करते हैं:


30
जेएस में फाइल सिस्टम एक्सेस प्राप्त करने की असंभवता के अलावा, मैं क्लाइंट-जनरेटेड चेकसम में बिल्कुल भी भरोसा नहीं करूंगा। इसलिए सर्वर पर चेकसम उत्पन्न करना किसी भी मामले में अनिवार्य है।
तोमलक

4
@Tomalak क्लाइंट पर भी करना अनिवार्य है यदि आप इसे अपलोड करना चाहते हैं यदि यह अलग है कि आपके पास पहले से क्या है।
जॉन

2
@ जॉन, मेरा बयान इस बात से इंकार नहीं करता है। क्लाइंट-साइड चेक सख्ती से उपयोगकर्ता की सुविधा के लिए हैं (और इस तरह अधिक या कम वैकल्पिक, यह निर्भर करता है कि आप इसे कितना सुविधाजनक बनाना चाहते हैं)। दूसरी ओर सर्वर-साइड जांच अनिवार्य है।
तोमलक

pdhome.org.uk/crypt/md5 में md5 फ़ंक्शन इनपुट के रूप में बाइनरी का समर्थन नहीं करता है? मुझे लगता है कि ब्राउज़र में अपलोड की गई छवि के लिए बाइनरी स्ट्रीम की गणना करना आवश्यक है। धन्यवाद।
जियाजिरोंग

यदि आप कर सकते हैं, तो अपने उत्तर में कुछ उदाहरण कोड जोड़ें। यह बहुत मदद करेगा।
cbdeveloper

30

मैंने एक लाइब्रेरी बनाई है जो बड़ी फ़ाइलों को कुशलतापूर्वक हैश करने के लिए वृद्धिशील md5 को लागू करती है। मूल रूप से आप चंक्स में एक फ़ाइल पढ़ते हैं (मेमोरी कम रखने के लिए) और इसे वृद्धिशील रूप से हैश करते हैं। आपको रीडमी में मूल उपयोग और उदाहरण मिले।

ध्यान रखें कि आपको HTML5 FileAPI की आवश्यकता है, इसलिए इसके लिए जाँच करना सुनिश्चित करें। परीक्षण फ़ोल्डर में एक पूर्ण उदाहरण है।

https://github.com/satazor/SparkMD5


@ बिस्वा यहाँ मेरा कार्यान्वयन है। gist.github.com/marlocorridor/3e6484ae5a646bd7c625
marlo

1
हे यह महान काम करता है! मैंने CryptoJS की कोशिश की और कभी भी किसी कारण से एक सटीक MD5 प्राप्त नहीं कर सका, यह एक आकर्षण की तरह काम करता है! Sha256 के लिए कोई योजना? @ संताज़ोर
1942

@ कैम, पुस्तकालय अच्छा है। हालाँकि मैंने आज इसकी कोशिश की और ऐसा लगता है कि .end()विधि के साथ एक मुद्दा है । अगर आप इस तरीके को दोबारा कहते हैं तो यह अगली बार गलत परिणाम देता है। क्योंकि आंतरिक रूप से .end()कहता है .reset()। यह एक कोडिंग आपदा है और पुस्तकालय लेखन के लिए अच्छा नहीं है।
Iammilind

पुस्तकालय के लिए धन्यवाद! एक साथ एक न्यूनतम कोड डालें
Qortex

27

CryptoJS के MD5 फ़ंक्शन और HTML5 FileReader API का उपयोग करके MD5 हैश की गणना करना बहुत आसान है । निम्न कोड स्निपेट दिखाता है कि आप बाइनरी डेटा को कैसे पढ़ सकते हैं और एमडी 5 हैश की गणना उस छवि से कर सकते हैं जिसे आपके ब्राउज़र में खींच लिया गया है:

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

ड्रैग एंड ड्रॉप की कार्यक्षमता के बारे में अधिक जानकारी यहां पाई जा सकती है: फाइल एपीआई और फाइलरीडर

मैंने Google Chrome संस्करण 32 में नमूने का परीक्षण किया।


2
समस्या यह है कि readAsBinaryString()इसे मानकीकृत नहीं किया गया है और यह इंटरनेट एक्सप्लोरर द्वारा समर्थित नहीं है। मैंने इसे एज में टेस्ट नहीं किया, लेकिन IE11 भी इसका समर्थन नहीं करता है।
स्टेन 18

@ user25163 इंटरनेट एक्सप्लोरर (और ओपेरा मिनी) केवल आधुनिक ब्राउज़र का समर्थन नहीं करते प्रतीत होते हैं readAsBinaryString(): caniuse.com/#feat=filereader - Microsoft एज इसका समर्थन करता है।
बेनी नेउगेबॉउर

MS Edge के बारे में जानकारी के लिए धन्यवाद! मैं एक कंपनी के लिए काम करता हूं। और आप जानते हैं, कि ग्राहक अक्सर पुराने सॉफ़्टवेयर का उपयोग करते हैं और उन्हें अपने सॉफ़्टवेयर को अपडेट करने के लिए आश्वस्त करना कितना कठिन है। मैं सिर्फ यह बताना चाहता था कि किसी को readAsBinaryString()इसके इस्तेमाल से सावधान रहना होगा क्योंकि यह पुराने ब्राउज़रों द्वारा समर्थित नहीं है। मुझे मिला एक विकल्प स्पार्कएमडी 5 है। यह FileReader API का भी उपयोग करता है, लेकिन विधि readAsArrayBuffer, जो IE द्वारा समर्थित है। और यह बड़ी फ़ाइलों को चंक्स में पढ़कर संभाल सकता है।
स्टैन डे

2
CryptoJS अब एक ArrayBuffer से बाइनरी / WordArray के माध्यम से परिवर्तित करने का समर्थन करता है:CryptoJS.lib.WordArray.create(arrayBuffer);
वॉरेन

@ArrenParad और उपरोक्त कोड फिर ArrayBuffer के साथ काम करने के लिए कैसे संशोधित किया जाएगा? आह, यह यहाँ पाया: stackoverflow.com/questions/28437181/…
TheStoryCoder

9

HTML5 + spark-md5औरQ

एक आधुनिक ब्राउज़र (जो एचटीएमएल 5 फ़ाइल एपीआई का समर्थन करता है) का उपयोग करके अपने को मानते हुए, यहां बताया गया है कि आप किसी बड़ी फ़ाइल के एमडी 5 हैश की गणना कैसे करते हैं (यह चर विराम पर हैश की गणना करेगा)

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

आपको FileAPI का उपयोग करने की आवश्यकता है। यह नवीनतम एफएफ और क्रोम में उपलब्ध है, लेकिन IE9 में नहीं। ऊपर सुझाए गए किसी भी md5 JS कार्यान्वयन को पकड़ो। मैंने यह कोशिश की है और इसे छोड़ दिया है क्योंकि जेएस बहुत धीमा था (बड़ी छवि फ़ाइलों पर मिनट)। यदि कोई टाइप किए गए सरणियों का उपयोग करके एमडी 5 को फिर से लिखता है, तो इसे फिर से जारी कर सकता है।

कोड कुछ इस तरह दिखेगा:

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

Webtoolkit MD5 ने बताया कि bendewey ने बहु-एमबी फ़ाइल के लिए 16s बेहतर प्रदर्शन किया: webtoolkit.info/javascript-md5.html
अलेक्जेंडर टोटिक

1
मैं यह काम पाने में कामयाब रहा हूँ और पाठ फ़ाइलों के लिए वही md5 हैश उत्पन्न कर रहा है (php: md5_file (...)) लेकिन चित्र मुझे अलग परिणाम दे रहे हैं? क्या यह बाइनरी डेटा या इसके अपलोड होने के तरीके के साथ कुछ करना है?
Castles

मुझे पूरा यकीन है कि यह कोड एक से अधिक फ़ाइलों के साथ काम नहीं करता है, क्योंकि ऑनलोड एक कॉलबैक है, readerजब तक ऑनलोड फ़ंक्शन नहीं चलता तब तक चर अंतिम फ़ाइल होगी।
डेव

CryptoJS अब एक ArrayBuffer से बाइनरी / WordArray के माध्यम से परिवर्तित करने का समर्थन करता है:CryptoJS.lib.WordArray.create(arrayBuffer);
वॉरेन

4

जेएस में फाइल सिस्टम एक्सेस प्राप्त करने की असंभवता के अलावा, मैं क्लाइंट-जनरेटेड चेकसम में बिल्कुल भी भरोसा नहीं करूंगा। इसलिए सर्वर पर चेकसम उत्पन्न करना किसी भी मामले में अनिवार्य है। - तोमलक अप्रैल 20 '09 को 14:05 बजे

जो कि ज्यादातर मामलों में बेकार है। आप चाहते हैं कि MD5 क्लाइंट की ओर से गणना की जाए, ताकि आप इसे सर्वर की ओर से पुन: कोडित कोड के साथ तुलना कर सकें और यह निष्कर्ष निकाल सकें कि अपलोड अलग हो गया है या नहीं। मुझे यह करने की आवश्यकता है कि वैज्ञानिक डेटा की बड़ी फ़ाइलों के साथ काम करने वाले अनुप्रयोगों में, जहाँ बिना सोचे-समझे फ़ाइलें प्राप्त करना महत्वपूर्ण था। मेरे मामले सरल थे, क्योंकि उपयोगकर्ताओं के पास एमडी 5 पहले से ही उनके डेटा विश्लेषण टूल से गणना की गई थी, इसलिए मुझे सिर्फ एक पाठ क्षेत्र के साथ यह पूछने की आवश्यकता थी।


3

फ़ाइलों का हैश पाने के लिए, बहुत सारे विकल्प हैं। आम तौर पर समस्या यह है कि बड़ी फ़ाइलों का हैश प्राप्त करना वास्तव में धीमा है।

मैंने थोड़ी लाइब्रेरी बनाई जो फाइलों के हैश को प्राप्त करती है, जिसमें फ़ाइल की शुरुआत के 64kb और उसके अंत के 64kb होते हैं।

लाइव उदाहरण: http://marcu87.github.com/hashme/ और पुस्तकालय: https://github.com/marcu87/hashme


2

MD5 हैश बनाने के लिए इंटरनेट पर एक युगल स्क्रिप्ट है।

वेबटूलकिट से एक अच्छा है, http://www.webtoolkit.info/javascript-md5.html

हालाँकि, मुझे विश्वास नहीं है कि स्थानीय फ़ाइल सिस्टम तक इसकी पहुँच होगी क्योंकि यह सीमित है।


1

आशा है कि आप अब तक एक अच्छा समाधान मिल गया है। यदि नहीं, तो नीचे दिया गया समाधान js-spark-md5 पर आधारित ES6 वादा कार्यान्वयन है

import SparkMD5 from 'spark-md5';

// Read in chunks of 2MB
const CHUCK_SIZE = 2097152;

/**
 * Incrementally calculate checksum of a given file based on MD5 algorithm
 */
export const checksum = (file) =>
  new Promise((resolve, reject) => {
    let currentChunk = 0;
    const chunks = Math.ceil(file.size / CHUCK_SIZE);
    const blobSlice =
      File.prototype.slice ||
      File.prototype.mozSlice ||
      File.prototype.webkitSlice;
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();

    const loadNext = () => {
      const start = currentChunk * CHUCK_SIZE;
      const end =
        start + CHUCK_SIZE >= file.size ? file.size : start + CHUCK_SIZE;

      // Selectively read the file and only store part of it in memory.
      // This allows client-side applications to process huge files without the need for huge memory
      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
    };

    fileReader.onload = e => {
      spark.append(e.target.result);
      currentChunk++;

      if (currentChunk < chunks) loadNext();
      else resolve(spark.end());
    };

    fileReader.onerror = () => {
      return reject('Calculating file checksum failed');
    };

    loadNext();
  });

1

निम्नलिखित स्निपेट एक उदाहरण दिखाता है, जो फ़ाइल को पढ़ने और हैशिंग करते समय 400 एमबी / एस के थ्रूपुट को संग्रहित कर सकता है।

यह हैश-वाशम नामक एक पुस्तकालय का उपयोग कर रहा है , जो कि WebAssembly पर आधारित है और js-only पुस्तकालयों की तुलना में हैश की तेजी से गणना करता है। 2020 तक, सभी आधुनिक ब्राउज़र WebAssembly का समर्थन करते हैं।

const chunkSize = 64 * 1024 * 1024;
const fileReader = new FileReader();
let hasher = null;

function hashChunk(chunk) {
  return new Promise((resolve, reject) => {
    fileReader.onload = async(e) => {
      const view = new Uint8Array(e.target.result);
      hasher.update(view);
      resolve();
    };

    fileReader.readAsArrayBuffer(chunk);
  });
}

const readFile = async(file) => {
  if (hasher) {
    hasher.init();
  } else {
    hasher = await hashwasm.createMD5();
  }

  const chunkNumber = Math.floor(file.size / chunkSize);

  for (let i = 0; i <= chunkNumber; i++) {
    const chunk = file.slice(
      chunkSize * i,
      Math.min(chunkSize * (i + 1), file.size)
    );
    await hashChunk(chunk);
  }

  const hash = hasher.digest();
  return Promise.resolve(hash);
};

const fileSelector = document.getElementById("file-input");
const resultElement = document.getElementById("result");

fileSelector.addEventListener("change", async(event) => {
  const file = event.target.files[0];

  resultElement.innerHTML = "Loading...";
  const start = Date.now();
  const hash = await readFile(file);
  const end = Date.now();
  const duration = end - start;
  const fileSizeMB = file.size / 1024 / 1024;
  const throughput = fileSizeMB / (duration / 1000);
  resultElement.innerHTML = `
    Hash: ${hash}<br>
    Duration: ${duration} ms<br>
    Throughput: ${throughput.toFixed(2)} MB/s
  `;
});
<script src="https://cdn.jsdelivr.net/npm/hash-wasm"></script>
<!-- defines the global `hashwasm` variable -->

<input type="file" id="file-input">
<div id="result"></div>


0

वर्तमान एचटीएमएल 5 के साथ एक बाइनरी फ़ाइल के md5 हैश की गणना करना संभव है, लेकिन मुझे लगता है कि इससे पहले का कदम बैंबरी डेटा ब्लॉबबर्स्ट को एक स्ट्रिंग में परिवर्तित करने के लिए होगा, मैं इस चरण को करने की कोशिश कर रहा हूं: लेकिन सफल नहीं रहा।

यहाँ मैं कोड की कोशिश की है: HTML5 जावास्क्रिप्ट में, एक बूँद को स्ट्रिंग के लिए परिवर्तित


-1

मैं नहीं मानता कि किसी फ़ाइल अपलोड की सामग्री तक पहुँचने के लिए जावास्क्रिप्ट में एक तरीका है। इसलिए आप MD5 योग बनाने के लिए फ़ाइल सामग्री को नहीं देख सकते हैं।

आप फ़ाइल को सर्वर पर भेज सकते हैं, जो तब एमडी 5 राशि वापस भेज सकते हैं या फ़ाइल सामग्री वापस भेज सकते हैं .. लेकिन यह बहुत काम है और शायद आपके उद्देश्यों के लिए सार्थक नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.