2009-12-10 10 views
6

Ich habe ein Skript, um in Base 62 (A-Za-z0-9) zu konvertieren, aber wie bekomme ich eine Nummer aus MD5?Konvertieren MD5 in Base62 für URL

Ich habe an vielen Stellen gelesen, dass, weil die Zahl von einem MD5 größer ist als php als Ganzzahl behandelt werden kann, wird es ungenau sein ... Da ich sowieso eine kurze URL möchte und nicht den ganzen Hash verwenden wollte, vielleicht nur 8 Zeichen davon ....

Also meine Frage ist, wie man Teil der Nummer eines MD5-Hashes bekommen?

Ist es auch eine schlechte Idee, nur einen Teil des MD5-Hash zu verwenden?

+0

md5 hash ist keine nummer, also was meinst du mit "teil der nummer"? –

+5

md5 ist eine Zahl in Base36 Codierung vertreten dachte ich ... – Mark

+1

Sie sind halb richtig, ein MD5-Hash ist eine Hex-Zahl in der Basis 16 (a-f0-9) dargestellt. –

Antwort

6

Ich werde hier eine andere Sache vorschlagen .. Da Sie nur daran interessiert sind, eine Dezimalstelle des MD5-Hash verwenden, warum verwenden Sie keine anderen kurzen numerischen Hash wie CRC32 oder Adler? Hier ein Beispiel:

$hash = sprintf('%u', crc32('your string here')); 

Dies wird einen 8-stelligen Hash Ihrer Zeichenfolge erzeugen.

EDIT: Ich glaube, ich habe dich missverstanden, here are some functions that provide conversions to and from bases up to 62.

EDIT (Wieder): mit beliebiger Länge Zahlen arbeiten zu können, entweder die bc_math oder die GMP-Erweiterung verwenden müssen, here is a function that uses the bc_math extension and can also convert from base 2 up to base 62. Sie sollten es wie folgt verwenden:

echo bc_base_convert(md5('your url here'), 16, 62); // public base 62 hash 

und die inverse:

echo bc_base_convert('base 62 encoded value here', 62, 16); // private md5 hash 

Hoffe, es hilft. =)

+0

ist es möglich herauszufinden, was in den Hash ging? Ich denke nur, wenn ich immer nur einen Teil eines Haschs zeige, muss es schwieriger sein zu trainieren, wie es erzeugt wurde ... richtig? – Mark

+0

Richtig, aber dann wäre es kein Hash im wahrsten Sinne des Wortes, auch Kollisionen sind viel wahrscheinlicher. –

1

Sie können dies wie folgt aus:. (Nicht alle Schritte in php, es ist eine lange Zeit gewesen ist, dass ich es benutzt habe)

  • erstellen MD5-Hash des Skripts wie folgt aus :

    $ hash = md5 (Skript, raw_output = true);

  • konvertieren, die Nummer 62.

    Sehen Sie sich die Fragen zu base conversion of arbitrary sized numbers in PHP

  • Kürzt die Zeichenfolge auf eine Länge, die Sie gerne stützen.

Es gibt kein Risiko, nur ein paar der Bits eines md5 in Verwendung. Alles was sich ändert, ist die Gefahr von Zusammenstößen.

+0

Netter Link, danke. –

0

Sie könnten eine leicht modifizierte Base 64 mit - verwenden und _ statt + und /:

function base64_url_encode($str) { 
    return strtr(base64_encode($str), array('+'=>'-', '/'=>'_')); 
} 
function base64_url_decode($str) { 
    return base64_decode(strtr($str, array('-'=>'+', '_'=>'/'))); 
} 

Zusätzlich erhalten Sie die hintere Polsterung = Zeichen entfernen konnte.

Und den rohen MD5-Wert (Binärkette) zu erhalten, setzen Sie den zweiten Parameter zu wahr ($raw_output im Handbuch genannt):

$raw_md5 = md5($str, true); 
+0

überprüfen Sie diese http://stackoverflow.com/questions/352434/base-conversion-of-arbitrary-sized-numbers-php/1743486#1743486 –

+0

Was ist los? Warum die Down-Abstimmung? – Gumbo

3

Wenn es möglich ist, würde ich nicht raten, eine mit Hash für Ihre URLs. Irgendwann werden Sie in Kollisionen geraten ... besonders wenn Sie den Hash abschneiden. Wenn Sie ein ID-basiertes System implementieren, bei dem jedes Element eine eindeutige ID hat, gibt es weitaus weniger Probleme. Das erste Element wird 1 sein, das zweite wird 2 usw. sein. Wenn Sie MySQL verwenden, werfen Sie einfach eine Autoinkrement-Spalte ein.

Um eine kurze ID zu machen:

//the basic example 
$id = base_convert($id, 36, 10); 

//if you're going to be needing 64 bit numbers 
//on a 32 bit machine, use this instead 
$id = gmp_strval(gmp_init($shortid, 36)); 

this helps:

//the basic example 
$sid = base_convert($id, 10, 36); 

//if you're going to be needing 64 bit numbers converted 
//on a 32 bit machine, use this instead 
$sid = gmp_strval(gmp_init($id, 10), 36); 

Um eine kurze ID zurück in die Basis-10-ID zu machen!

Wenn Sie wirklich wollen, Basis 62 (die nicht mit gmp oder base_convert getan werden kann), check this out: http://snipplr.com/view/22246/base62-encode--decode/

+0

GMP, netter! =) –

+0

Sorry vielleicht habe ich mich nicht klar genug gemacht, die MD5 funktioniert nicht als ID ... nur als eine Möglichkeit, einen Benutzer zu stoppen, die nächste URL zu erraten ... also ist die URL id = 1 & md5 = dsf213sfe. Danke trotzdem – Mark

+0

Fair genug! Mein Fehler. Stört mich nicht :) – brianreavis

0

Sie können so etwas tun,

$hash = md5("The data to be hashed", true); 
$ints = unpack("L*num", $hash); 

$hash_str = base62($ints['num1']) . base62($ints['num2']) . base62($ints['num3']) . base62($ints['num4']) 
0

Es eigentlich ist eine Java-Implementierung, die Sie wahrscheinlich extrahieren könnten. Es ist eine Open-Source-CMS-Lösung namens Pulse.

Suchen Sie hier nach dem Code toBase62() und fromBase62().

http://pulse.torweg.org/javadoc/src-html/org/torweg/pulse/util/StringUtils.java.html

Die einzige Abhängigkeit in StringUtils ist die LifeCycle-Klasse, die eine Möglichkeit bietet, eine gesalzene Hash für eine Zeichenfolge zu erhalten, die Sie auch alle zusammen weglassen könnte oder einfach nur die Methode kopieren StringUtils auf Ihre Kopie über. Voilá.

0

Ab PHP 5.3.2 unterstützt GMP Basen bis zu 62 (war vorher nur 36), also Brianreavis Vorschlag war sehr nahe. Ich denke, die einfachste Antwort auf Ihre Frage ist also:

Umwandlung von Base-16 zu Base-62 hat offensichtlich Raumvorteile. Ein normaler 128-Bit-MD5-Hash ist 32 Zeichen in Hex, aber in Basis-62 ist es nur 22. Wenn Sie die Hashes in einer Datenbank speichern, können Sie sie in Raw-Binär konvertieren und noch mehr Speicherplatz sparen (16 Byte für ein MD5).

Da der resultierende Hash nur eine String-Repräsentation ist, können Sie nur substr verwenden, wenn Sie nur ein bisschen davon wollen (wie die Funktion).

0

Sie können versuchen, base62x eine sichere und kompatible codierte Darstellung zu erhalten.

Here is for more information about base62x oder einfach -base62x in -NatureDNS.

shell> ./base62x -n 16 -enc 16AF 
1Ql 
shell> ./base62x -n 16 -dec 1Ql 
16AF 

shell> ./base62x 
Usage: ./base62x [-v] [-n <2|8|10|16|32>] <-enc|dec> string 
Version: 0.60