Combiné las respuestas de los párpados y KimKha.
El siguiente es un servicio angularjs y admite números, cadenas y objetos.
exports.Hash = () => {
let hashFunc;
function stringHash(string, noType) {
let hashString = string;
if (!noType) {
hashString = `string${string}`;
}
var hash = 0;
for (var i = 0; i < hashString.length; i++) {
var character = hashString.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
function objectHash(obj, exclude) {
if (exclude.indexOf(obj) > -1) {
return undefined;
}
let hash = '';
const keys = Object.keys(obj).sort();
for (let index = 0; index < keys.length; index += 1) {
const key = keys[index];
const keyHash = hashFunc(key);
const attrHash = hashFunc(obj[key], exclude);
exclude.push(obj[key]);
hash += stringHash(`object${keyHash}${attrHash}`, true);
}
return stringHash(hash, true);
}
function Hash(unkType, exclude) {
let ex = exclude;
if (ex === undefined) {
ex = [];
}
if (!isNaN(unkType) && typeof unkType !== 'string') {
return unkType;
}
switch (typeof unkType) {
case 'object':
return objectHash(unkType, ex);
default:
return stringHash(String(unkType));
}
}
hashFunc = Hash;
return Hash;
};
Ejemplo de uso:
Hash('hello world'), Hash('hello world') == Hash('hello world')
Hash({hello: 'hello world'}), Hash({hello: 'hello world'}) == Hash({hello: 'hello world'})
Hash({hello: 'hello world', goodbye: 'adios amigos'}), Hash({hello: 'hello world', goodbye: 'adios amigos'}) == Hash({goodbye: 'adios amigos', hello: 'hello world'})
Hash(['hello world']), Hash(['hello world']) == Hash(['hello world'])
Hash(1), Hash(1) == Hash(1)
Hash('1'), Hash('1') == Hash('1')
Salida
432700947 true
-411117486 true
1725787021 true
-1585332251 true
1 true
-1881759168 true
Explicación
Como puede ver, el corazón del servicio es la función hash creada por KimKha. He agregado tipos a las cadenas para que la estructura del objeto también afecte el valor hash final. Las claves se combinan para evitar colisiones de matriz | objeto.
La comparación de objetos sin párpados se utiliza para evitar una recursión infinita mediante objetos de autorreferencia.
Uso
Creé este servicio para poder tener un servicio de error al que se accede con objetos. Para que un servicio pueda registrar un error con un objeto determinado y otro pueda determinar si se encontraron errores.
es decir
JsonValidation.js
ErrorSvc({id: 1, json: '{attr: "not-valid"}'}, 'Invalid Json Syntax - key not double quoted');
UserOfData.js
ErrorSvc({id: 1, json: '{attr: "not-valid"}'});
Esto devolvería:
['Invalid Json Syntax - key not double quoted']
Mientras
ErrorSvc({id: 1, json: '{"attr": "not-valid"}'});
Esto volvería
[]