960 Stimmen

Erzeugen eines Hash aus einem String in Javascript

Ich muss Zeichenketten in eine Form von Hash konvertieren. Ist dies in JavaScript möglich?

Ich verwende keine serverseitige Sprache, also kann ich es nicht auf diese Weise tun.

6voto

Andrew Punkte 4502

Le site Jenkins Ein Haschisch nach dem anderen ist ganz nett:

//Credits (modified code): Bob Jenkins (http://www.burtleburtle.net/bob/hash/doobs.html)
//See also: https://en.wikipedia.org/wiki/Jenkins_hash_function
//Takes a string of any size and returns an avalanching hash string of 8 hex characters.
function jenkinsOneAtATimeHash(keyString)
{
  let hash = 0;
  for (charIndex = 0; charIndex < keyString.length; ++charIndex)
  {
    hash += keyString.charCodeAt(charIndex);
    hash += hash << 10;
    hash ^= hash >> 6;
  }
  hash += hash << 3;
  hash ^= hash >> 11;
  //4,294,967,295 is FFFFFFFF, the maximum 32 bit unsigned integer value, used here as a mask.
  return (((hash + (hash << 15)) & 4294967295) >>> 0).toString(16)
};

Beispiele:

jenkinsOneAtATimeHash('test')
"31c25ec1"
jenkinsOneAtATimeHash('a')
"ca2e9442"
jenkinsOneAtATimeHash('0')
"6e3c5c6b"

Sie können auch die .toString(16) Teil am Ende, um Zahlen zu erzeugen:

jenkinsOneAtATimeHash2('test')
834821825
jenkinsOneAtATimeHash2('a')
3392050242
jenkinsOneAtATimeHash2('0')
1849449579

Beachten Sie, dass Sie, wenn Sie keine Hash-Werte benötigen, eine String o Schlüssel brauchen, sondern nur eine aus dem Nichts generierte Raute, können Sie verwenden. :

window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)

Beispiele:

window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"6ba9ea7"
window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"13fe7edf"
window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
"971ffed4"

und das gleiche wie oben, Sie können den Teil `.toString(16) am Ende entfernen, um Zahlen zu erzeugen:

window.crypto.getRandomValues(new Uint32Array(1))[0]
1154752776
window.crypto.getRandomValues(new Uint32Array(1))[0]
3420298692
window.crypto.getRandomValues(new Uint32Array(1))[0]
1781389127

Anmerkung: Sie können mit dieser Methode auch mehrere Werte auf einmal erzeugen, z. B.:

window.crypto.getRandomValues(new Uint32Array(3))
Uint32Array(3) [ 2050530949, 3280127172, 3001752815 ]

5voto

jcollum Punkte 39638

Ich brauchte eine ähnliche Funktion (aber anders), um eine eindeutige ID auf der Grundlage des Benutzernamens und der aktuellen Zeit zu generieren. Also:

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 Jul 2022: Wie @canRau anmerkt, bevorzugen die Autoren von shortid jetzt nanoid https://github.com/ai/nanoid/

3voto

Oleg Abrazhaev Punkte 2493

Ich sehe keinen Grund, diesen überkomplizierten Krypto-Code anstelle von gebrauchsfertigen Lösungen, wie z.B. einer Objekt-Hash-Bibliothek, zu verwenden. Sich auf einen Anbieter zu verlassen 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'

3voto

brillout Punkte 8542

Wenn Sie Kollisionen vermeiden wollen, sollten Sie eine sicherer Hash wie SHA-256 . Es gibt mehrere JavaScript SHA-256-Implementierungen.

Ich habe Tests geschrieben, um verschiedene 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 durchzuführen.

3voto

Frank Punkte 759

Ich habe die beiden Lösungen (Benutzer esmiralha und lordvlad) kombiniert, um eine Funktion zu erhalten, die bei Browsern, die die js-Funktion unterstützen, schneller sein sollte reduzieren() und noch mit alten Browsern kompatibel:

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();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X