1

I use CryptoJs to have hash (sha256) of a PDF file.

I already have the hash of my file but I can't get it outside the function.

This is my code :

var reader = new FileReader();
var hash = "";

reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        var i8a = new Uint8Array(evt.target.result);
        var a = []; for (var i = 0; i < i8a.length; i += 4) { a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]); }
        var wordArray = CryptoJS.lib.WordArray.create(a,i8a.length);
        var hash = CryptoJS.SHA256(wordArray);
        alert(hash);
    }
};

var blob = file.slice(0, file.size + 1);
reader.readAsArrayBuffer(blob);

alert(hash);

The first alert give me the sha, but the second is empty. How can I do to get hash defined into the function to use it after?

if I add a callBack function it working. But I wanted to make an Ajax request, and when I add the request into a callBack function like this :

function callBack(hash){
     $.ajax({
          type: "POST",
          url:"http://...",
          dataType:'json',
          data:({shaPdf: hash}),
          success: function(data) {
             //...
           },
          error: function(error) {
           }
           });

I have this error into my console :

Uncaught TypeError: Cannot read property 'words' of undefined
wxcvbn
  • 483
  • 2
  • 7
  • 20

1 Answers1

1

You need a call back function:

var reader = new FileReader();
var hash = "";

reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        var i8a = new Uint8Array(evt.target.result);
        var a = []; for (var i = 0; i < i8a.length; i += 4) { a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]); }
        var wordArray = CryptoJS.lib.WordArray.create(a,i8a.length);
        var hash = CryptoJS.SHA256(wordArray);
        callBack(hash); // <-- callBack at the end of this function
    }
};

var blob = file.slice(0, file.size + 1);
reader.readAsArrayBuffer(blob);

function callBack(hash)
{
   alert(hash);
}

Since your reader is loading the file asynchronous, the second alert fires immediately after the other code. The reader is not done yet loading the file, so hash is empty. If we wrap the alert into a function, which we call upon after the onloadend, we are able to use the value outside of the function.

Mouser
  • 13,132
  • 3
  • 28
  • 54
  • It's working, but after I wanted to make an ajax request, and your solution doesn't work if I add an ajax request into the callBack function. Have you got any idea? – wxcvbn Jan 03 '17 at 13:58
  • It's basically the same. Read up on asynchronous calls. Ajax calls also need a call back after they are done. – Mouser Jan 03 '17 at 13:59
  • Sorry I don't understand, how can I do a callback on ajax request? – wxcvbn Jan 03 '17 at 14:03
  • I've update my code – wxcvbn Jan 03 '17 at 14:07
  • I see now, you can put an ajax call into it, after that something in your code breaks it. I can't see it with this example. Please start another question, since this one has been answered. The problem you're facing now has a different origin. – Mouser Jan 03 '17 at 14:09
  • I think I find the problem. the type of hash passed as parameter into callback function is an object not a string. I don't understant when I do an `alert` hash I have my PDF hash, but when I look into the oject hash I can't see anything witch can be a hash. Do you know how can I get the real hash value ? – wxcvbn Jan 03 '17 at 14:35
  • It's okay I found the solution! – wxcvbn Jan 03 '17 at 14:40