Search code examples
javascriptnode.jsexpressnode-crypto

Crypto module - Node.js


Which is the simplest way to compare a hash of a file without storing it in a database?

For example:

var filename = __dirname + '/../public/index.html';
var shasum = crypto.createHash('sha1');

var s = fs.ReadStream(filename);
s.on('data', function(d) {
  shasum.update(d);
});

s.on('end', function() {
  var d = shasum.digest('hex');
  console.log(d + ' ' + filename);

  fs.writeFile(__dirname + "/../public/log.txt", d.toString() + '\n', function(err) {
     if(err) {
         console.log(err);
      } else {
         console.log("The file was saved!");
      }
  }); 
});

The above code returns the hash of the HTML file. If I edit the file how can I know if it has been changed? In other words, how can I know if the hash has been changed?

Any suggestions?

Edited

Now the hash is being saved in the log file. How can I retrieve the hash from the file and match it with the new generated one? A code example would be awesome to give me a better understanding.

There is no difference with this question, but it isn't clear for me yet how to implement it.


Solution

  • If you're looking for changes on a file, then you can use one of Node's filesystem functions, fs.watch. This is how it's used:

    fs.watch(filename, function (event, filename) {
      //event is either 'rename' or 'change'
      //filename is the name of the file which triggered the event
    });
    

    The watch function is however not very consistent, so you can use fs.watchFile as an alternative. fs.watchFile uses stat polling, so it's quite a bit slower than fs.watch, which detects file changes instantly.

    Watching a file will return an instance of fs.FSWatcher, which has the events change and error. Calling .close will stop watching for changes on the file.

    Here's an example relating to your code:

    var filename = __dirname + '/../public/index.html';
    var shasum = crypto.createHash('sha1');
    
    var oldhash = null;
    
    var s = fs.ReadStream(filename);
    s.on('data', function(d) {
      shasum.update(d);
    });
    
    s.on('end', function() {
      var d = shasum.digest('hex');
      console.log(d + ' ' + filename);
      oldhash = d.toString();
    
      fs.writeFile(__dirname + "/../public/log.txt", d.toString() + '\n', function(err) {
         if(err) {
             console.log(err);
          }
          else {
             console.log("The file was saved!");
          }
      }); 
    });
    
    //watch the log for changes
    fs.watch(__dirname + "/../public/log.txt", function (event, filename) {
      //read the log contents
      fs.readFile(__dirname + "/../public/log.txt", function (err, data) {
        //match variable data with the old hash
        if (data == oldhash) {
          //do something
        }
      });
    });