Gå til innhold

5 siffret unik kode


Anbefalte innlegg

Hei, jeg trenger en funksjon som kan generere en 5 siffret unik kode vær gang (for mitt system), skal bestå av bokstaver og tall og kan ikke under noen omstendigheter bli lik to ganger.

 

Altså inntil det er tomt da, og de må være random og ikke følge en rekkefølge.

 

Noen tanker?

Lenke til kommentar
Videoannonse
Annonse

Hvis du hele tiden må sjekke om den ikke finnes fra før av så burde du muligens vurdere å benytte deg av avanserte algoritmer i innebygde php-funksjoner eller en database. Når jeg tenker meg om så veit jeg faktisk ikke hva som er raskest av å skrive til db og bruke denne til å sjekke om den genererte hashen finnes, eller om det er raskere å lagre alt i en stor array f. eks.

Lenke til kommentar

1. Generer alle tall fra 0 til 99999

2. Stokk dem godt

3. Lagre dem i en liste på en eller annen måte. Du kan f.eks. bruke en vanlig database eller helt enkelt en fil.

4. Skriv en liten kodesnutt som henter første nummer i listen og oppdaterer hva "første" betyr. "Første" kan være en peker til første element i listen (f.eks. hvis du har en id-kolonne i database, eller et linjenummer i fil). Eller det brukte nummeret kan fjernes fra databasen/filen.

 

Dette er i alle fall en mye bedre teknikk enn å forsøke å generere noe unikt hver gang - når det er et så lite tall du har med å gjøre.

Lenke til kommentar

5 siffer er veldig vanskelig å få unik ved flere millioner hits, med bare tall og bokstaver. Har du store bokstaver også. Så blir det andre saker. Da blir det 5^62-4^62 = 901 356 496. Rimelig stort tall. Da er altså sansynligheten for at koden skal gjenta seg veldig veldig liten..

 

Du kan også lagre alle genererte koder, om du er veldig skeptisk. Deretter teste generert kode opp mot databasen, hvor du har lagret alle kodene. Om det blir retunert 0, så fortsetter du. Ellers så genrerer du igjen.

 

gammel funksjon jeg hadde liggende:

function create_password($length=5,$use_upper=1,$use_lower=1,$use_number=1){
$upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$lower = "abcdefghijklmnopqrstuvwxyz";
$number = "0123456789";
if($use_upper){
	$seed_length += 26;
	$seed .= $upper;
}
if($use_lower){
	$seed_length += 26;
	$seed .= $lower;
}
if($use_number){
	$seed_length += 10;
	$seed .= $number;
}
for($x=1;$x<=$length;$x++){
	$password .= $seed{rand(0,$seed_length-1)};
}
return($password);
}

Endret av warpie
Lenke til kommentar

Hvordan blir det uniks vær gang?

Sansynligheten for at den skal repitere kode er så liten at du skal ikke tenke på det.. MEN om du nå uansett bare MÅ... Så skrev jeg følgdene:

 

Du kan også lagre alle genererte koder, om du er veldig skeptisk. Deretter teste generert kode opp mot databasen, hvor du har lagret alle kodene. Om det blir retunert 0, så fortsetter du. Ellers så genrerer du igjen.
Endret av warpie
Lenke til kommentar

Vet ikke om du er mye inne på matte. Men sansynligheten for at den skal repitere kode er så liten at du skal ikke tenke på det.. MEN om du nå uansett bare MÅ... Så skrev jeg følgdene:

Hvis du er mye inne på matte kjenner man "Birthday Problem", og kan fint regne det ut.

 

F.eks med [1-9A-Za-z]{5} blir det 4 582 116 mulige nøkler. Trekker du ut 1200 tilfeldige av dem, som er det TS trenger nå, har du 14% sannsynlighet for at det finnes et par. Om et par måneder når han har trukket 2500 nøkler runder man 50% sannsynlighet for minst et par, derfra øker det eksponensielt, så med litt over 3000 runder man 2/3 osv...

 

Enten lagre alle verdiene, eller lagre random seed og antall generert, så man kan gjenskape alle verdiene når man trenger å lage nye.

 

Eller;

Sannsynligheten for å vinne i Lotto er tilnærmet 0

Sannsynligheten for at noen vinner i Lotto er tilnærmet 1

 

Hvilket tall som er naturlig å se på er avhengig av om man er Norsk Tipping, eller bare en som vurderer å spille Lotto.

Endret av MailMan13
Lenke til kommentar

Det er ikke korrekt å regne det ut slik (62!/5!) i dette tilfellet. Du krysser ut brukte bokstaver/tall, slik at de ikke gjentar seg (på samme plass i koden). Dette er altså ikke totalt antall mulige kombinasoner. Dermed: Feil

 

Gjentakelse av bokstaver og tall på samme plass er tilatt, og høyest nødvendig for å få noe ordentlig ut av det. Dermed er antall mulige kombinasjoner: 901 356 496, nå er sansynligheten for å møte på to like utrolig liten.

Endret av warpie
Lenke til kommentar

Selvfølgelig, regnet permutasjoner uten å tenke på det, men det er jo ikke det vi er interessert i.

 

Problemet blir mindre, men ikke utrolig liten. Med med 9e7 runder man prosenten rundt noen tusen, og 50% etter ca 20000.

Endret av MailMan13
Lenke til kommentar

Du tenker nok litt for avansert på noe enkelt. 450 678 248 er halvparten av 901 356 496, nå en passerer dette beløpet er det enkelt å si at en vil få en gjentaklse annen hver gang i det lange løp. (450/900) = 0.5 (50%)

 

Det er enkel sansynlighetsberegning. Kast teringen 100 ganger, den vil snitte ut på ca 3.5 :)

 

Sitat: Med med 9e7 runder...

Host: 9e8

Endret av warpie
Lenke til kommentar

Det er nok du som tenker litt for enkelt.

 

Du tenker sannsynlighet for at et neste tall du trekker er et duplikat. Da blir det riktig med slik du sier. Men sannsynligheten for at det ikke finnes duplikater i hele mengden er det vi er ute etter, da må vi gange inn alle trekkene vi har gjort frem til siste element også...

 

Sansynligheten for et gitt par er et duplikater er (n-1)/(n).

 

Vi har n(n-1)/2 par.

 

Sannsynlighet for at det ikke er kolisjon

p = ((n-1) / n) ^ c(n, c)

 

en.wikipedia.org/wiki/Birthday_problem#A_simple_exponentiation

Sitat: Med med 9e7 runder...

Host: 9e8

Ja, litt upresist her i dag. Men det er kombinasjonen (901356496) jeg plugget inn i beregningen...

 

 

Eller, med din måte kan brukes (k/n) hvis du tar med foregående trekk:

sannsynlighet for at siste element er unikt * sannsynlighet for nest siste element er unikt * ....

 

p = (k/n) * ((k-1) * n) .... * k

 

Fant en link som skriver ut hele greien for deg:

http://jeff.aaron.ca/cgi-bin/birthday

Endret av MailMan13
Lenke til kommentar

Skal se på det senere.

 

Edit: Det var ikke godt å bli klok på, for en som ikke har så høy kunskap innen matematikk (I wish I had) :) Hadde sikkert funnet ut av dette om jeg hadde orket å lese meg opp på matten igjen. Blir vel en dag.

Endret av warpie
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...