Autor Zpráva
tazatel
Profil *
Potřeboval bych v rámci webu nějak pojmenovávat soubory, které se tam budou dohrávat. Tzn. generovat unikátní řetězec, dlouhý řekněme 5 nebo 6 znaků. Existuje efektivnější způsob vygenerování názvu, než náhodný řetězec a pak ověření, jestli už v databázi není?
Všiml jsem si, že jste tady postavili jakési pískoviště, kde jednotlivé experimenty máte pojmenované stejným způsobem, tak mě napadlo se zeptat.
juriad
Profil
tazatel:
Tady v kod.djpw.cz se prostě inkrementuje řetězec.
Aktuálně poslední je http://kod.djpw.cz/ngeb, další bude ogeb, pgeb, qgeb, rgeb atd. až zgeb, aheb, ..., zheb, aieb, ...

Unikátní třeba bývá čas + číslo procesu.

Nebo můžeš použít to co již PHP obsahuje:
http://www.php.net/manual/en/function.tmpfile.php
http://www.php.net/manual/en/function.tempnam.php
Bubák
Profil
tazatel:
Jak napsal juriad, „v kod.djpw.cz se prostě inkrementuje řetězec“. Nevýhodou takového řešení je, že URL stránky/souboru jde snadno odhalit (pozor, "tajná", neuhádnutelná adresa není vhodný způsob, jak ochránit důvěrné stránky/soubory), výhodou je jednoduchá implementace.
Joker
Profil
tazatel:
Existuje efektivnější způsob vygenerování názvu, než náhodný řetězec a pak ověření, jestli už v databázi není?
Použít číselnou řadu.
Stačí si pamatovat poslední použité číslo a zvýšit ho o 1. Kdyby vadilo, že názvy souborů budou odhadnutelné, dá se k tomu přidat pár náhodných znaků.

Nebo místo čísel inkrementovat řetězec, jak píše juriad, tam kratší řetězec pokryje mnohem víc souborů (když se použije 0-9 a a-z, je to de facto 36-ková soustava, čtyři znaky stačí na víc než 1,6 milionu souborů)

Další možnost je použít aktuální čas.
Triviální metoda by byla vzít aktuální timestamp, odečíst nějakou konstantu (abychom neměli tak vysoké číslo) a převést to na hexadecimální číslo (aby to bylo kratší).
Výhodou je jednoduchost a nemusí se nikde držet stav žádného počítadla.
Nevýhodou je postupné „spotřebovávání“ hodnot i když se žádné soubory neukládají. Velikost čísla není závislá na počtu souborů, ale na uplynulém čase.
Sedmimístná čísla (když se začne od „0000000“) vystačí zhruba na 8 let, osmimístná na více než 127 let.
Taky je nutné řešit situaci, kdy se dva soubory mají uložit v kratším intervalu než sekunda. Takže to není vhodné pro použití, kdy se ukládá více souborů naráz, spíš pro použití, kdy se ukládá čas od času vždy jeden soubor.
tazatel
Profil *
Bubák:
Ano, to je v mém případě součást zadání. Nepotřebuju vyloženě, aby obrázky nebylo možné dohledat, ale nechtěl bych, aby napsání robota pro stažení všech trvalo 10 minut.
juriad
Profil
Nebo jednoduše vypočítej hash (třeba sha1) názvu souboru spojeného s aktuálním časem (třeba v sekundách), ten bude hexadecimální a můžeš si ho oříznout třeba na 6 znaků. Kdybys náhodou vyhrál loterii (tedy nastala kolize), tak to zkusíš znovu s časem + 1, +2, +3. A kdyby to v několika málo (~10) pokusech nikdy nevyšlo, prostě soubor odmítneš s omluvou.
Nepíšeš přece nikterak kritickou aplikaci, ve které k chybě nesmí dojít.

Ve svém gitovém repozitory mám 14198 objektů a když se podívám na hashe (čtyřicetiznakové), tak unikáních prefixů oseknutých na několik málo znaků je:
  počet | délka
   1495 | 5 # 1495 souborům stačí pro jednoznačné určení prvních 5 znaků z 40
   8785 | 6
   1380 | 7
     83 | 8
      6 | 9
      2 | 10 # dva soubory lze od sebe rozlišit až 10. znakem
Tedy pro 15000 souborů mi stačí prvních 8 znaků s tím, že 8 souborů na první pokus nepůjde uložit.
tazatel
Profil *
juriad:
Nepíšeš přece nikterak kritickou aplikaci, ve které k chybě nesmí dojít.

To je sice pravda, ale na druhou stranu není vůbec žádný důvod, aby k nějaké chybě došlo. Jde mi spíš o optimalizaci té akce, kde optimální rovná se rychlé a zároveň přehledné v kódu, abych to nějak složitě nedešifroval, až to budu potřebovat příště někde jinde a trochu jinak.

Zatím mám při vší úctě pocit, že zůstanu u svého řešení, tzn. vygeneruju náhodný 6znakový string, ověřím proti databázi a budu to dělat tak dlouho, dokud ho budu nacházet. Číslo 36^6 mi dává značnou šanci, že k třetímu pokusu bude docházet jen velmi vyjímečně.
Bubák
Profil
tazatel:
Číslo 36^6 mi dává značnou šanci
Můžeš přidat i VeLKá píSmENA ;-)
aDAm
Profil
Nebo ještě přihodím funkci uniqid která generuje unikátní identifikátor.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: