Tools.php a revizia 98
- David Grudl
- Nette Core | 8218
- pmg
- Člen | 372
Uniqid
je vhodná funkce pro generování jedinečných názvů
souborů. Je navržena tak, aby nikdy nevrátila stejný výstup. Pokud se
použije volitelný parametr more_entropy
, přidá se do výstupu
ještě hodnota z LCG. Ten
je inicializován opět časem a především číslem procesu, takže se
stejný výstup nevrátí ani ve dvou souběžných procesech.
I když výstup funkce uniqid
vypadá jako těžko uhodnutelná
hodnota, ve skutečnosti jde o hexadecimálně vyjádřený čas v
µs spojený s hodnotou LCG. Pokud známe přibližný čas požadavku, funkce
nám nabídne jen pár bytů entropie.
Na Linuxu máme pro generování těžko uhodnutelných identifikátorů
soubor /dev/urandom
. V ostatních případech považuji za
nejlepší použít mt_rand
s opakovanou inicializací. Během
průchodu cyklem uplyne nějaký čas, takže se nám do výsledku vnáší
entropie. Funkce mt_srand
kromě přesného času a čísla procesu
používá i LCG. Marsennee Twister
potom výsledek pěkně zamíchá, takže už pak není nutné používat
md5
.
Osobně bych funkci Tools::uniqueId
uvítal. Takto nějak bych
si ji představoval:
function get_unique_id($length = 16, $binary = FALSE) {
$s = '';
$fp = @fopen('/dev/urandom', 'r');
if ($fp) {
$s = fread($fp, $length);
fclose($fp);
$length -= strlen($s);
}
if ($length > 0) {
$size = floor(log(mt_getrandmax(), 256));
do {
mt_srand();
$s .= substr(pack('V', mt_rand()), 0, min($size, $length));
$length -= $size;
} while ($length > 0);
}
return $binary ? $s : bin2hex($s);
}
var_dump(get_unique_id());
Je možné použít i base_convert($s, 16, 36)
, ale pozor, že
to potom nevrací konstantně dlouhý výstup. Asi by proto bylo lepší nechat
volitelnou délku, povolit binární výstup a případnou konverzi nechat na
uživateli.
- David Grudl
- Nette Core | 8218
Ta funkce je bohužel pevně spojena s konkrétním typem operačního systému.
- pmg
- Člen | 372
Děkuji za odpověď, ale nevím, jestli ti dobře rozumím. Funkce zkusí
použít soubor /dev/urandom
, a pokud není k dispozici,
vygeneruje řetězec pomocí mt_rand
. Tím pevným spojením s OS
je myšleno, že se ten soubor vůbec zkouší?
Původně jsem chtěl varovat, že identifikátor generovaný pomocí
uniqid
nemusí být bezpečný. Protože se ale na pár řádků
dá napsat funkce, která vrátí bezpečnější řetězec, napadlo mě, proč
by nemohla být v Nette\Tools
. Kód jsem uváděl jen jako
příklad, jak by to šlo řešit.
Je pravda, že většinou je bezpečný identifikátor potřeba pro session, kde s tím není problém. Může se to ale hodit, když se ten klíč má uložit do databáze, poslat na email ap.
Jestli je třída Nette\Tools
zamýšlena jinak, tak na
implementaci netrvám;-)
Edit: Jestli myslíte, že to nenajde využití nebo že
lcg_value
stačí, tak také ne.
Editoval pmg (22. 11. 2008 18:08)
- David Grudl
- Nette Core | 8218
pmg napsal(a):
Děkuji za odpověď, ale nevím, jestli ti dobře rozumím. Funkce zkusí použít soubor
/dev/urandom
, a pokud není k dispozici, vygeneruje řetězec pomocímt_rand
. Tím pevným spojením s OS je myšleno, že se ten soubor vůbec zkouší?
Ano, navíc na Windows to může otevřít např.
C:\dev\urandom
.
Původně jsem chtěl varovat, že identifikátor generovaný pomocí
uniqid
nemusí být bezpečný. Protože se ale na pár řádků dá napsat funkce, která vrátí bezpečnější řetězec, napadlo mě, proč by nemohla být vNette\Tools
. Kód jsem uváděl jen jako příklad, jak by to šlo řešit.
Ten rozbor je fajn, určitě je dobré vědět, co jednotlivé funkce generují, že uniqid() není vhodný pro generování neuhodnutelných jmen. Ale lepší generátor do frameworku (alespoň zatím) přidávat nechci, protože podobná funkce je potřeba velmi zřídka.
- pmg
- Člen | 372
Jen nechci další generátor přidávat do frameworku – lepší je pochopi a využít existující.
Děkuji, že se mnou polemizuješ, a mrzí mě, že se tentokrát neshodneme:-( Myslím, že v PHP nelze jednoduše vygenerovat bezpečný identifikátor požadované délky a formátu. Framework by tu rutinu mohl usnadnit.
Nikdo jiný na téma nereagoval, takže asi nemá cenu se tím zabývat.
- romansklenar
- Člen | 655
Já bych byl taky pro usnadnění této rutiny. Ale je taky na druhou stranu pravda, že člověk by měl chápat jak to pracuje a ne to jen tupě využívat.
- pmg
- Člen | 372
Já bych byl taky pro usnadnění této rutiny.
Jde nám to dobře, ale prozatím trochu zmírněme. David zřejmě vytušil, že po generátoru identifikátorů bude následovat ještě generátor obsahu stránek, tzv. autocopywriter. O generátoru kapitálu proto teď radši pomlčme.
Nette\Tools rulezzz!
- ViliamKopecky
- Nette hipster | 230
pmg napsal(a):
Já bych byl taky pro usnadnění této rutiny.
Jde nám to dobře, ale prozatím trochu zmírněme. David zřejmě vytušil, že po generátoru identifikátorů bude následovat ještě generátor obsahu stránek, tzv. autocopywriter. O generátoru kapitálu proto teď radši pomlčme.
Nette\Tools rulezzz!
offtopic…
Bohužel na generátor obsahu stránek mají už zřejmě patent lidé z blog.cz ;)
- pmg
- Člen | 372
Nette na mě působí jako framework, který si klade za cíl poskytnout především kvalitní základ pro libovolnou aplikaci; tedy ne knihovny pro řešení všechmožných úkolů. Pokud budeme vycházet z této myšlenky, někde se ta hranice stanovit musí. Jsou ale funkce, které se těžko zařadí do nějaké třídy. Tato by se dala zkrátit na pár řádků. Leda ji pak dát přímo do nějaké aplikované třídy, ale já jsem od začátku myslel, že využití bude častější.
Snad nejsem ovlivněnej tím, že dělám web pro Sazka, a.s.
- romansklenar
- Člen | 655
pmg napsal(a):
Pokud budeme vycházet z této myšlenky, někde se ta hranice stanovit musí.
Právě zde by mohlo přijít ke slovu nette-extras
.