জাভাস্ক্রিপ্ট ব্যবহার করে কোনও ফাইলের এমডি 5 হ্যাশ কীভাবে গণনা করা যায়


104

জাভাস্ক্রিপ্ট ব্যবহার করে সার্ভারে আপলোড করার আগে কোনও ফাইলের MD5 হ্যাশ গণনা করার কোনও উপায় আছে কি?


1
দৃ Related়ভাবে সম্পর্কিত: [অতিপ্রবাহের র্যাম ছাড়াই খুব বড় ফাইলগুলির জন্য জাভাস্ক্রিপ্টে চেকসাম কীভাবে তৈরি করতে এবং 64 বিটে রূপান্তর করা যায়? ] ( Stackoverflow.com/q/51987434/514235 )
iammilind

উত্তর:


92

যদিও আছে জাতীয় বাস্তবায়নের MD5 আলগোরিদিম, পুরোনো ব্রাউজারে সাধারণত স্থানীয় ফাইলসিস্টেম থেকে ফাইল পড়তে অক্ষম হয়

আমি এটি ২০০৯ সালে লিখেছিলাম। সুতরাং নতুন ব্রাউজারগুলির কী হবে?

ফাইলএপিআই সমর্থন করে এমন একটি ব্রাউজারের সাহায্যে আপনি * কোনও ফাইলের বিষয়বস্তু * পড়তে পারেন - ব্যবহারকারীকে এটি একটি <input>উপাদান বা ড্র্যাগ-এন্ড-ড্রপ দিয়ে নির্বাচন করতে হবে । জানুয়ারী ২০১৩ পর্যন্ত, এখানে প্রধান ব্রাউজারগুলি কীভাবে স্ট্যাক আপ রয়েছে:


30
জেএস-তে ফাইল সিস্টেম অ্যাক্সেস পাওয়ার অসম্ভবতা ছাড়াও, আমি ক্লায়েন্ট-উত্পন্ন চেকসামে কোনও আস্থা রাখব না। সুতরাং সার্ভারে চেকসাম তৈরি করা যে কোনও ক্ষেত্রেই বাধ্যতামূলক।
তোমালাক

4
@ তোমালাক ক্লায়েন্টের কাছে এটি করা বাধ্যতামূলক আপনি যদি কেবলমাত্র এটি ইতিমধ্যে আপলোড করতে চান তবে আপনার ইতিমধ্যে যা আছে তার চেয়ে আলাদা।
জন

2
@ জন ভাল, আমার বক্তব্য এটিকে অস্বীকার করে না। ক্লায়েন্ট-পার্শ্বের চেকগুলি কঠোরভাবে ব্যবহারকারীর সুবিধার জন্য (এবং আরও কম বা বেশি alচ্ছিক, আপনি এটি কতটা সুবিধাজনক করতে চান তার উপর নির্ভর করে)। অন্যদিকে সার্ভার-সাইড চেকগুলি বাধ্যতামূলক।
তোমালাক

pjhome.org.uk/crypt/md5 এ md5 ফাংশন ইনপুট হিসাবে বাইনারি সমর্থন করে না? আমি ব্রাউজারে একটি আপলোড করা চিত্রের জন্য বাইনারি স্ট্রিম গণনা করা প্রয়োজন বলে মনে করি। ধন্যবাদ.
jiajianrong

যদি আপনি পারেন তবে আপনার উত্তরে কিছু উদাহরণ কোড যুক্ত করুন। এটি অনেক সাহায্য করবে।
সিবিডিভেলপার

30

বড় আকারের ফাইলগুলি দক্ষতার সাথে হ্যাশ করার জন্য আমি একটি লাইব্রেরি তৈরি করেছি যা ইনক্রিমেন্টাল এমডি 5 প্রয়োগ করে। মূলত আপনি খণ্ডগুলিতে একটি ফাইল পড়েছেন (স্মৃতিশক্তি কম রাখতে) এবং এটি ক্রমবর্ধমানভাবে হ্যাশ করে। আপনি রিডমিতে বেসিক ব্যবহার এবং উদাহরণ পেয়েছেন।

আপনার এইচটিএমএল 5 ফাইলএপিআই দরকার সে বিষয়ে সচেতন হন, তাই এটির জন্য অবশ্যই পরীক্ষা করে দেখুন। পরীক্ষার ফোল্ডারে একটি পূর্ণ উদাহরণ রয়েছে।

https://github.com/satazor/SparkMD5


@ বিশওয়া এখানে আমার বাস্তবায়ন is gist.github.com/marlocorridor/3e6484ae5a646bd7c625
marlo

1
আরে এই দুর্দান্ত কাজ! আমি ক্রিপ্টোজেএস চেষ্টা করেছিলাম এবং কোনও কারণে কখনও এটির থেকে সঠিক এমডি 5 বের করতে পারি না, এটি কবজির মতো কাজ করে! Sha256 এর জন্য কোনও পরিকল্পনা? @ স্যাটাজোর
এসেছিলেন

@ ক্যামেক, লাইব্রেরিটি ভাল। তবে আমি আজ এটি চেষ্টা করেছি এবং মনে হচ্ছে যে .end()পদ্ধতিটিতে কোনও সমস্যা আছে । আপনি যদি এই পদ্ধতিটিকে আবার কল করেন তবে পরবর্তী বার এটি ভুল ফলাফল দেয়। কারণ অভ্যন্তরীণ .end()কল .reset()। এটি কোডিং বিপর্যয় এবং লাইব্রেরি লেখার পক্ষে ভাল নয়।
iammilind

লাইব্রেরির জন্য ধন্যবাদ! একটি ন্যূনতম কোড একসাথে রাখুন: dev.to/micmo/compute-md5-checksum-for-a-file-in-typescript-59a4
কোর্টেক্স

27

ক্রিপ্টোজেএস এবং এইচটিএমএল 5 ফাইলরেডার এপিআই এর এমডি 5 ফাংশন ব্যবহার করে এমডি 5 হ্যাশ গণনা করা বেশ সহজ । নিম্নলিখিত কোড স্নিপেটটি দেখায় যে আপনি কীভাবে বাইনারি ডেটা পড়তে পারেন এবং আপনার ব্রাউজারে টেনে আনা এমন চিত্র থেকে 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);
};

ড্র্যাগ অ্যান্ড ড্রপ এরিয়া দেখতে আমি কিছু সিএসএস যুক্ত করার পরামর্শ দিচ্ছি:

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

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

ড্র্যাগ অ্যান্ড ড্রপ কার্যকারিতা সম্পর্কে আরও এখানে পাওয়া যাবে: ফাইল এপিআই এবং ফাইলআরডার

আমি গুগল ক্রোম সংস্করণ 32 এ নমুনা পরীক্ষা করেছি tested


2
সমস্যাটি হ'ল readAsBinaryString()এটি মানসম্মত হয়নি এবং এটি ইন্টারনেট এক্সপ্লোরার দ্বারা সমর্থিত নয়। আমি এডে এটি পরীক্ষা করে দেখিনি, তবে আইই 11 এমনকি এটি সমর্থন করে না।
StanE

@ ব্যবহারকারী 25163 ইন্টারনেট এক্সপ্লোরার (এবং অপেরা মিনি) একমাত্র আধুনিক ব্রাউজার সমর্থন করছে না বলে মনে হচ্ছে readAsBinaryString(): caniuse.com/#feat=filereader - মাইক্রোসফ্ট এজ এটি সমর্থন করে।
বেনি নিউজবাউয়ার

এমএস এজ সম্পর্কিত তথ্যের জন্য ধন্যবাদ! আমি একটি সংস্থায় কাজ করি। এবং আপনি জানেন যে গ্রাহকরা প্রায়শই পুরানো সফ্টওয়্যার ব্যবহার করেন এবং তাদের সফ্টওয়্যার আপডেট করার জন্য তাদের বোঝানো কতটা কঠিন। আমি কেবল উল্লেখ করতে চেয়েছিলাম, এটির ক্ষেত্রে সতর্কতা অবলম্বন করা উচিত readAsBinaryString()কারণ এটি পুরানো ব্রাউজারগুলি সমর্থন করে না। আমার কাছে পাওয়া একটি বিকল্প স্পার্কএমডি 5। এটি ফাইলআরেডার এপিআই ব্যবহার করে তবে পদ্ধতিটি readAsArrayBuffer, যা আইআই দ্বারা সমর্থিত supported এবং এটি বিশাল আকারের ফাইলগুলি পড়ার দ্বারা পরিচালনা করতে পারে।
StanE

2
ক্রিপ্টোজেএস এখন আরেবাফার থেকে বাইনারি / ওয়ার্ডআরেতে রূপান্তরিত করে এর মাধ্যমে সমর্থন করে:CryptoJS.lib.WordArray.create(arrayBuffer);
ওয়ারেন

@ ওয়ারেনপ্যারাদ এবং তারপরে কোডটি কীভাবে অ্যারেবফারের সাথে কাজ করার জন্য পরিবর্তন করা হবে? : আহা, তা এখানে পাওয়া stackoverflow.com/questions/28437181/...
TheStoryCoder

9

HTML5 + spark-md5এবংQ

ধরে নিচ্ছি যে আপনি একটি আধুনিক ব্রাউজার ব্যবহার করছেন (এটি এইচটিএমএল 5 ফাইল এপিআই সমর্থন করে) আপনি এখানে একটি বৃহত ফাইলের 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

আপনাকে ফাইলএপিআই ব্যবহার করতে হবে। এটি সর্বশেষতম এফএফ এবং ক্রোমে উপলব্ধ, তবে আইই 9 নয়। উপরে প্রস্তাবিত যে কোনও এমডি 5 জেএস বাস্তবায়ন ধরুন। আমি এটি চেষ্টা করেছি এবং এটিকে পরিত্যাগ করেছি কারণ জেএস খুব ধীর ছিল (বড় চিত্রের ফাইলে কিছু মিনিট)। যদি কেউ টাইপ করা অ্যারে ব্যবহার করে এমডি 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));
     }
 }

ওয়েবটোকলিট এমডি 5 বেন্ডিওয়ে দ্বারা নির্দেশিত একাধিক এমবি ফাইলের জন্য 16 সেকেন্ডের আরও ভাল পারফরম্যান্স করেছে: webtoolkit.info/javascript-md5.html
আলেকজান্ডার টোটিক

1
আমি এই কাজটি পরিচালনা করতে সক্ষম হয়েছি এবং একই এমডি 5 হ্যাশটি টেক্সট ফাইলগুলির জন্য (php: md5_file (...)) উত্পন্ন করছে তবে চিত্রগুলি আমাকে বিভিন্ন ফলাফল দিচ্ছে? এটি বাইনারি ডেটা বা এর আপলোড করার উপায়ের সাথে কিছু করার?
দুর্গগুলি

আমি বেশ নিশ্চিত যে এই কোডটি একাধিক ফাইলের সাথে কাজ করে না, কারণ ওললোডটি একটি কলব্যাক হয়, readerভেরিয়েবলটি ওভারলোড ফাংশনগুলি সঞ্চালনের সময়ে শেষ ফাইল হবে।
ডেভ

ক্রিপ্টোজেএস এখন আরেবাফার থেকে বাইনারি / ওয়ার্ডআরেতে রূপান্তরিত করে এর মাধ্যমে সমর্থন করে:CryptoJS.lib.WordArray.create(arrayBuffer);
ওয়ারেন

4

জেএস-তে ফাইল সিস্টেম অ্যাক্সেস পাওয়ার অসম্ভবতা ছাড়াও, আমি ক্লায়েন্ট-উত্পন্ন চেকসামে কোনও আস্থা রাখব না। সুতরাং সার্ভারে চেকসাম তৈরি করা যে কোনও ক্ষেত্রেই বাধ্যতামূলক। - তোমালাক এপ্রিল 20 '09 এ 14:05 এ

যা বেশিরভাগ ক্ষেত্রেই অকেজো। আপনি ক্লায়েন্ট সাইডে এমডি 5 গণনা করতে চান, যাতে আপনি এটি সার্ভার সাইডে সংশোধিত কোডের সাথে তুলনা করতে পারেন এবং সিদ্ধান্ত নিতে পারছেন যে তারা যদি আলাদা হয় তবে আপলোডটি ভুল হয়েছে। আমার এটি করা দরকার যে বৈজ্ঞানিক ডেটার বড় ফাইলগুলির সাথে কাজ করে এমন অ্যাপ্লিকেশনগুলিতে, যেখানে নিরবচ্ছিন্ন ফাইলগুলি প্রাপ্তি হ'ল মূল বিষয়। আমার কেসগুলি সহজ ছিল, কারণ ব্যবহারকারীদের এমডি 5 ইতিমধ্যে তাদের ডেটা বিশ্লেষণ সরঞ্জামগুলি থেকে গণনা করা হয়েছিল, সুতরাং আমার কেবল পাঠ্য ক্ষেত্রের সাথে তাদের এটি জিজ্ঞাসা করা দরকার।


3

ফাইলগুলির হ্যাশ পেতে, অনেকগুলি বিকল্প রয়েছে। সাধারণত সমস্যাটি হ'ল বড় ফাইলগুলির হ্যাশ পাওয়া সত্যিই ধীর।

আমি একটি ছোট লাইব্রেরি তৈরি করেছি যা ফাইলগুলির শুরুতে k৪ কেবি এবং এটির শেষের k৪ কেবি দিয়ে ফাইলগুলির হ্যাশ পায়।

সরাসরি উদাহরণ: http://marcu87.github.com/hashme/ এবং গ্রন্থাগার: https://github.com/marcu87/hashme


2

এমডি 5 হ্যাশ তৈরি করতে ইন্টারনেটে সেখানে বেশ কয়েকটি স্ক্রিপ্ট রয়েছে।

ওয়েব টোকলিট থেকে একটি ভাল, http://www.webtoolkit.info/javascript-md5.html

যদিও, আমি বিশ্বাস করি না যে এটির স্থানীয় ফাইল সিস্টেমটিতে অ্যাক্সেস থাকবে কারণ অ্যাক্সেস সীমাবদ্ধ।


1

আশা করি আপনি এতক্ষণে একটি ভাল সমাধান খুঁজে পেয়েছেন। যদি তা না হয় তবে নীচের সমাধানটি জেএস -স্পার্ক-এমডি 5 এর উপর ভিত্তি করে একটি 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 এমবি / গুলি একটি থ্রুপুট সংরক্ষণাগারভুক্ত করতে পারে।

এটি হ্যাশ-ওয়েম নামে একটি লাইব্রেরি ব্যবহার করছে , যা ওয়েবঅ্যাস্পাবলির উপর ভিত্তি করে এবং হ্যাশকে কেবল জেএস-এর লাইব্রেরির চেয়ে দ্রুত গণনা করে। 2020 পর্যন্ত, সমস্ত আধুনিক ব্রাউজারগুলি ওয়েবঅ্যাসাব্ল্যাশনে সমর্থন করে।

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 এর মাধ্যমে বাইনারি ফাইলের এমডি 5 হ্যাশ গণনা করা উচিত, তবে আমি মনে করি এর আগে যে পদক্ষেপটি ছিল বেনারি ডেটা ব্লববিল্ডারকে একটি স্ট্রিংয়ে রূপান্তর করা, আমি এই পদক্ষেপটি করার চেষ্টা করছি: তবে সফল হতে পারিনি।

আমি চেষ্টা করেছি এমন কোডটি এখানে: এইচটিএমএল 5 জাভাস্ক্রিপ্টে একটি ব্লববিল্ডারকে স্ট্রিংয়ে রূপান্তর করা


-1

আমি বিশ্বাস করি না যে কোনও ফাইল আপলোডের বিষয়বস্তু অ্যাক্সেস করার জন্য জাভাস্ক্রিপ্টের একটি উপায় আছে। সুতরাং আপনি এমডি 5 যোগ করতে ফাইলের সামগ্রীগুলি দেখতে পারেন না।

তবে আপনি সার্ভারে ফাইলটি প্রেরণ করতে পারেন, এটির পরে MD5 যোগফল পাঠাতে বা ফাইলের সামগ্রীগুলি ফেরত পাঠাতে পারে .. তবে এটি অনেক কাজ এবং সম্ভবত আপনার উদ্দেশ্যে সার্থক নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.