最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

How do I use Sha256 on a file(binary file such as images) in javascript? - Stack Overflow

matteradmin2PV0评论

I am trying to do a Sha256 on a file in Javascript. I used FileReader(HTML5) to read in a file. I use the readAsBinaryString function in the FileReader to pass in the images file. Then on the FileReader.onload function I pass in the evt.target.result to the SHA256 method in the CryptoJs API. I am able to successfully get a hash value but it is not correct. When I pass in a text file, it works fine but not image file.

Code(Should be able to copy the code below to a HTML file and run it on firefox - press the "entire file" button):

<style>
  #byte_content {
    margin: 5px 0;
    max-height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
  }
  #byte_range { margin-top: 5px; }
</style>

<input type="file" id="files" name="file" /> Read bytes: 
<span class="readBytesButtons">
  <button data-startbyte="0" data-endbyte="4">1-5</button>
  <button data-startbyte="5" data-endbyte="14">6-15</button>
  <button data-startbyte="6" data-endbyte="7">7-8</button>
  <button>entire file</button>
</span>
<div id="byte_range"></div><BR>
<div id="byte_content"></div><BR>
<div id="crypto_sha256"></div>

<script src=".0.2/build/rollups/sha256.js"></script>
<script src=".0.2/build/ponents/enc-base64-min.js"></script>
<script>

  var sha256;

  function readBlob(opt_startByte, opt_stopByte) {

    var files = document.getElementById('files').files;
    if (!files.length) {
      alert('Please select a file!');
      return;
    }

    var file = files[0];
    var start = parseInt(opt_startByte) || 0;
    var stop = parseInt(opt_stopByte) || file.size - 1;

    var reader = new FileReader();

    // If we use onloadend, we need to check the readyState.
    reader.onloadend = function(evt) {
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        document.getElementById('byte_content').textContent = evt.target.result;
        document.getElementById('byte_range').textContent = 
            ['Read bytes: ', start + 1, ' - ', stop + 1,
             ' of ', file.size, ' byte file'].join('');

        //**UPDATED SOLUTION: Since its binary data, the message needs to be converted from string to bytes using Latin1**
            sha256.update(CryptoJS.enc.Latin1.parse(evt.target.result));

        var hash = sha256.finalize();

        document.getElementById('crypto_sha256').textContent = ['SHA-256: ', hash].join('');
      }
    };

    var blob = file.slice(start, stop + 1);
    reader.readAsBinaryString(blob);
  }

  document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
    if (evt.target.tagName.toLowerCase() == 'button') {
      var startByte = evt.target.getAttribute('data-startbyte');
      var endByte = evt.target.getAttribute('data-endbyte');

      sha256 = CryptoJS.algo.SHA256.create();

      readBlob(startByte, endByte);
    }
  }, false);
</script>

Sample outputs:

  1. Testing a "text" file:

    • SHA256 generated by Javascript:
      78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09
    • SHA256 generated by cygwin on the same file:
      $ sha256sum Phillips.txt 78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09 *SomeTestFile.txt
  2. Testing a "binary" file(pdf):

    • SHA256 generated by Javascript:
      57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605
    • SHA256 generated by cygwin on the same file:
      $ sha256sum Smoke\ Detector\ Brochure.pdf 57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605 *Smoke Detector Brochure.pdf

I am trying to do a Sha256 on a file in Javascript. I used FileReader(HTML5) to read in a file. I use the readAsBinaryString function in the FileReader to pass in the images file. Then on the FileReader.onload function I pass in the evt.target.result to the SHA256 method in the CryptoJs API. I am able to successfully get a hash value but it is not correct. When I pass in a text file, it works fine but not image file.

Code(Should be able to copy the code below to a HTML file and run it on firefox - press the "entire file" button):

<style>
  #byte_content {
    margin: 5px 0;
    max-height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
  }
  #byte_range { margin-top: 5px; }
</style>

<input type="file" id="files" name="file" /> Read bytes: 
<span class="readBytesButtons">
  <button data-startbyte="0" data-endbyte="4">1-5</button>
  <button data-startbyte="5" data-endbyte="14">6-15</button>
  <button data-startbyte="6" data-endbyte="7">7-8</button>
  <button>entire file</button>
</span>
<div id="byte_range"></div><BR>
<div id="byte_content"></div><BR>
<div id="crypto_sha256"></div>

<script src="http://crypto-js.googlecode./svn/tags/3.0.2/build/rollups/sha256.js"></script>
<script src="http://crypto-js.googlecode./svn/tags/3.0.2/build/ponents/enc-base64-min.js"></script>
<script>

  var sha256;

  function readBlob(opt_startByte, opt_stopByte) {

    var files = document.getElementById('files').files;
    if (!files.length) {
      alert('Please select a file!');
      return;
    }

    var file = files[0];
    var start = parseInt(opt_startByte) || 0;
    var stop = parseInt(opt_stopByte) || file.size - 1;

    var reader = new FileReader();

    // If we use onloadend, we need to check the readyState.
    reader.onloadend = function(evt) {
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        document.getElementById('byte_content').textContent = evt.target.result;
        document.getElementById('byte_range').textContent = 
            ['Read bytes: ', start + 1, ' - ', stop + 1,
             ' of ', file.size, ' byte file'].join('');

        //**UPDATED SOLUTION: Since its binary data, the message needs to be converted from string to bytes using Latin1**
            sha256.update(CryptoJS.enc.Latin1.parse(evt.target.result));

        var hash = sha256.finalize();

        document.getElementById('crypto_sha256').textContent = ['SHA-256: ', hash].join('');
      }
    };

    var blob = file.slice(start, stop + 1);
    reader.readAsBinaryString(blob);
  }

  document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
    if (evt.target.tagName.toLowerCase() == 'button') {
      var startByte = evt.target.getAttribute('data-startbyte');
      var endByte = evt.target.getAttribute('data-endbyte');

      sha256 = CryptoJS.algo.SHA256.create();

      readBlob(startByte, endByte);
    }
  }, false);
</script>

Sample outputs:

  1. Testing a "text" file:

    • SHA256 generated by Javascript:
      78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09
    • SHA256 generated by cygwin on the same file:
      $ sha256sum Phillips.txt 78cb5e86455dc8e3bc20fe17e0213a938281216d57b31f8307f5bca67c37bb09 *SomeTestFile.txt
  2. Testing a "binary" file(pdf):

    • SHA256 generated by Javascript:
      57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605
    • SHA256 generated by cygwin on the same file:
      $ sha256sum Smoke\ Detector\ Brochure.pdf 57f93c1d20a8ad8ade984a1d9756c1a40600bd8a7527601945c4e0b5e042c605 *Smoke Detector Brochure.pdf
Share edited Dec 24, 2012 at 15:25 user422930 asked Dec 20, 2012 at 22:53 user422930user422930 2591 gold badge5 silver badges15 bronze badges 8
  • Why do you think it isn't correct? – Hunter McMillen Commented Dec 20, 2012 at 22:54
  • Print the file to screen on the FileReader.onload and pare it side by side with the original. Is it the same? – Tyron Commented Dec 20, 2012 at 22:57
  • I ran a sha256 on the same file in cygwin(sha256sum) and in java(MessageDigest.getInstance("SHA-256")). Cygwin and java gave me the same sha256 hash. – user422930 Commented Dec 20, 2012 at 23:53
  • I read the file into the FileReader object and then used (e.target.result) to display the file to screen and it seemed to work fine. – user422930 Commented Dec 20, 2012 at 23:56
  • 1 Jeff Mott, the owner of the CryptoJS was able to help me resolve the issue. Here is Jeff's solution and explanation: crypto-js issues – user422930 Commented Dec 24, 2012 at 15:15
 |  Show 3 more ments

2 Answers 2

Reset to default 4

I know this question is quite old but I figured I'd share what I know anyways.

You can do this more easily by doing what I discuss in this answer https://stackoverflow./a/17848266/2226207

Basically you can include ponents/lib-typedarrays-min.js and then do the following in code.

var reader = new FileReader();

// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
  if (evt.target.readyState == FileReader.DONE) { // DONE == 2

    var wordArray = CryptoJS.lib.WordArray.create(e.target.result);
    var hash = CryptoJS.SHA256(wordArray);
  }
};

var blob = file.slice(start, stop + 1);
reader.readAsArrayBuffer(blob);

I haven't tested the above solution but it should work fine.

Here is a simple solution found : https://code.google./p/crypto-js/issues/detail?id=62

When you pass a string to a hasher, it's converted to bytes using UTF-8. That's to ensure foreign characters are not clipped. Since you're working with binary data, you'll want to convert the string to bytes using Latin1.

sha256.update(CryptoJS.enc.Latin1.parse(evt.target.result));
Post a comment

comment list (0)

  1. No comments so far