Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Funkcje haszujace i unikalny identyfikator
Forum PHP.pl > Forum > PHP
Sekwer
Witam, zastanawiam się nad generowaniem unikalnego identyfikatora o jak najkrótszym łańcuchu znaków. Szukałem na forum i nie znalazłem odpowiedniego tematu. Moją uwage zwróciło kilka funkcji.

CRC32
ADLER32
uniqid() (funkcja w php)

Nie chodzi tu o szyfrowanie haseł, a o budowanie krótkich linków czy krótkich nazw plików.
Która funkcje byście polecali?

PS Swoja droga ciekawe jakie jest prawdopodobieństwo kolizji. Myślę, że do takich zastosowań jak nazwy plików się nada smile.gif
darophp
MD5 masz długie, albo SHA
Sekwer
Znam te funkcje skrótu. Bardziej chodzi mi o wygenerowanie jak najkrótszego identyfikatora. 8 znaków to co udało mi się uzyskać i chyba jak na razie to wszystko.
8 znaków jako liczba heksdecymalna smile.gif
croc
Ja bym skorzystał mimo wszystko z md5, tylko wyciął z niego np. losowo 8 znaków.

  1. $hash = md5(time() . '-' . rand(0, 1000));
  2. $hash = substr($hash, rand(0, 24), 8);


I zabezpieczyłbym się przed kolizjami, np. tak (jeżeli chodzi o unikalne nazwy plików, analogicznie możesz zrobić np. wyszukiwanie po hashu z bazy danych):

  1. do {
  2. $hash = md5(time() . '-' . rand(0, 1000));
  3. $hash = substr($hash, rand(0, 24), 8);
  4. }
  5. while(file_exists('pliki/' . $hash . '.txt'));
Sekwer
Cytat(croc @ 13.05.2010, 09:28:10 ) *
Ja bym skorzystał mimo wszystko z md5, tylko wyciął z niego np. losowo 8 znaków.

  1. $hash = md5(time() . '-' . rand(0, 1000));
  2. $hash = substr($hash, rand(0, 24), 8);


I zabezpieczyłbym się przed kolizjami, np. tak (jeżeli chodzi o unikalne nazwy plików, analogicznie możesz zrobić np. wyszukiwanie po hashu z bazy danych):

  1. do {
  2. $hash = md5(time() . '-' . rand(0, 1000));
  3. $hash = substr($hash, rand(0, 24), 8);
  4. }
  5. while(file_exists('pliki/' . $hash . '.txt'));


Twoje rozwiązanie nie jest profesjonalne.

BTW Po co mam robić dodatkowe zapytanie do bazy o klucz?

Moje rozwiązanie musi działać bez bazy, ponieważ raz mogę mieć bazę w projekcie a raz nie.

Wydaje mi się, ze nie da się zejść poniżej 8 znaków, mówią to proste obliczenia matematyczne jeżeli haszem jest liczba heksadecymalna.

Pozdrawiam smile.gif

PS Łatwo chyba zapamiętać 8 znaków yahoo.gif
croc
Albo ni w pytkę nie wiem o co ci chodzi, albo nie umiesz czytać ze zrozumieniem. Chyba to drugie.
Sekwer
Skoro nie zastanawiasz się nad tym co piszesz to już twój problem.

Nie można wybierać losowych znaków z innego hasha md5 bo jest duże prawdopodobieństwo kolizji.

Naucz się podstaw PHP i kryptografii i dopiero się wypowiadaj.
croc
Ty się naucz lepiej praktycznego podejścia do sprawy, panie "liczba heksdecymalna".
erix
Dość.

Jakiekolwiek przepychanki w tym temacie i polecą warny.
jaslanin
wg mnie hasz nie służy do tego by generować unikalne kody w takim sensie jak Ty to opisujesz. Zastosowaniem hasza są funkcje skrótu, potwierdzanie autentyczności danych itd.

Powiedzmy że mamy hasz: xxxx gdzie x to znaki z zakresu [0-9], masz wtedy 10000 możliwych kodów.
W przypadku md5 jest to 16^32 = 3.40282367 × 10^38 (ponieważ md5 to znaki z zakresu [0-9,a-f]), jest to ileś tam razy więcej możliwości więc prawdopodobieństwo powtórzenia w md5 jest znikome dzięki temu.
Chodzi mi o to że na x znakach możesz mieć skończoną liczbę możliwości.

proponuję byś pocztytał manual php, dokładnie: http://www.php.net/manual/en/function.base-convert.php#52450, zapoznał się z różnymi pomysłami i wybrał.

Ja to robię tak, dodaje te zdjęcia/linki do bazy danych, robię klucz główny z AI potem używam funkcji do której podałem linka na id
np. na dwóch znakach mam 3844(62^2) możliwości, na 3 znakach już 238 328 (62^3) itd.
Alfabet w tym przypadku to: [0-9,a-z,A-Z], więc przyjemny myślę smile.gif

Obrazowy przykład:
Kod
<?php

function dec2any( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base );
    }
    $out = "";
    for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {
        $a = floor( $num / pow( $base, $t ) );
        $out = $out . substr( $index, $a, 1 );
        $num = $num - ( $a * pow( $base, $t ) );
    }
    return $out;
}

function any2dec( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );
    }
    $out = 0;
    $len = strlen( $num ) - 1;
    for ( $t = 0; $t <= $len; $t++ ) {
        $out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
    }
    return $out;
}

/*for ($i=1; $i<62*62+5; ++$i) {
    echo dec2any($i);
    echo"<BR>";
}*/

$test = 3844;

echo dec2any($test);
echo "<br>";
echo any2dec(dec2any($test));

?>
Sekwer
@jaslanin dzięki za wyczerpujący post

Cytat(croc @ 15.05.2010, 10:11:26 ) *
Ty się naucz lepiej praktycznego podejścia do sprawy, panie "liczba heksdecymalna".


@croc "heksdecymalna" to literówka w poście #5 jest napisane liczba heksadecymalna panie "pytka"

Obok sumy kontrolnej funkcje skrótu mają fajne zastosowanie jako identyfikator. Nie ma idealnego rozwiązania, bo każde ma jakieś ograniczenia.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.