Jump to content
Sign in to follow this  
uzytkownik

Pytanie do programisty

Recommended Posts

Chciałbym generować takie unikalne ciągi znakowe jak np. robi YouTube w swoich linkach.

 

Przykład:

youtube.com/watch?v=4Vpkz-uzH9I&feature=popular

 

Na wielu stronach są podobne rozwiązania i nie jestem pewien, czy programiści korzystają z gotowych PHP'owych funkcji kodujących czy trzeba sobie napisać własny skrypt generujący takie ciągi... Jeśli ktoś korzysta, proszę o informacje.

 

I jeszcze jedno. Wiadomo, że działania na na stringach są wolniejsze niż te na liczbach. Czy jest to na tyle zauważalne, że powinno się używać raczej zmiennych liczbowych niż stringów? (zakładając, że korzysta się ze zwyczajnego wirtualnego hostingu).

Share this post


Link to post
Share on other sites
Chciałbym generować takie unikalne ciągi znakowe jak np. robi YouTube w swoich linkach.

 

Przykład:

youtube.com/watch?v=4Vpkz-uzH9I&feature=popular

 

Na wielu stronach są podobne rozwiązania i nie jestem pewien, czy programiści korzystają z gotowych PHP'owych funkcji kodujących czy trzeba sobie napisać własny skrypt generujący takie ciągi... Jeśli ktoś korzysta, proszę o informacje.

 

I jeszcze jedno. Wiadomo, że działania na na stringach są wolniejsze niż te na liczbach. Czy jest to na tyle zauważalne, że powinno się używać raczej zmiennych liczbowych niż stringów? (zakładając, że korzysta się ze zwyczajnego wirtualnego hostingu).

 

Można to zrobic w kilku linijkach kodu:

 

function Hash($length) {

$conso=array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","v","w","x","y","z","a","e","i","o","u");

$hash="";

srand((double)microtime()*1000000);

for($i=1;$i<=$length;$i++) $hash.=$conso[rand(0,strlen($conso)-1)];

return $hash;

}

 

W tablicy conso możesz zdefiniować jakie litery/cyfry/znaki mają się pojawiać.

 

PHP nie wymaga określania typów zmiennych dlatego nie ma większego znaczenia czy operujesz na stringach czy łańcuchach.

Edited by Kokoro

Share this post


Link to post
Share on other sites

lub też md5() i wycinać z niego odpowiednią ilość znaków a kodować np. czas z datą, rokiem to masz pewność że będzie on unikalny.

Jest tyle rozwiązań ... ;)

Share this post


Link to post
Share on other sites

Napisz funkcję rekurencyjną, generującą ciąg znaków, potem wytnij to substr(), a potem wyrażeniem regularnym ogranicz znaki, jakie chcesz..

Share this post


Link to post
Share on other sites
I jeszcze jedno. Wiadomo, że działania na na stringach są wolniejsze niż te na liczbach. Czy jest to na tyle zauważalne, że powinno się używać raczej zmiennych liczbowych niż stringów? (zakładając, że korzysta się ze zwyczajnego wirtualnego hostingu).

O czym Ty mówisz? Przecież te różnice nie są mierzone w sekundach, a w mili, jak nie mikro..

Share this post


Link to post
Share on other sites
O czym Ty mówisz? Przecież te różnice nie są mierzone w sekundach, a w mili, jak nie mikro..

Dla pojedynczych operacji może tak, ale dla całej, rozbudowanej aplikacji każdy ułamek sekundy jest na wagę złota... ;)

 

Kwestia optymalizacji aplikacji to temat na długie, długie rozmowy ;) W każdym razie nie można go bagatelizować!

Edited by bartol

Share this post


Link to post
Share on other sites

Dziękuję za odpowiedzi.

W pierwszym poście nie sprecyzowałem o co mi chodzi, więc zrobię to teraz. Przykładowo chcę wykonać serwis z fotkami. Każda fotka ma być w URL reprezentowana poprzez string(litery, cyfry + ew. inne znaki). Nie może to być liczba, bo chcę uniemożliwić użytkownikom, obejrzenie wszystkich fotek poprzez wpisywanie kolejnych liczb w URL. String powinien być w miarę krótki (najlepiej 5-8 znaków)

Chciałbym, żeby skrypt generował za każdym razem unikalny kod, abym nie musiał w bazie sprawdzać, czy dana nazwa nie jest zajęta - aplikacja ma być maksymalnie wydajna i prosta.

 

Druga sprawa - wydajność aplikacji przy zastosowaniu stringów.

Ideałem byłoby ponumerowanie kolejnych zdjęć od 1 do ... ale jak już wspomniałem nie chcę, żeby ktoś obejrzał wszystkie fotki poprzez sprytne manipulowanie URLem. Pozostaje więc użycie stringów.

I teraz pytanie. Czy bardzo zauważalny będzie spadek wydajności aplikacji? Na dedyka na razie mnie nie stać, to muszę się upewnić czy host z którego korzystam, podoła :P

 

Można to zrobic w kilku linijkach kodu:

 

function Hash($length) {

$conso=array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","v","w","x","y","z","a","e","i","o","u");

$hash="";

srand((double)microtime()*1000000);

for($i=1;$i<=$length;$i++) $hash.=$conso[rand(0,strlen($conso)-1)];

return $hash;

}

 

W tablicy conso możesz zdefiniować jakie litery/cyfry/znaki mają się pojawiać.

 

Dobre to, ale istnieje pewne prawdopodobieństwo wylosowania tej samej wartości.

 

Oj programiści.. :P

 

uniqid()

 

Zapomniałem o tej fajnej funkcji. Chyba właśnie tą wykorzystam. Minusem jest, że generuje trochę za długi string (wydajność aplikacji maleje). Jeśli nie znajdę czegoś innego to właśnie uniqid() wykorzystam. Dzięki :P

 

lub też md5() i wycinać z niego odpowiednią ilość znaków a kodować np. czas z datą, rokiem to masz pewność że będzie on unikalny.

Jest tyle rozwiązań ... :P

 

Dowiedziono, że funkcje hashujące dla różnych wartości hashowanych mogą wytworzyć ten sam kod, choć niezwykle rzadkio się to zdarza. Ale jeśli się obetnie do długości 5-8 znaków to prawdopodobieństwo powtórzenia niebezpiecznie wzrasta ;)

 

 

O czym Ty mówisz? Przecież te różnice nie są mierzone w sekundach, a w mili, jak nie mikro..

 

Dla pojedynczych operacji może tak, ale dla całej, rozbudowanej aplikacji każdy ułamek sekundy jest na wagę złota... ;)

 

Kwestia optymalizacji aplikacji to temat na długie, długie rozmowy ;) W każdym razie nie można go bagatelizować!

 

Nie bagatelizuję. Rozmawiamy o generowaniu losowego ciągu znaku, a nie rozbudowanej aplikacji.

 

Chodzi o całą aplikację. Moja wina, że nie doprecyzowałem o co mi chodzi.

Edited by uzytkownik

Share this post


Link to post
Share on other sites
Dziękuję za odpowiedzi.

W pierwszym poście nie sprecyzowałem o co mi chodzi, więc zrobię to teraz. Przykładowo chcę wykonać serwis z fotkami. Każda fotka ma być w URL reprezentowana poprzez string(litery, cyfry + ew. inne znaki). Nie może to być liczba, bo chcę uniemożliwić użytkownikom, obejrzenie wszystkich fotek poprzez wpisywanie kolejnych liczb w URL. String powinien być w miarę krótki (najlepiej 5-8 znaków)

Chciałbym, żeby skrypt generował za każdym razem unikalny kod, abym nie musiał w bazie sprawdzać, czy dana nazwa nie jest zajęta - aplikacja ma być maksymalnie wydajna i prosta.

 

Druga sprawa - wydajność aplikacji przy zastosowaniu stringów.

Ideałem byłoby ponumerowanie kolejnych zdjęć od 1 do ... ale jak już wspomniałem nie chcę, żeby ktoś obejrzał wszystkie fotki poprzez sprytne manipulowanie URLem. Pozostaje więc użycie stringów.

I teraz pytanie. Czy bardzo zauważalny będzie spadek wydajności aplikacji? Na dedyka na razie mnie nie stać, to muszę się upewnić czy host z którego korzystam, podoła ;)

 

Na 100% unikalna nazwa bez sprawdzania w bazie to może być np:

$nazwa=$user_id.time();

Taka nazwa nie powtórzy się przez najbliższe 68 lat ;)

 

Raczej nikt nie będzie sprawdzał timestamp dla każdej sekundy aby wykryć jakieś zdjęcia :P Zresztą możesz używać _POST aby ukryć parametr (ok, do obejścia, ale komu by się chciało).

 

Minusem jest, że używając time() user nie może dodać 2-ch zdjęć w tej samej sekundzie (co raczej jest niemożliwe, ale dla spokoju możesz użyć microtime() ).

Edited by Kokoro

Share this post


Link to post
Share on other sites

Proponuję własną funkcję:

 

// funkcja generująca losowy ciąg o długości od 1 do 15 znaków

// pierwsze 6 znaków to zmienna czasowa, pozostałe, jeśli są konieczne

// generuje zmienna losowa.

 

function losuj($dlugosc){

$time = microtime();

$los = substr ($time , 2 , 6);

$dodatkowo = $dlugosc - strlen($los) + 1;

if ( $dodatkowo>0 ) $los .= rand( pow(10,$dodatkowo) , (pow(10,($dodatkowo+1))-1) );

$los = substr ($los , 0 , $dlugosc);

return $los;

}

 

 

echo "http://satio.pl/".losuj(15).".jpg"; // zastosowanie, link do działającej funkcji poniżej

 

program PHP: funkcja do generowania nazwy pliku ze zmiennej w postaci cyfr

 

 

Poniżej dodaję jeszcze kod do Tworzenia dowolnego systemu kodowania znaków,

dzięki czemu losową liczbę z funkcji "losuj()" można dodać do funkcji "koduj()",

gdzie ta sama liczba losowa przy 15 znakach w dziesiętnym systemie,

będzie zajmowała 8 znaków w systemie 64 znakowym

 

// funkcja generująca ciąg znaków z ciągu cyfr na podstawie tablicy znaków

// w zasadzie umożliwia generowanie dowolnego systemu:

// binarnego (przy wpisaniu tylko wartości w tablicy: "0","1"

// szesnastkowego, w tym przypadku 64-znakowego

 

function koduj($dec)

{

$sign = ""; // suppress errors

if( $dec < 0){ $sign = "-"; $dec = abs($dec); }

 

$tab = array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","v","w","x","y","z","a","e","i","o","u",

"B","C","D","F","G","H","J","K","L","M","N","P","R","S","T","V","W","X","Y","Z","A","E","I","O","U",

"1","2","3","4","5","6","7","8","9","0","=","-","+","&");

$typ = count($tab);

 

do

{

$new = $tab[($dec%$typ)] . $new;

$dec /= $typ;

}

while( $dec >= 1 );

 

return $sign . $new;

}

 

echo koduj(333553127380726);

 

funkcja do prezentowania liczby w dowolnym systemie znakowym: szesnastkowy, binarny, 64-znakowy, ...

Edited by Czyzis

Share this post


Link to post
Share on other sites
Dowiedziono, że funkcje hashujące dla różnych wartości hashowanych mogą wytworzyć ten sam kod, choć niezwykle rzadkio się to zdarza. Ale jeśli się obetnie do długości 5-8 znaków to prawdopodobieństwo powtórzenia niebezpiecznie wzrasta

 

 

Masz jakiś przykład? Lub ewentualnie artykuł na ten temat?

Share this post


Link to post
Share on other sites
Masz jakiś przykład? Lub ewentualnie artykuł na ten temat?

 

Też jestem tego ciekaw, mimo wszystko jestem zwolennikiem własnych rozwiązań, bazowanie na gotowych funkcjach często i tak wymaga dodatkowych zabiegów, a długość kodu wcale nie ma odzwierciedlenia w czasie wykonywania...

Share this post


Link to post
Share on other sites

@bert, @Czyzis, bardzo proszę ;)

 

http://pl.wikipedia.org/wiki/MD5

 

"...W marcu 2004 powstał rozproszony projekt nazywany MD5CRK. Twórcą projektu był Jean-Luc Cooke i jego współpracownicy. Miał on na celu wykazanie, że możliwe jest wyznaczenie wiadomości różnej od zadanej, która ma taką samą wartość skrótu. Do tego celu wykorzystano sieć Internet oraz dużą liczbę komputerów biorących udział w projekcie. Projekt wykazał, że dysponując bardzo dużą mocą obliczeniową możliwe jest podrabianie generowanych podpisów...."

 

"...W marcu 2005 Arjen Lenstra, Xiaoyun Wang i Benne de Weger zaprezentowali metodę umożliwiającą znalezienie kolizji dla algorytmu MD5 i przeprowadzenie ataku polegającego na wysłaniu dwóch różnych wiadomości chronionych tym samym podpisem cyfrowym. Kilka dni później Vlastimil Klima opublikował algorytm, który potrafił znaleźć kolizję w ciągu minuty, używając metody nazwanej tunneling..."

Edited by uzytkownik

Share this post


Link to post
Share on other sites
Masz jakiś przykład? Lub ewentualnie artykuł na ten temat?

 

Tu nie ma czego dowodzić ;)

 

Gdyby powyższy cytat nie był prawdą, to okazało by się, że algorytm md5 lub podobne byłby najlepszym w historii algorytmem kompresji.

Każdy plik/ciąg znaków można by było skompresować do 32 bajtów.

 

Ale oczywiście tak nie jest. Dla różnych haseł funkcja mieszająca może zwrócić tę samą (kolizja) wartość. Świadomie bardzo trudno znaleźć kolizję dla danego hasła. Współczesne komputery są do tego zbyt wolne i wykorzystują niefektywne algorytmy. Z pomocą mogą przyjść komputery kwantowe i odpowiednie algorytmy (faktoryzacja dużych liczb pierwszych), które już zostały wymyślone.

Share this post


Link to post
Share on other sites
Też jestem tego ciekaw, mimo wszystko jestem zwolennikiem własnych rozwiązań, bazowanie na gotowych funkcjach często i tak wymaga dodatkowych zabiegów, a długość kodu wcale nie ma odzwierciedlenia w czasie wykonywania...

 

Gotowe funkcje mają tę zaletę, że są dużo szybsze. Setki, a nawet tysiące razy szybsze. Kod skompilowany zawsze będzie szybszy od kodu interpretowanego.

Pisanie w PHP jest jak budowanie z klocków, samo PHP jest powolne ze względu na to że nie jest to skompilowany kod, jednak poszczególne jego kawałki (funkcje) są szybkie. Pisanie kodu PHP polega na umiejętnym wykorzystywaniu gotowych funkcji.

Share this post


Link to post
Share on other sites
Tu nie ma czego dowodzić ;)

 

Gdyby powyższy cytat nie był prawdą, to okazało by się, że algorytm md5 lub podobne byłby najlepszym w historii algorytmem kompresji.

Każdy plik/ciąg znaków można by było skompresować do 32 bajtów.

 

Ale oczywiście tak nie jest. Dla różnych haseł funkcja mieszająca może zwrócić tę samą (kolizja) wartość. Świadomie bardzo trudno znaleźć kolizję dla danego hasła. Współczesne komputery są do tego zbyt wolne i wykorzystują niefektywne algorytmy. Z pomocą mogą przyjść komputery kwantowe i odpowiednie algorytmy (faktoryzacja dużych liczb pierwszych), które już zostały wymyślone.

 

Ja po prostu tylko, pytam się czy zna jakiś przykład gdzie dwie różne treści po zakodowaniu dadzą ten sam kod.

Lub też żeby podesłał mi informację na ten temat, bo z chęcią sobie poczytam.

 

@bert, @Czyzis, bardzo proszę

Dzięki, poczytam. ;)

Edited by Bert

Share this post


Link to post
Share on other sites
Gotowe funkcje mają tę zaletę, że są dużo szybsze. Setki, a nawet tysiące razy szybsze. Kod skompilowany zawsze będzie szybszy od kodu interpretowanego.

Pisanie w PHP jest jak budowanie z klocków, samo PHP jest powolne ze względu na to że nie jest to skompilowany kod, jednak poszczególne jego kawałki (funkcje) są szybkie. Pisanie kodu PHP polega na umiejętnym wykorzystywaniu gotowych funkcji.

 

...a tych funkcji w PHP jest od groma. Znajomość wielu z nich znacznie ułatwia pracę.

 

 

Podrążyłem jeszcze temat kolizji MD5 i znalazłem takie coś:

http://www.mscs.dal.ca/~selinger/md5collision/

oraz

http://www.links.org/?p=6

 

Podane tam są przykładowe dwie wartości, które dają ten sam hash. Zrobiłem test, ale otrzymałem różne wyniki. Może coś zle przeczytałem. Jak, komuś się uda niech da znać :)

Share this post


Link to post
Share on other sites
Gotowe funkcje mają tę zaletę, że są dużo szybsze. Setki, a nawet tysiące razy szybsze. Kod skompilowany zawsze będzie szybszy od kodu interpretowanego.

Pisanie w PHP jest jak budowanie z klocków, samo PHP jest powolne ze względu na to że nie jest to skompilowany kod, jednak poszczególne jego kawałki (funkcje) są szybkie. Pisanie kodu PHP polega na umiejętnym wykorzystywaniu gotowych funkcji.

 

zgadzam się, jednak to nie zmienia faktu, że rozwiązaniem problemu nie jest gotowa funkcja

i w tym przypadku należy powiązać kilka funkcji, które wygenerują odpowiedni niepowtarzalny kod o odpowiedniej długości,

więc dyskusyjną kwestią pozostaje optymalne powiązanie funkcji, gdyż żadna z gotowych nie spełnia oczekiwań.

Share this post


Link to post
Share on other sites

skoro już poruszyliśmy temat haseł dodam jeszcze mały skrypt do generowania haseł, które łatwo zapamiętać,

wiadomo, pula jest o wiele mniejsza, bo nie są mieszane na przemian z cyframi, ale przez to łatwiej je zapamiętać,

efekt jest taki, że hasło jest generowane z 7 liter (spółgłoski i samogłoski) + znak specjalny + liczba 3 cyfrowa,

czyli hasło posiada 11 znaków, a pomimo tego można je przeczytać (zostały wyeliminowane znaki: q,x,y)

nie sprawdzałem ilości kombinacji bo to skrypt demonstracyjny, gdyż do poważniejszego wykorzystania przydałaby się jakaś logika mieszania i zmiany długości hasła, ale teraz nie myślę nad ulepszaniem tego skryptu.

 

function haslo()

{

$samogloski = array("a","e","i","o","u");

$spolgloski = array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","w","z");

$inne = array("=","-","+","&","#","$","*","@","%","_");

 

for($x=0;$x<3;$x++){

$new = $spolgloski[rand(0,count($spolgloski)-1)].$samogloski[rand(0,count($samogloski)-1)];

$pass .= $new;

}

 

$pass .= $spolgloski[rand(0,count($spolgloski)-1)].$inne[rand(0,count($inne)-1)].rand(0,9).rand(0,9).rand(0,9);

return $pass;

}

 

można zerknąć na efekt pod adresem: http://satio.pl/programy/pass.php

Edited by Czyzis

Share this post


Link to post
Share on other sites

Grzesiek86 - dziękuję za policzenie kombinacji :)

Te miliardy mnie zainspirowały do małej zmiany, ale na korzyść, gdyż

z 11 znaków powstało hasło 10 znakowe,

ilość kombinacji to: 5^3*17^4*10^2*25 = 26 100 312 500

czyli 4 razy mniej niż poprzednia wersja, ale za to czytelność i łatwość wymówienia wzrosła

 

 

function haslo2()

{

$samogloski = array("a","e","i","o","u");

$spolgloski = array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","w","z");

$wszystkie = array("b","c","d","f","g","h","j","k","l","m","n","p","r","s","t","w","z","y","x","q","a","e","i","o","u");

for($x=0;$x<3;$x++) $pass .= $spolgloski[rand(0,count($spolgloski)-1)].$samogloski[rand(0,count($samogloski)-1)];

$pass .= $spolgloski[rand(0,count($spolgloski)-1)].rand(0,9).rand(0,9).$wszystkie[rand(0,count($wszystkie)-1)];

return $pass;

}

 

tutaj dostępne efekty tego algorytmu http://satio.pl/programy/pass2.php

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×