9 Stimmen

Ist die Verwendung einer Teilzeichenkette eines MD5-Hashes wie dieser eindeutig genug?

Ich versuche, eine 12-Zeichen-ID für Artikel auf meiner Website zu erstellen, ähnlich wie youtube seine Video-ID handhabt ( http://www.youtube.com/watch?v=53iddd5IcSU ). Im Moment generiere ich einen MD5-Hash und greife dann wie folgt auf 12 Zeichen zu:

$ArticleId = substr(MD5("Article".$currentID),10,12)

wobei $currentID die numerische ID aus der Datenbank ist (z. B. 144)

Ich bin etwas paranoid, dass ich in eine doppelte $ArticleId laufen, aber realistisch, was sind die Chancen, dass dies geschehen wird? Und da die Spalte in meiner Datenbank eindeutig ist, wie kann ich dieses seltene Szenario behandeln, ohne dass ein hässlicher Fehler ausgelöst wird?

P.S. Ich habe ein kleines Skript erstellt, um innerhalb der ersten 5000 $ArticleId's nach Duplikaten zu suchen und es gab keine.

EDIT: Ich mag es nicht, wie die base64_encode Hashes aussehen, also habe ich dies getan:

function retryAID($currentID)
{
    $AID = substr(MD5("Article".$currentID*2),10,12);

    $setAID = "UPDATE `table` SET  `artID` =  '$AID' WHERE `id` = $currentID ";
    mysql_query($setLID) or retryAID($currentID);
}

$AID = substr(MD5("Article".$currentID),10,12);

$setAID = "UPDATE `table` SET  `artID` =  '$AID' WHERE `id` = $currentID ";
mysql_query($setAID) or retryAID($currentID);

Da die AID-Spalte eindeutig ist, wird die mysql_query einen Fehler auslösen und die Funktion retryAID wird eine eindeutige ID finden...

6voto

Bill the Lizard Punkte 384619

Was ist falsch daran, eine fortlaufende ID zu verwenden? Die Datenbank wird dies für Sie übernehmen.

Davon abgesehen sind 12 Zeichen immer noch 96 Bit. 2 96 \= 79228162514264337593543950336 mögliche Hashes. Auch wenn MD5 bekanntermaßen kollisionsgefährdet ist, gibt es einen großen Unterschied zwischen dem Möglichkeit einer Kollision und der Wahrscheinlichkeit einen zu sehen.

Aktualisierung:

Basierend auf dem Rückgabewert der PHP md5 Funktion, die Sie verwenden, sind meine obigen Zahlen nicht ganz richtig.

Gibt den Hash als 32-stellige hexadezimale Zahl zurück.

Da Sie 12 Zeichen aus einer 32-Zeichen-Hexadezimalzahl nehmen (und nicht 12 Bytes des 128-Bit-Hashes), beträgt die tatsächliche Anzahl der möglichen Hashes, die Sie erhalten könnten, 16 12 \= 281474976710656. Immer noch eine ganze Menge.

1voto

Matthew Punkte 46409
<?php
  function get_id()
  {
    $max = 1679615; // pow(36, 4) - 1;
    $id = '';

    for ($i = 0; $i < 3; ++$i)
    {
      $r = mt_rand(0, $max);
      $id .= str_pad(base_convert($r, 10, 36), 4, "0", STR_PAD_LEFT);
    }
    return $id;
  }
?>

Gibt eine 12-stellige Zahl zur Basis-36 zurück, was 4.738.381.338.321.616.896 Möglichkeiten ergibt. (Die Wahrscheinlichkeit einer Kollision hängt von der Verteilung des Zufallszahlengenerators ab).

Um Kollisionen zu vermeiden, müssen Sie eine Schleife bilden:

<?php
do {
  $id = get_id();
} while ( !update_id($id) );
?>

0voto

Louis Punkte 4072

Nein, nicht sehr einzigartig.

Warum nicht base64 kodieren, wenn Sie es kürzer brauchen?

0voto

dschulz Punkte 4476

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