Random uniek id genereren
Gepost door Enrico Pallazzo op 27-03-2010 12:33.
====[INLEIDING]====
Je herkent dit soort links vast wel: http://www.youtube.com/watch?v=5tDDpNW00iw
Hierin zit het unieke id van de video, namelijk: "5tDDpNW00iw". Maar hoe maak je zulke unieke id's nou eigenlijk?
====[WERKING SCRIPT]====
Dit script maakt het mogelijk een random uniek id te generen op basis van elk getal van 1 t/m 9007199254740992, bijvoorbeeld het unieke id van een rij in je database :-) (Oftewel, je hoeft niet te controleren of het nieuw aangemaakte unieke id daadwerkelijk uniek is.)
Daarnaast kan dit script het "random unieke id" ook weer eenvoudig converteren naar het oorspronkelijke id met de toevoeging: true.
Voorbeeld:
<?php
rand_uniqid(9007199254740989);
// heeft als returnwaarde: 'PpQXn7COf'
rand_uniqid('PpQXn7COf', true);
// heeft als returnwaarde: '9007199254740989'
?>
====[MINIMALE STRINGLENGTE]====
Wil je dat het random unieke id minimaal uit 3 tekens bestaat, gebruik dan: $pad_up = 3
====[WAAROM DIT SCRIPT]====
Omdat je je bezoekers niet wilt laten weten hoeveel rijen je in je database hebt.
Wanneer een bezoeker de volgende pagina ziet:
www.site.nl/user/235
Dan is het niet moeilijk te raden dat er ook een user 234 en misschien wel 236 is. En omdat de administrator vaak als eerste aangemaakt wordt is de kans groot dat die het userid 1 heeft. Niet handig dus.
====[rand_uniqid() VS uniqid()]====
Waarom niet uniqid() gebruiken? Omdat uniqid(), voor zover mij bekend, onmogelijk te koppelen is aan de autoincrement (database).
Met uniqid() loop je tevens de kans dat het nummer toch niet uniek in de database komt te staan (kans is astronomisch klein maar toch aanwezig).
Verder geeft uniqid() een string van 13 of 23 characters.
En "PpQXn7COf" lijkt mij beter dan "4ba67f7b18450" of "4ba67fa3d28c79.92212865"
====[BEVEILIGING]====
Je kan de volgorde van de tekens in $index aanpassen om het lastiger voor hackers te maken om een lookup script te bouwen. Je moet hiervoor een password maken maar dat is optioneel.
====[TODO]====
- Het toevoegen van een prefix en/of suffix, al dan niet random of gedefinieerd.
====[UPDATES]====
1. Tekens verwijderd uit $index: a e o u i s A E O U I S. Hiermee voorkom je dat je bijvoorbeeld je klanten een infaam en abject uniek id geeft. Denk maar eens aan wat het voor je business kan betekenen als één van je nieuwe klanten zich afvraag waarom zijn gebruikersnaam: 'penis' is.
2. Voor de liefhebbers: de OOP versie van het script: http://www.phpfreakz.nl/library.php?sid=27601
3. Voor de liefhebbers: de JS versie van het script: http://www.phpfreakz.nl/library.php?sid=27602
4. Voor de liefhebbers: de PostgreSQL versie van het script: http://www.phpfreakz.nl/library.php?sid=27606 (Met dank aan: Dieter Wijnen)
Bestanden van dit script
index.php
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <?php
function rand_uniqid($in, $to_num = false, $pad_up = false, $passKey = null)
{
$index = "bcdfghjklmnpqrtvwxyz_-0123456789BCDFGHJKLMNPQRTVWXYZ";
if ($passKey !== null) {
// Although this function's purpose is to just make the
// ID short - and not so much secure,
// you can optionally supply a password to make it harder
// to calculate the corresponding numeric ID
for ($n = 0; $n<strlen($index); $n++) {
$i[] = substr( $index,$n ,1);
}
$passhash = hash('sha256',$passKey);
$passhash = (strlen($passhash) < strlen($index))
? hash('sha512',$passKey)
: $passhash;
for ($n=0; $n < strlen($index); $n++) {
$p[] = substr($passhash, $n ,1);
}
array_multisort($p, SORT_DESC, $i);
$index = implode($i);
}
$base = strlen($index);
if ($to_num) {
// Digital number <<-- alphabet letter code
$in = strrev($in);
$out = 0;
$len = strlen($in) - 1;
for ($t = 0; $t <= $len; $t++) {
$bcpow = bcpow($base, $len - $t);
$out = $out + strpos($index, substr($in, $t, 1)) * $bcpow;
}
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$out -= pow($base, $pad_up);
}
}
$out = sprintf('%F', $out);
$out = substr($out, 0, strpos($out, '.'));
} else {
// Digital number -->> alphabet letter code
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$in += pow($base, $pad_up);
}
}
$out = "";
for ($t = floor(log($in, $base)); $t >= 0; $t--) {
$bcp = bcpow($base, $t);
$a = floor($in / $bcp) % $base;
$out = $out . substr($index, $a, 1);
$in = $in - ($a * $bcp);
}
$out = strrev($out); // reverse
}
return $out;
}
?> |


