HTML Data Port

© 2005 Goetz Heller

Table of Contents Description Examples Subclass Template Copyright Note back

hashAlgorithm: An Abstract Base Class - JavaScript Source Code

try { 
  if (system.security.encryption.hash.hashAlgorithm == null) {
    throw new Error('');
  };
} catch(e) { // don't install twice
  // dependencies
  try {
    eval('core');
  } catch(e) {
    throw new Error('hashAlgorithm: class \'core\' not installed');
  }

// generic hash interface

// constructor
var hashAlgorithm = function() {};

// provide for class information
hashAlgorithm.classID = function() {
  return 'system.security.encryption.hash.hashAlgorithm';
};

// disallow instantiation
hashAlgorithm.isAbstract = function() {
  return true;
};

// class factory
hashAlgorithm.create = function(alg) {
  if (arguments.length == 0) {
    throw new Error('hashAlgorithm.create(): missing argument');
  }
  if (typeof alg != 'string') {
    throw new Error('hashAlgorithm.create(): wrong argument type');
  }
  var cls = null;
  var cn = alg
  try {
    cls = core.getClassByID(cn);
  } catch(e) {
    cn = (new core.classPath(alg)).nameSpaceString();
    if (cn == null || cn.length == 0) {
      cn = 'system.security.encryption.hash.'+alg;
    }
    try {
      cls = core.getClassByID(cn);
    } catch(e) {
      throw new Error('hashAlgorithm.create(): class \''+alg+'\' not installed');
    }
  }
  if (cls.sup.classID() != this.classID()) {
      throw new Error('hashAlgorithm.create(): class \''+alg+'\' is not a hash algorithm');
  }
  return core.createInstance(cn);
};

// returns the hash value as a byte array. Assumes computeHash() has been called before.
hashAlgorithm.prototype.getHashValue = function() {
  return this.hashValue;
};

// populate with data structures
hashAlgorithm.prototype.initialize = function() {
  // do specific initialization stuff
  this.buffer = new Array(this.iInputBlockSize);    // input buffer (byte)
  this.hashValue = new Array(this.iOutputBlockSize);// (byte)
  this.hash = '';
};

// override; to be called from overriding method on subclass instance
hashAlgorithm.prototype.reset = function() {
  try {
    // reset digest string
    this.hash = '';
    // clear digest array
    for (var i = 0; i < this.hashValue.length; i++) {
      this.hashValue[i] = 0x00;
      this.hash += String.fromCharCode(0);
    }
    // clear Buffer
    for (var i = 0; i < this.buffer.length; i++) {
      this.buffer[i] = 0x00;
    }
  } catch(e) {};
};

// digest a string and return digest as string
hashAlgorithm.prototype.computeHash = function(inp) {
  if (typeof inp != 'string') {
    return null;
  }
  this.reset();
  this.hashCore(inp, 0, inp.length);
  this.hashFinal();
  return this.buildHash();
};

// override
hashAlgorithm.prototype.hashCore = function(inp, start, bcount) {
  throw new Error ('hashAlgorithm.hashCore(): abstract function not overridden');
};

// build digest string from hashValue, a byte array
hashAlgorithm.prototype.hashFinal = function() {
  throw new Error ('hashAlgorithm.hashFinal(): abstract function not overridden');
};

// build digest string from hashValue, a byte array
// override and call from overriding method as last statement
// before returning
hashAlgorithm.prototype.buildHash = function() {
  this.hash = '';
  for (var i = 0; i < this.hashValue.length; i++) {
    this.hash += String.fromCharCode(this.hashValue[i]);
  }
  return this.hash;
};

core.installClass(hashAlgorithm);

} // end catch