59 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| function pad (hash, len) {
 | |
|   while (hash.length < len) {
 | |
|     hash = '0' + hash;
 | |
|   }
 | |
|   return hash;
 | |
| }
 | |
| 
 | |
| function fold (hash, text) {
 | |
|   var i;
 | |
|   var chr;
 | |
|   var len;
 | |
|   if (text.length === 0) {
 | |
|     return hash;
 | |
|   }
 | |
|   for (i = 0, len = text.length; i < len; i++) {
 | |
|     chr = text.charCodeAt(i);
 | |
|     hash = ((hash << 5) - hash) + chr;
 | |
|     hash |= 0;
 | |
|   }
 | |
|   return hash < 0 ? hash * -2 : hash;
 | |
| }
 | |
| 
 | |
| function foldObject (hash, o, seen) {
 | |
|   return Object.keys(o).sort().reduce(foldKey, hash);
 | |
|   function foldKey (hash, key) {
 | |
|     return foldValue(hash, o[key], key, seen);
 | |
|   }
 | |
| }
 | |
| 
 | |
| function foldValue (input, value, key, seen) {
 | |
|   var hash = fold(fold(fold(input, key), toString(value)), typeof value);
 | |
|   if (value === null) {
 | |
|     return fold(hash, 'null');
 | |
|   }
 | |
|   if (value === undefined) {
 | |
|     return fold(hash, 'undefined');
 | |
|   }
 | |
|   if (typeof value === 'object') {
 | |
|     if (seen.indexOf(value) !== -1) {
 | |
|       return fold(hash, '[Circular]' + key);
 | |
|     }
 | |
|     seen.push(value);
 | |
|     return foldObject(hash, value, seen);
 | |
|   }
 | |
|   return fold(hash, value.toString());
 | |
| }
 | |
| 
 | |
| function toString (o) {
 | |
|   return Object.prototype.toString.call(o);
 | |
| }
 | |
| 
 | |
| function sum (o) {
 | |
|   return pad(foldValue(0, o, '', []).toString(16), 8);
 | |
| }
 | |
| 
 | |
| module.exports = sum;
 |