Ich muss Strings in eine Art Hash konvertieren. Ist das in JavaScript möglich?
Ich verwende keine serverseitige Sprache, daher kann ich das nicht so machen.
Ich muss Strings in eine Art Hash konvertieren. Ist das in JavaScript möglich?
Ich verwende keine serverseitige Sprache, daher kann ich das nicht so machen.
Antworten:
Object.defineProperty(String.prototype, 'hashCode', {
value: function() {
var hash = 0, i, chr;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
});
Quelle: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
hash << 5 - hash
ist das gleiche wie hash * 31 + char
aber viel schneller. Es ist schön, weil es so schnell ist und 31 eine kleine Primzahl ist. Win Win dort.
(hash * 31) + char
ist identisch mit der Ausgabe des Shift-basierten Codes ((hash<<5)-hash)+char
, selbst für sehr lange Zeichenfolgen (ich habe sie mit Zeichenfolgen mit mehr als einer Million Zeichen getestet), sodass sie nicht "unbrauchbar" ist der Genauigkeit. Die Komplexität ist O (n) sowohl für die zahlenbasierte als auch für die verschiebungsbasierte Version, daher ist sie hinsichtlich der Komplexität nicht "unbrauchbar".
n
, was ist der größte, n
für den ich möglicherweise keine Kollision haben kann?
var hashCode = function hashCode (str) {etc...}
? Und dann verwenden als hashCode("mystring")
?
BEARBEITEN
Basierend auf meinen jsperf-Tests ist die akzeptierte Antwort tatsächlich schneller: http://jsperf.com/hashcodelordvlad
ORIGINAL
Wenn jemand interessiert ist, ist hier eine verbesserte (schnellere) Version, die bei älteren Browsern, denen die reduce
Array-Funktion fehlt, fehlschlägt .
hashCode = function(s){
return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
Version mit einzeiliger Pfeilfunktion:
hashCode = s => s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)
Hinweis: Selbst mit dem besten 32-Bit - Hash - Kollisionen werden früher oder später auftreten.
Die Hash - Kollision probablility kann berechnet werden , wie aproximated ( siehe hier ). Dies kann höher sein, als die Intuition vermuten lässt:
Unter der Annahme eines 32-Bit-Hashs und k = 10.000 Elementen tritt eine Kollision mit einer Wahrscheinlichkeit von 1,2% auf. Für 77.163 Proben beträgt die Wahrscheinlichkeit 50%! ( Taschenrechner ).
Ich schlage unten eine Problemumgehung vor.
In einer Antwort auf diese Frage
Welcher Hashing-Algorithmus eignet sich am besten für Eindeutigkeit und Geschwindigkeit? Ian Boyd hat eine gründliche Analyse veröffentlicht . Kurz gesagt (wie ich es interpretiere) kommt er zu dem Schluss, dass Murmeln am besten ist, gefolgt von FNV-1a.
Der von esmiralha vorgeschlagene String.hashCode () -Algorithmus von Java scheint eine Variante von DJB2 zu sein.
Einige Benchmarks mit großen Eingabezeichenfolgen hier: http://jsperf.com/32-bit-hash
Wenn kurze Eingabezeichenfolgen gehasht werden, sinkt die Leistung des Murmelns im Vergleich zu DJ2B und FNV-1a: http://jsperf.com/32- Bit-Hash / 3
Im Allgemeinen würde ich murmur3 empfehlen.
Eine JavaScript-Implementierung finden Sie hier:
https://github.com/garycourt/murmurhash-js
Wenn die Eingabezeichenfolgen kurz sind und die Leistung wichtiger ist als die Verteilungsqualität, verwenden Sie DJB2 (wie in der akzeptierten Antwort von esmiralha vorgeschlagen).
Wenn Qualität und kleine Codegröße wichtiger sind als Geschwindigkeit, verwende ich diese Implementierung von FNV-1a (basierend auf diesem Code ).
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
function hashFnv32a(str, asString, seed) {
/*jshint bitwise:false */
var i, l,
hval = (seed === undefined) ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if( asString ){
// Convert to 8 digit hex string
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
}
Kollisionswahrscheinlichkeit verbessern
Wie hier erklärt , können wir die Hash-Bitgröße mit diesem Trick erweitern:
function hash64(str) {
var h1 = hash32(str); // returns 32 bit (as 8 byte hex string)
return h1 + hash32(h1 + str); // 64 bit (as 16 byte hex string)
}
Gehen Sie vorsichtig damit um und erwarten Sie nicht zu viel.
("0000000" + (hval >>> 0).toString(16)).substr(-8);
? Ist das nicht dasselbe wie (hval >>> 0).toString(16)
?
hval
, (hval >>> 0).toString(16)
vielleicht weniger als 8 Zeichen lang sein, so dass Sie Pad mit Nullen. Ich war nur verwirrt, weil ich (hval >>> 0).toString(16)
immer genau 8 Zeichen hatte.
Math.imul
Funktion implementiert wird . Das allein macht es zu Top-Benchmarks und letztendlich zu einer besseren Wahl als DJB2 auf lange Sicht.
Basierend auf der akzeptierten Antwort in ES6. Kleiner, wartbar und funktioniert in modernen Browsern.
function hashCode(str) {
return str.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
// Test
console.log("hashCode(\"Hello!\"): ", hashCode('Hello!'));
EDIT (2019-11-04) :
Version mit einzeiliger Pfeilfunktion:
const hashCode = s => s.split('').reduce((a,b) => (((a << 5) - a) + b.charCodeAt(0))|0, 0)
// test
console.log(hashCode('Hello!'))
str += ""
vor dem Hashing hinzugefügt habe , um Ausnahmen zu vermeiden, die str.split is not a function
ausgelöst wurden, wenn Nicht-Strings als Parameter übergeben wurden
hash |= 0
, um in ein 32-Bit-Int zu konvertieren. Diese Implementierung funktioniert nicht. Ist das ein Fehler?
Fast die Hälfte der Antworten sind Implementierungen von Java
String.hashCode
, die weder von hoher Qualität noch superschnell sind. Es ist nichts Besonderes, es multipliziert sich nur mit 31 für jeden Charakter. Es kann einfach und effizient in einer Zeile implementiert werden und ist viel schneller mitMath.imul
:
hashCode=s=>{for(var i=0,h;i<s.length;i++)h=Math.imul(31,h)+s.charCodeAt(i)|0;return h}
Hier ist etwas Besseres - cyrb53 , ein einfacher, aber qualitativ hochwertiger 53-Bit-Hash. Es ist ziemlich schnell, bietet eine sehr gute Hash-Verteilung und deutlich niedrigere Kollisionsraten als jeder 32-Bit-Hash.
const cyrb53 = function(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ h1>>>16, 2246822507) ^ Math.imul(h2 ^ h2>>>13, 3266489909);
h2 = Math.imul(h2 ^ h2>>>16, 2246822507) ^ Math.imul(h1 ^ h1>>>13, 3266489909);
return 4294967296 * (2097151 & h2) + (h1>>>0);
};
Ähnlich wie bei den bekannten MurmurHash / xxHash-Algorithmen wird eine Kombination aus Multiplikation und Xorshift verwendet , um den Hash zu generieren, jedoch nicht so gründlich. Dadurch ist es schneller als JavaScript und wesentlich einfacher zu implementieren.
Es wird eine Lawine (nicht streng) erreicht, was im Grunde bedeutet, dass kleine Änderungen in der Eingabe große Änderungen in der Ausgabe haben, wodurch der resultierende Hash zufällig erscheint:
0xc2ba782c97901 = cyrb53("a")
0xeda5bc254d2bf = cyrb53("b")
0xe64cc3b748385 = cyrb53("revenge")
0xd85148d13f93a = cyrb53("revenue")
Sie können auch einen Startwert für alternative Streams derselben Eingabe angeben:
0xee5e6598ccd5c = cyrb53("revenue", 1)
0x72e2831253862 = cyrb53("revenue", 2)
0x0de31708e6ab7 = cyrb53("revenue", 3)
Technisch gesehen handelt es sich um einen 64-Bit-Hash (zwei nicht korrelierte 32-Bit-Hashes parallel), aber JavaScript ist auf 53-Bit-Ganzzahlen beschränkt. Bei Bedarf kann die vollständige 64-Bit-Ausgabe weiterhin verwendet werden, indem die Rückgabezeile für eine Hex-Zeichenfolge oder ein Array geändert wird.
Beachten Sie, dass das Erstellen von Hex-Zeichenfolgen die Stapelverarbeitung in leistungskritischen Situationen drastisch verlangsamen kann.
return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
// or
return [h2>>>0, h1>>>0];
Und nur zum Spaß, hier ist ein minimaler 32-Bit-Hash in 89 Zeichen mit höherer Qualität als sogar FNV oder DJB2:
TSH=s=>{for(var i=0,h=9;i<s.length;)h=Math.imul(h^s.charCodeAt(i++),9**9);return h^h>>>9}
ch
initialisiert?
'imul'
.
Wenn es jemandem hilft, habe ich die beiden reduce
wichtigsten Antworten zu einer Version kombiniert, die ältere Browser toleriert. Diese Version verwendet die schnelle Version, sofern verfügbar, und greift auf die Lösung von esmiralha zurück, wenn dies nicht der Fall ist.
/**
* @see http://stackoverflow.com/q/7616461/940217
* @return {number}
*/
String.prototype.hashCode = function(){
if (Array.prototype.reduce){
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
var hash = 0;
if (this.length === 0) return hash;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
Verwendung ist wie:
var hash = "some string to be hashed".hashCode();
String.prototype.hashCode = function(){ var hash = 5381; if (this.length === 0) return hash; for (var i = 0; i < this.length; i++) { var character = this.charCodeAt(i); hash = ((hash<<5)+hash)^character; // Convert to 32bit integer } return hash; }
Dies ist eine raffinierte und leistungsstärkere Variante:
String.prototype.hashCode = function() {
var hash = 0, i = 0, len = this.length;
while ( i < len ) {
hash = ((hash << 5) - hash + this.charCodeAt(i++)) << 0;
}
return hash;
};
Dies entspricht der Implementierung des Standards durch Java object.hashCode()
Hier ist auch eine, die nur positive Hashcodes zurückgibt:
String.prototype.hashcode = function() {
return (this.hashCode() + 2147483647) + 1;
};
Und hier ist eine passende für Java, die nur positive Hashcodes zurückgibt:
public static long hashcode(Object obj) {
return ((long) obj.hashCode()) + Integer.MAX_VALUE + 1l;
}
Genießen!
Ich bin ein bisschen überrascht, dass noch niemand über die neue SubtleCrypto-API gesprochen hat.
Um einen Hash aus einer Zeichenfolge abzurufen, können Sie die folgende subtle.digest
Methode verwenden:
function getHash(str, algo = "SHA-256") {
let strBuf = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest(algo, strBuf)
.then(hash => {
window.hash = hash;
// here hash is an arrayBuffer,
// so we'll connvert it to its hex version
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += ('00000000' + view.getUint32(i).toString(16)).slice(-8);
}
return result;
});
}
getHash('hello world')
.then(hash => {
console.log(hash);
});
var promise = crypto.subtle.digest({name: "SHA-256"}, Uint8Array.from(data)); promise.then(function(result){ console.log(Array.prototype.map.call(new Uint8Array(result), x => x.toString(16).padStart(2, '0')).join('')); });
crypto
ist nicht gerade performant.
Dank des Beispiels von mar10 habe ich einen Weg gefunden, die gleichen Ergebnisse in C # AND Javascript für einen FNV-1a zu erzielen. Wenn Unicode-Zeichen vorhanden sind, wird der obere Teil aus Gründen der Leistung verworfen. Ich weiß nicht, warum es hilfreich wäre, diese beim Hashing beizubehalten, da ich momentan nur URL-Pfade hashe.
C # -Version
private static readonly UInt32 FNV_OFFSET_32 = 0x811c9dc5; // 2166136261
private static readonly UInt32 FNV_PRIME_32 = 0x1000193; // 16777619
// Unsigned 32bit integer FNV-1a
public static UInt32 HashFnv32u(this string s)
{
// byte[] arr = Encoding.UTF8.GetBytes(s); // 8 bit expanded unicode array
char[] arr = s.ToCharArray(); // 16 bit unicode is native .net
UInt32 hash = FNV_OFFSET_32;
for (var i = 0; i < s.Length; i++)
{
// Strips unicode bits, only the lower 8 bits of the values are used
hash = hash ^ unchecked((byte)(arr[i] & 0xFF));
hash = hash * FNV_PRIME_32;
}
return hash;
}
// Signed hash for storing in SQL Server
public static Int32 HashFnv32s(this string s)
{
return unchecked((int)s.HashFnv32u());
}
JavaScript-Version
var utils = utils || {};
utils.FNV_OFFSET_32 = 0x811c9dc5;
utils.hashFnv32a = function (input) {
var hval = utils.FNV_OFFSET_32;
// Strips unicode bits, only the lower 8 bits of the values are used
for (var i = 0; i < input.length; i++) {
hval = hval ^ (input.charCodeAt(i) & 0xFF);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
}
utils.toHex = function (val) {
return ("0000000" + (val >>> 0).toString(16)).substr(-8);
}
Math.imul
kann es für den Multiplikationsschritt verwendet werden, wodurch die Leistung erheblich verbessert wird . Das einzige Problem ist, dass es in IE11 ohne Shim nicht funktioniert .
Ich brauchte eine ähnliche Funktion (aber anders), um eine eindeutige ID basierend auf dem Benutzernamen und der aktuellen Uhrzeit zu generieren. Damit:
window.newId = ->
# create a number based on the username
unless window.userNumber?
window.userNumber = 0
for c,i in window.MyNamespace.userName
char = window.MyNamespace.userName.charCodeAt(i)
window.MyNamespace.userNumber+=char
((window.MyNamespace.userNumber + Math.floor(Math.random() * 1e15) + new Date().getMilliseconds()).toString(36)).toUpperCase()
Produziert:
2DVFXJGEKL
6IZPAKFQFL
ORGOENVMG
... etc
edit Jun 2015: Für neuen Code verwende ich shortid: https://www.npmjs.com/package/shortid
Mein schneller (sehr langer) Einzeiler basierend auf der Multiply+Xor
Methode von FNV :
my_string.split('').map(v=>v.charCodeAt(0)).reduce((a,v)=>a+((a<<7)+(a<<3))^v).toString(16);
Ich verwende keine serverseitige Sprache, daher kann ich das nicht so machen.
Sind Sie sicher , können Sie es nicht tun , dass die Art und Weise ?
Haben Sie vergessen, dass Sie Javascript verwenden, die Sprache, die sich ständig weiterentwickelt?
Versuchen Sie es SubtleCrypto
. Es unterstützt die Hash-Funktionen SHA-1, SHA-128, SHA-256 und SHA-512.
async function hash(message/*: string */) {
const text_encoder = new TextEncoder;
const data = text_encoder.encode(message);
const message_digest = await window.crypto.subtle.digest("SHA-512", data);
return message_digest;
} // -> ArrayBuffer
function in_hex(data/*: ArrayBuffer */) {
const octets = new Uint8Array(data);
const hex = [].map.call(octets, octet => octet.toString(16).padStart(2, "0")).join("");
return hex;
} // -> string
(async function demo() {
console.log(in_hex(await hash("Thanks for the magic.")));
})();
Ich bin etwas spät zur Party, aber Sie können dieses Modul verwenden: crypto :
const crypto = require('crypto');
const SALT = '$ome$alt';
function generateHash(pass) {
return crypto.createHmac('sha256', SALT)
.update(pass)
.digest('hex');
}
Das Ergebnis dieser Funktion ist immer eine 64
Zeichenfolge. etwas wie das:"aa54e7563b1964037849528e7ba068eb7767b1fab74a8d80fe300828b996714a"
Ich habe die beiden Lösungen (Benutzer esmiralha und lordvlad) kombiniert, um eine Funktion zu erhalten, die für Browser, die die js-Funktion reduct () unterstützen, schneller sein sollte und dennoch mit alten Browsern kompatibel ist:
String.prototype.hashCode = function() {
if (Array.prototype.reduce) {
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
} else {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
};
Beispiel:
my_string = 'xyz';
my_string.hashCode();
Wenn Sie Kollisionen vermeiden möchten, können Sie einen sicheren Hash wie SHA-256 verwenden . Es gibt mehrere JavaScript SHA-256-Implementierungen.
Ich habe Tests geschrieben, um mehrere Hash-Implementierungen zu vergleichen, siehe https://github.com/brillout/test-javascript-hash-implementations .
Oder gehen Sie zu http://brillout.github.io/test-javascript-hash-implementations/ , um die Tests auszuführen.
Dies sollte ein bisschen sicherer sein als einige andere Antworten, jedoch in einer Funktion ohne vorinstallierte Quelle
Ich habe im Grunde eine minimierte vereinfachte Version von sha1 erstellt.
Sie nehmen die Bytes der Zeichenfolge und gruppieren sie nach 4 bis 32 Bit "Wörtern".
Dann erweitern wir alle 8 Wörter auf 40 Wörter (für eine größere Auswirkung auf das Ergebnis).
Dies geht zur Hashing-Funktion (der letzten Reduzierung), wo wir mit dem aktuellen Status und der Eingabe einige Berechnungen durchführen. Wir bekommen immer 4 Wörter raus.
Dies ist fast eine Ein-Befehls- / Ein-Zeilen-Version mit Map, Reduce ... anstelle von Schleifen, aber es ist immer noch ziemlich schnell
String.prototype.hash = function(){
var rot = (word, shift) => word << shift | word >>> (32 - shift);
return unescape(encodeURIComponent(this.valueOf())).split("").map(char =>
char.charCodeAt(0)
).reduce((done, byte, idx, arr) =>
idx % 4 == 0 ? [...done, arr.slice(idx, idx + 4)] : done
, []).reduce((done, group) =>
[...done, group[0] << 24 | group[1] << 16 | group[2] << 8 | group[3]]
, []).reduce((done, word, idx, arr) =>
idx % 8 == 0 ? [...done, arr.slice(idx, idx + 8)] : done
, []).map(group => {
while(group.length < 40)
group.push(rot(group[group.length - 2] ^ group[group.length - 5] ^ group[group.length - 8], 3));
return group;
}).flat().reduce((state, word, idx, arr) => {
var temp = ((state[0] + rot(state[1], 5) + word + idx + state[3]) & 0xffffffff) ^ state[idx % 2 == 0 ? 4 : 5](state[0], state[1], state[2]);
state[0] = rot(state[1] ^ state[2], 11);
state[1] = ~state[2] ^ rot(~state[3], 19);
state[2] = rot(~state[3], 11);
state[3] = temp;
return state;
}, [0xbd173622, 0x96d8975c, 0x3a6d1a23, 0xe5843775,
(w1, w2, w3) => (w1 & rot(w2, 5)) | (~rot(w1, 11) & w3),
(w1, w2, w3) => w1 ^ rot(w2, 5) ^ rot(w3, 11)]
).slice(0, 4).map(p =>
p >>> 0
).map(word =>
("0000000" + word.toString(16)).slice(-8)
).join("");
};
Wir konvertieren auch die Ausgabe in hex, um eine Zeichenfolge anstelle eines Wortarrays zu erhalten.
Die Verwendung ist einfach. zum Beispiel "a string".hash()
wird zurückkehren"88a09e8f9cc6f8c71c4497fbb36f84cd"
Ich habe mich für eine einfache Verkettung von Zeichencodes entschieden, die in Hex-Zeichenfolgen konvertiert wurden. Dies dient einem relativ engen Zweck, nämlich lediglich einer Hash-Darstellung einer SHORT-Zeichenfolge (z. B. Titel, Tags), die mit einer Serverseite ausgetauscht werden muss, die aus nicht relevanten Gründen den akzeptierten HashCode-Java-Port nicht einfach implementieren kann. Offensichtlich keine Sicherheitsanwendung hier.
String.prototype.hash = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.map.call(range, function(i) {
return self.charCodeAt(i).toString(16);
}).join('');
}
Dies kann mit Underscore knapper und browserverträglicher gemacht werden. Beispiel:
"Lorem Ipsum".hash()
"4c6f72656d20497073756d"
Ich nehme an, wenn Sie größere Zeichenfolgen auf ähnliche Weise hashen möchten, können Sie einfach die Zeichencodes reduzieren und die resultierende Summe hexifizieren, anstatt die einzelnen Zeichen miteinander zu verketten:
String.prototype.hashLarge = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.reduce.call(range, function(sum, i) {
return sum + self.charCodeAt(i);
}, 0).toString(16);
}
'One time, I hired a monkey to take notes for me in class. I would just sit back with my mind completely blank while the monkey scribbled on little pieces of paper. At the end of the week, the teacher said, "Class, I want you to write a paper using your notes." So I wrote a paper that said, "Hello! My name is Bingo! I like to climb on things! Can I have a banana? Eek, eek!" I got an F. When I told my mom about it, she said, "I told you, never trust a monkey!"'.hashLarge()
"9ce7"
Natürlich mehr Kollisionsrisiko mit dieser Methode, obwohl Sie mit der Arithmetik in der Reduzierung herumspielen könnten, aber Sie wollten den Hash diversifizieren und verlängern.
Leicht vereinfachte Version von @ esmiralhas Antwort.
Ich überschreibe String in dieser Version nicht, da dies zu unerwünschtem Verhalten führen kann.
function hashCode(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = ~~(((hash << 5) - hash) + str.charCodeAt(i));
}
return hash;
}
Fügen Sie dies hinzu, weil es noch niemand getan hat, und dies scheint viel gefragt und mit Hashes implementiert zu sein, aber es wird immer sehr schlecht gemacht ...
Dies erfordert eine Zeichenfolgeneingabe und eine maximale Anzahl, der der Hash entsprechen soll, und erzeugt eine eindeutige Zahl basierend auf der Zeichenfolgeneingabe.
Sie können dies verwenden, um einen eindeutigen Index für ein Array von Bildern zu erstellen (Wenn Sie einen bestimmten Avatar für einen Benutzer zurückgeben möchten, der zufällig ausgewählt, aber auch anhand seines Namens ausgewählt wurde, wird er immer einer Person mit diesem Namen zugewiesen ).
Sie können dies natürlich auch verwenden, um einen Index in ein Array von Farben zurückzugeben, z. B. um eindeutige Avatar-Hintergrundfarben basierend auf dem Namen einer Person zu generieren.
function hashInt (str, max = 1000) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash = hash & hash;
}
return Math.round(max * Math.abs(hash) / 2147483648);
}
Ich sehe keinen Grund, diesen überkomplizierten Kryptocode anstelle von gebrauchsfertigen Lösungen wie Objekt-Hash-Bibliotheken usw. zu verwenden. Die Abhängigkeit vom Anbieter ist produktiver, spart Zeit und reduziert die Wartungskosten.
Verwenden Sie einfach https://github.com/puleos/object-hash
var hash = require('object-hash');
hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'
var crypto = require('crypto');
. Ich denke, es fügt diesen Abhängigkeitscode des Herstellers in der minimierten Version während eines Builds hinzu.