it-swarm.com.de

Was ist der beste Weg, um einen kurzen Hash zu erstellen, ähnlich wie der kleine URL?

Ich verwende zurzeit MD5-Hashes, möchte aber etwas finden, das einen kürzeren Hash erzeugt, der nur [a-z] [A-Z] [0-9] verwendet. Es muss nur 5-10 Zeichen lang sein. 

Gibt es da draußen etwas, das dies schon macht? 

Update:

Ich mag den CRC32-Hash. Gibt es eine saubere Möglichkeit, es in .NET zu berechnen?

Update2:  

Ich verwende die CRC32-Funktion von der bereitgestellten Verknüpfung von Joe. Wie kann ich den uInt in die oben definierten Zeichen konvertieren? 

39
Arron S

Das .NET-String-Objekt verfügt über eine GetHashCode () - Funktion. Es gibt eine Ganzzahl ..__ zurück. Wandelt sie in ein Hex-Zeichen und dann in eine 8 Zeichen lange Zeichenfolge.

So wie: 

string hashCode = String.Format("{0:X}", sourceString.GetHashCode());

Mehr dazu: http://msdn.Microsoft.com/de-de/library/system.string.gethashcode.aspx

UPDATE: Zu dieser Antwort wurden die Anmerkungen des obigen Links hinzugefügt:

Das Verhalten von GetHashCode hängt von seiner Implementierung ab, die ändert sich möglicherweise von einer Version der Common Language Runtime in Ein weiterer. Ein Grund, warum dies passieren kann, ist die Verbesserung der Leistung von GetHashCode.

Wenn zwei Zeichenfolgenobjekte gleich sind, gibt die GetHashCode-Methode .__ zurück. identische Werte. Es gibt jedoch keinen eindeutigen Hash-Code-Wert für jeder eindeutige String-Wert. Verschiedene Strings können denselben Hash zurückgeben Code.

Notizen an Anrufer

Der von GetHashCode zurückgegebene Wert ist plattformabhängig. Es unterscheidet sich von die 32-Bit- und 64-Bit-Versionen von .NET Framework.

45
Vlad

Ist es Ihr Ziel, einen URL-Shortener oder eine Hash-Funktion zu erstellen?

Wenn Sie ein URL-Shortener erstellen möchten, benötigen Sie keine Hash-Funktion. In diesem Fall möchten Sie lediglich eine Folge von kryptografisch sicheren Zufallszahlen generieren und dann jeder URL eine eindeutige Nummer aus der Folge zuweisen.

Sie können dies mit Code wie folgt tun:

using System.Security.Cryptography;

const int numberOfNumbersNeeded = 100;
const int numberOfBytesNeeded = 8;
var randomGen = RandomNumberGenerator.Create();
for (int i = 0; i < numberOfNumbersNeeded; ++i)
{
     var bytes = new Byte[numberOfBytesNeeded];
     randomGen.GetBytes(bytes);
}

Die Verwendung des kryptografischen Zahlengenerators macht es sehr schwierig, die von Ihnen generierten Zeichenfolgen vorherzusagen, was für Sie wichtig ist.

Sie können dann die 8-Byte-Zufallszahl mithilfe der Buchstaben in Ihrem Alphabet in einen String konvertieren. Dies ist im Wesentlichen eine Änderung der Basisberechnung (von Basis 256 zu Basis 62). 

34

Ich glaube nicht, dass URL-Verkürzungsdienste Hashes verwenden, ich glaube, sie haben nur eine laufende alphanumerische Zeichenfolge, die mit jeder neuen URL erhöht und in einer Datenbank gespeichert wird .. Wenn Sie wirklich eine Hash-Funktion verwenden müssen, schauen Sie sich diesen Link an: einige Hashfunktionen Auch ein bisschen offtopic, aber je nachdem, woran Sie arbeiten, könnte dies interessant sein: Coding Horror article

16
jörg

Nehmen Sie einfach eine Base36 (ohne Berücksichtigung der Groß- und Kleinschreibung) oder Base64 der ID des Eintrags.

Also, sagen wir, ich wollte Base36 verwenden:

(ID - Base36)
1 - 1
2 - 2
3 - 3
10 A
11 - B
12 - C
...
10000 - 7PS
22000 - GZ4
34000 - Q8C
...
1000000 - LFLS
2345000 - 1E9EW
6000000 - 3KLMO 

Sie könnten diese sogar noch kürzer halten, wenn Sie mit base64 arbeiten, aber die URL berücksichtigt die Groß- und Kleinschreibung. Sie sehen, dass Sie immer noch Ihren schönen, ordentlichen alphanumerischen Schlüssel erhalten und mit der Garantie, dass es keine Kollisionen gibt!

11
KingNestor

Sie können keinen short - Hash verwenden, da Sie eine 1: 1-Zuordnung von der Kurzversion zum tatsächlichen Wert benötigen. Für einen kurzen Hash wäre die Chance für eine Kollision viel zu hoch. Normale, lange Hashes wären nicht sehr benutzerfreundlich (und selbst wenn die Wahrscheinlichkeit einer Kollision wahrscheinlich klein genug wäre, fühle ich mich trotzdem nicht "richtig").

TinyURL.com scheint eine inkrementierte Zahl zu verwenden, die in Base 36 (0-9, A-Z) umgewandelt wird.

7
Arjan

Zuerst bekomme ich eine Liste mit zufälligen Zahlen. Dann wähle ich jedes char aus dem Basisstring aus, füge das Ergebnis hinzu und gebe es zurück. Ich wähle 5 Zeichen aus, was 6471002 Permutationen aus der Basis 62 ergeben wird. Der zweite Teil ist das Überprüfen mit DB, um zu sehen, ob eine vorhanden ist, wenn nicht, dann kurze URL speichern.

 const string BaseUrlChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

 private static string ShortUrl
 {
     get
     {
         const int numberOfCharsToSelect = 5;
         int maxNumber = BaseUrlChars.Length;

         var rnd = new Random();
         var numList = new List<int>();

         for (int i = 0; i < numberOfCharsToSelect; i++)
             numList.Add(rnd.Next(maxNumber));

         return numList.Aggregate(string.Empty, (current, num) => current + BaseUrlChars.Substring(num, 1));
      } 
  }
3

Sie können die Anzahl der Zeichen aus dem MD5-Hash verringern, indem Sie sie als alphanumerische Zeichen kodieren. Jedes MD5-Zeichen wird normalerweise als Hexadezimal dargestellt, dh es sind 16 mögliche Werte. [a-zA-Z0-9] enthält 62 mögliche Werte, sodass Sie jeden Wert mit 4 MD5-Werten kodieren können.

BEARBEITEN:

hier ist eine Funktion, die eine Zahl (4 Hex-Ziffern lang) verwendet und [0-9a-zA-Z] zurückgibt. Dies sollte Ihnen eine Vorstellung davon geben, wie Sie es implementieren können. Beachten Sie, dass möglicherweise Probleme mit den Typen auftreten. Ich habe diesen Code nicht getestet.

char num2char( unsigned int x ){
    if( x < 26 ) return (char)('a' + (int)x);
    if( x < 52 ) return (char)('A' + (int)x - 26);
    if( x < 62 ) return (char)('0' + (int)x - 52);
    if( x == 62 ) return '0';
    if( x == 63 ) return '1';
}
3
Colin

Sie können CRC32 verwenden, es ist 8 Byte lang und ähnelt MD5. Eindeutige Werte werden durch Hinzufügen eines Zeitstempels zum tatsächlichen Wert unterstützt. 

So wird es aussehen wie http://foo.bar/abcdefg12 .

2
Joe

Wenn Sie nach einer Bibliothek suchen, die winzige eindeutige Hashes aus Inters generiert, kann ich http://hashids.org/net/ wärmstens empfehlen. Ich verwende es in vielen Projekten und es funktioniert fantastisch. Sie können auch Ihren eigenen Zeichensatz für benutzerdefinierte Hashes angeben.

2
herostwist

Sie können Ihren md5-Hashcode mit base64 anstelle von hexadezimal codieren. Auf diese Weise erhalten Sie eine kürzere URL, die genau die Zeichen [a-z] [A-Z] [0-9] verwendet.

0
codymanix

Es gibt ein wundervolles, aber altes Programm namens btoa , das Binärzeichen in ASCII mit Groß- und Kleinbuchstaben, Ziffern und zwei zusätzlichen Zeichen konvertiert. Es gibt auch die MIME base64-Codierung. Die meisten Linux-Systeme haben wahrscheinlich ein Programm namens base64 oder base64encode. Entweder würden Sie eine kurze, lesbare Zeichenfolge aus einem 32-Bit-CRC erhalten.

0
Norman Ramsey

Wenn Sie sich nicht für die kryptografische Stärke interessieren, werden alle CRC-Funktionen verwendet.

Wikipedia listet eine Reihe verschiedener Hash-Funktionen auf, einschließlich der Länge der Ausgabe. Das Umwandeln ihrer Ausgabe in [a-z] [A-Z] [0-9] ist trivial.

0
Kevin Montrose