Unieke hash mbt shorturl script

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Robin Roboo

Robin Roboo

11/05/2011 14:46:40
Quote Anchor link
Hi Mensen,

Sinds kort ben ik bezig een oud shorturl script van me te herschrijven maar nu in OOP style. Hierbij loop ik hoofdzakelijk tegen het probleem op van het creëren van een unieke hash. Het script zal een suffix moeten kunnen gebruiken (mits deze niet bezet is natuurlijk) en indien er geen suffix is ingevoerd, er zelf 1 creëren.

Enkel is het probleem nu dat je met een combinatie van 62 karakters (a-z, A-Z, 0-9) bij een suffix grootte van 4 characters al in de 14 miljoen combinaties kan lopen (62^4). Het lijkt me daarbij niet echt verstandig om continu een loop te gaan draaien om te controleren of de nieuwe (door het systeem gegenereerd in dit geval) nog vrij is. (Stel je voor dat er al 13 miljoen bezet zijn..)

Wat zouden jullie hier voor oplossing bij gebruiken? Of wat is hier de snelste oplossing voor?

Thanks in advance!

Robin
 
PHP hulp

PHP hulp

06/05/2024 12:44:44
 
Robin Roboo

Robin Roboo

16/05/2011 19:54:44
Quote Anchor link
Is bumpen nou wel of niet toegestaan? Anyways, stiekem bumpje bij deze.
 
Roel -

Roel -

16/05/2011 20:06:03
Quote Anchor link
Beginnen bij a lijkt me. Dan b, c, ... z
Daarna a, ab, ac... etc.

Bumpen is overigens toegestaan na één dag ja.
Gewijzigd op 16/05/2011 20:06:50 door Roel -
 
Robin Roboo

Robin Roboo

16/05/2011 20:24:23
Quote Anchor link
Roel van de Water op 16/05/2011 20:06:03:
Beginnen bij a lijkt me. Dan b, c, ... z
Daarna a, ab, ac... etc.

Bumpen is overigens toegestaan na één dag ja.


En bij een database met 14 miljoen records? Allemaal 1 voor 1 af gaan lijkt me geen mogelijkheid. Enige oplossing die ik zie is het toevoegen van alle mogelijke combinaties (geen idee hoe overigens) en dan vervolgens gewoon met een query een vrije combinatie zoeken. Maar hoe ga ik dan zoveel combinaties toevoegen? Bij een suffix met 4 karakters (i.e.: 3fA4)heb je al 14776336 mogelijke combinaties.. (62(2x alfabet + 0-9)^4)..
 
- SanThe -

- SanThe -

16/05/2011 21:11:24
Quote Anchor link
sha1(microtime())
 
Joris van Rijn

Joris van Rijn

17/05/2011 05:44:19
Quote Anchor link
sha1(date('H i s u'))
Gewijzigd op 17/05/2011 06:21:37 door Joris van Rijn
 
Chris -

Chris -

17/05/2011 07:25:18
Quote Anchor link
Het gaat om een zo kort mogelijke code.. SHA1 is 40 tekens?

Je kan inderdaad 14 miljoen records aanmaken, vervolgens "SELECT code FROM codes WHERE used = 0 ORDER BY RAND() LIMIT 1" gebruiken om een code op te halen. Op de "code" veld zet je een UNIQUE attribuut, dan heb je geen dubbele codes ook.

Wellicht heb je hier wat aan?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
/*
 * @Name keygen
 * @Author Chris Horeweg
 * @Version not_important
 */


function generate_key($chars, $length, $holder, $split_length = null, $split_char = null)
{

    $return_string = ''; $j = 0;
    for($i = 0; $i < $length; $i++)
    {

        if($split_length && $split_char)
        {

            if($j == $split_length)
            {

                $return_string .= $split_char;    
                $j = 0;
            }

            $j++;
        }

        $return_string .= $chars[rand(0, count($chars) -1)];
    }

    if(isset($holder[$return_string]))
    {

        return generate_key($chars, $length, $holder, $split_length, $split_char);
    }

    else
    {
        return $return_string;
    }
}


echo '<pre>';
$tmp = array();
$chars = range('a','z');
$str_length = ctype_digit($_GET['l']) ? $_GET['l'] : 4;
$amount = ctype_digit($_GET['a']) ? $_GET['a'] : 10000000;

for($i = 1; $i <= $amount; $i++)
{

    $string = generate_key($chars, $str_length, $tmp);
    $tmp[$string] = $string;
    echo strtoupper($string).PHP_EOL;
    flush();
}

?>


Simpel script, geef aan hoeveel codes je wilt en hij maakt unieke codes aan :)
 
Robin Roboo

Robin Roboo

17/05/2011 08:31:23
Quote Anchor link
Chris Horeweg op 17/05/2011 07:25:18:
Het gaat om een zo kort mogelijke code.. SHA1 is 40 tekens?

Je kan inderdaad 14 miljoen records aanmaken, vervolgens "SELECT code FROM codes WHERE used = 0 ORDER BY RAND() LIMIT 1" gebruiken om een code op te halen. Op de "code" veld zet je een UNIQUE attribuut, dan heb je geen dubbele codes ook.

Wellicht heb je hier wat aan?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
/*
 * @Name keygen
 * @Author Chris Horeweg
 * @Version not_important
 */


function generate_key($chars, $length, $holder, $split_length = null, $split_char = null)
{

    $return_string = ''; $j = 0;
    for($i = 0; $i < $length; $i++)
    {

        if($split_length && $split_char)
        {

            if($j == $split_length)
            {

                $return_string .= $split_char;    
                $j = 0;
            }

            $j++;
        }

        $return_string .= $chars[rand(0, count($chars) -1)];
    }

    if(isset($holder[$return_string]))
    {

        return generate_key($chars, $length, $holder, $split_length, $split_char);
    }

    else
    {
        return $return_string;
    }
}


echo '<pre>';
$tmp = array();
$chars = range('a','z');
$str_length = ctype_digit($_GET['l']) ? $_GET['l'] : 4;
$amount = ctype_digit($_GET['a']) ? $_GET['a'] : 10000000;

for($i = 1; $i <= $amount; $i++)
{

    $string = generate_key($chars, $str_length, $tmp);
    $tmp[$string] = $string;
    echo strtoupper($string).PHP_EOL;
    flush();
}

?>


Simpel script, geef aan hoeveel codes je wilt en hij maakt unieke codes aan :)

Inderdaad is het natuurlijk de bedoeling dat de suffix zo kort mogelijk blijft (of in ieder geval bij de kortst mogelijke combinatie begint). Thanks voor je script, hier heb ik zeker wel wat aan. Op welke manier kan ik het beste 14 miljoen hashes in een database gooien? Query opbouwen en dan met bigdump erin gooien ofzo? Of zijn er snellere methodes?
 
- Ariën  -
Beheerder

- Ariën -

17/05/2011 08:35:21
Quote Anchor link
Unique key op je database, en dan kijken met of er een fout optreedt met mysql_erro_no().

Ik meen dat bij een duplicate key foutcode 1022 teruggaf, of 1044. Maar dat moet je even op zoeken. Als hij een unique key aangeeft doe je een nieuwe insert.
 
Robin Roboo

Robin Roboo

17/05/2011 08:50:47
Quote Anchor link
- Aar - op 17/05/2011 08:35:21:
Unique key op je database, en dan kijken met of er een fout optreedt met mysql_erro_no().

Ik meen dat bij een duplicate key foutcode 1022 teruggaf, of 1044. Maar dat moet je even op zoeken. Als hij een unique key aangeeft doe je een nieuwe insert.

1066 geloof ik inderdaad, maar je gaat natuurlijk niet (die kans kan je lopen) 13 miljoen records aflopen.. Daarom lijkt alle mogelijk combinaties toevoegen en daar een vrije uitkiezen de beste mogelijkheid.
 
- Ariën  -
Beheerder

- Ariën -

17/05/2011 09:09:56
Quote Anchor link
Jij loopt toch geen 13 miljoen records door? MySQL houd zelf toch wel een index bij, lijkt me of er dubbele bij zitten?
 
Robin Roboo

Robin Roboo

17/05/2011 09:49:22
Quote Anchor link
- Aar - op 17/05/2011 09:09:56:
Jij loopt toch geen 13 miljoen records door? MySQL houd zelf toch wel een index bij, lijkt me of er dubbele bij zitten?

Heb je een voorbeeld van wat je bedoelt? Ik denk dat we elkaar verkeerd begrijpen..
 
- Ariën  -
Beheerder

- Ariën -

17/05/2011 09:59:39
Quote Anchor link
Heb je al eens gekeken wat een UNIQUE-index op je database doet? En wat mysql_erro_no() doet? Als deze gelijk is aan 1066, dan weet je dat die ID al bestaat, en dan kan je een nieuwe poging wagen.
 
Robin Roboo

Robin Roboo

17/05/2011 10:11:46
Quote Anchor link
- Aar - op 17/05/2011 09:59:39:
Heb je al eens gekeken wat een UNIQUE-index op je database doet? En wat mysql_erro_no() doet? Als deze gelijk is aan 1066, dan weet je dat die ID al bestaat, en dan kan je een nieuwe poging wagen.

Maar bedoel je dan mét of zonder alle mogelijke combinaties in de database? In example: Ik heb een database waar 14 miljoen mogelijke combinaties in kunnen, 13 miljoen daarvan zijn al bezet. Nu ga ik vervolgens een query draaien met 3 random combinaties om te kijken of deze nog vrij zijn, deze zijn allen bezet dus krijg ik error no 1066 terug. Dan ga ik hem weer opnieuw draaien. Ik heb geen benul van de kans berekening, maar bij 3 verschillende combinaties op een database waar al 13miljoen combinaties in staan, lijkt me de kans vrij klein dat je snel een vrije combinatie zal vinden. Ik denk overigens nog steeds dat ik je verkeerd begrijp, vandaar het verzoek om een voorbeeld ;-)
 
Chris -

Chris -

17/05/2011 10:55:04
Quote Anchor link
Robin, kijk nou nog eens naar mijn query.. Die werkt gewoon, 1 keer draaien en klaar!
 
Robin Roboo

Robin Roboo

17/05/2011 10:57:49
Quote Anchor link
Chris Horeweg op 17/05/2011 10:55:04:
Robin, kijk nou nog eens naar mijn query.. Die werkt gewoon, 1 keer draaien en klaar!

Deze heb ik inderdaad bekeken en werkt naar verwachting, heb hem een klein beetje aangepast zodat a-Z en 0-9 er ook in voorkomen en ze niet uppercase zijn. Hoe kan ik nu het beste alle combinaties toevoegen in de database? Met bigdump of gewoon rechtstreeks via phpmyadmin? Qua verstand van database ontbreekt er nog wat van mijn kant, maar heb reeds een boek besteld om me erin te kunnen gaan verdiepen.
 
Chris -

Chris -

17/05/2011 10:59:20
Quote Anchor link
MySQL verbinding maken en in plaats van ze te echo-en, een query uitvoeren en ze erin zetten ;-) Zie de beginners MySQL handleiding
 
Robin Roboo

Robin Roboo

17/05/2011 11:01:27
Quote Anchor link
Chris Horeweg op 17/05/2011 10:59:20:
MySQL verbinding maken en in plaats van ze te echo-en, een query uitvoeren en ze erin zetten ;-) Zie de beginners MySQL handleiding

Hehe okay, ja zover was ik al met MySQL. Ging me eerder om het normaliseren en het optimaal laten werken van een MySQL database. Thanks voor je hulp tot zover in ieder geval!



Toevoeging op 17/05/2011 18:56:03:

Hey Chris. Het is allemaal gelukt, thanks voor je hulp. Momenteel staan er ruim 240 duizend combinaties in de database, dat is eerst wel even genoeg denk ik. Is er ook een snellere manier om random vrije hashes op te halen? In jouw query had je order by rand, maar het ziet er naar uit dat dit de query wel ruim 5 seconden doet vertragen..
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.