08. maj 2002 - 09:49Der er
35 kommentarer og 1 løsning
Vurdering af sjældenhed
Hvis denne funktion køres med 10 som værdi for intAntaltegn, hvor lille er sandsynligheden så for, at det samme password kommer 2 gange? Jeg troede det var en god algoritme, men har flere gange konstateret, at det samme password genereres. Selv om der ikke forsøges så mange gange.
Function MakePassword(intAntaltegn) For x = 1 To intAntalTegn Randomize intChooser = Int(Rnd * 2) + 1 Select Case intChooser Case 1 intWildChar = Int(Rnd * 57) + 65 If intWildChar => 91 And intWildChar <= 96 Then intWildChar = intWildChar + 8 End If strPassword = strPassword & Chr(intWildChar) Case Else intWildChar = Int(Rnd * 9) + 1 strPassword = strPassword & intWildChar End Select Next MakePassword = strPassword End Function
hvis du sætter password ind i en database kan du jo checke på om det du lige har lavet allerede findes i database og hvis det så gør skal den bare køre funktionen igen
-Det er fordi løkken kører så hurtigt, at Randomize næsten er ens hver gang. Hvis du sætter den udenfor bliver den "tilstrækkelig" forskellig for hver gang den kaldes. Og Rnd kaldes jo hver gang med sidste værdi som seed, -derfor er det kun nødvendigt at Randomize den første gang den kaldes.
Function MakePassword(intAntaltegn) Randomize For x = 1 To intAntalTegn intChooser = Int(Rnd * 2) + 1 Select Case intChooser Case 1 intWildChar = Int(Rnd * 57) + 65 If intWildChar => 91 And intWildChar <= 96 Then intWildChar = intWildChar + 8 End If strPassword = strPassword & Chr(intWildChar) Case Else intWildChar = Int(Rnd * 9) + 1 strPassword = strPassword & intWildChar End Select Next MakePassword = strPassword End Function
Nu hvor jeg nærlæser din funktion, ser jeg at det måske er et andet sted problemet ligger. Anden gang du kalder Rnd (i Case 1), vil den hver anden gang (i snit) have den samme seedværdi (2 eller 1). Det er ikke godt! Jeg laver lige nogle tests og vender tilbage.
Det er Randomize der skaber problemerne. Du skal slet ikke kalde den i funktionen. Du kan kalde den inden (men endelig ikke i en løkke), men det er ikke nødvendigt. Jeg har simplificeret din funktion lidt, og testet den med 10.000 passwords på 10 karakterer, og nu fungerer den:
Function MakePassword(ByVal Antaltegn As Long) As String Dim lWildchar As Long, bUnik As Boolean, i As Long
MakePassword = "" For i = 1 To Antaltegn Do bUnik = True lWildchar = Int(Rnd * 75) + 48 If lWildchar > 57 And lWildchar < 65 Then bUnik = False If lWildchar > 90 And lWildchar < 97 Then bUnik = False Loop Until bUnik = True MakePassword = MakePassword & Chr(lWildchar) Next i
Function MakePassword(ByVal Antaltegn As Long) As String --------------------------------------^
Min kode:
<% Function MakePassword(ByVal Antaltegn As Long) As String Dim lWildchar As Long, bUnik As Boolean, i As Long
MakePassword = "" For i = 1 To Antaltegn Do bUnik = True lWildchar = Int(Rnd * 75) + 48 If lWildchar > 57 And lWildchar < 65 Then bUnik = False If lWildchar > 90 And lWildchar < 97 Then bUnik = False Loop Until bUnik = True MakePassword = MakePassword & Chr(lWildchar) Next i
Aha. Det må være fordi det er VB-script. Prøv som jeg foreslog at fjerne "As String" i funktionen. Jeg er heller ikke sikker på at Dim linien er i orden, men jeg kender ikke meget til VB-script. Koden er "ren" VB.
Jeg ved ikke om du kan kalde Randomize direkte i VB-script, men hvis du kan så ville jeg nok sætte Randomize ind lige før ID2= Makepassword(10).
<% Function MakePassword(Antaltegn) Dim lWildchar Dim bUnik Dim i
MakePassword = "" For i = 1 To Antaltegn Do bUnik = True lWildchar = Int(Rnd * 75) + 48 If lWildchar > 57 And lWildchar < 65 Then bUnik = False If lWildchar > 90 And lWildchar < 97 Then bUnik = False Loop Until bUnik = True MakePassword = MakePassword & Chr(lWildchar) Next i
Der er såmænd ikke den store forskel. Du kunne have brugt det gamle, hvis du havde sat Randomize udenfor på samme måde. Forskelle: Du skelnede mellem bogstaver og tal, ved at lave to forskellige cases, og i bogstaverne fjernede du de ugyldige ved at lægge 8 til.
Jeg lavede det sådan at du finder et tal mellem 48 - 122 = Alle tal og bogstaver. Og fjerner de ugyldige ved at sige, at den skal finde et nyt tal, og blive ved med det indtil tallet er gyldigt. (Do - loopet.)
-Beklager forvirringen med VB-script. Det havde kørt første gang i "ren" VB.
Som hirayz var inde på: Du kan ikke være 100% sikker, og burde måske lave noget sammenligning via en DB. I sandsynlighedsregning KAN det (næsten) umulige jo ske. Det KAN godt lade sig gøre at slå en sekser 500 gange i træk med en terning. -Det er bare meget usandsynligt!
MHT til dette script: Jeg er ikke så stiv i sandsynlighedsregning, men jeg ville mene at sandsynligheden for at få det samme password (på 10 karakterer) er noget i retning af: 60^10 = 6^17, hvilket vil sige at det sker ca. 1 gang ud af 10 milliarder med 50.000 passwords.
Jeg vil prøve at køre programmet i et loop på 100.000, og derefter teste for gengangere, men det vil tage et par timer - og jeg kan ikke gøre det her (er på arbejde). Men jeg prøver i aften.
NB: Den udregning jeg kom med gælder kun for "ægte" tilfældige tal. Da Randomize og Rnd kun er pseudo-tilfældige, skal det tages med et (stort)gran salt. Jeg mener at Randomize genererer efter systemtimeren i millisekunder, dvs at den kun har : 24*60*60*1000=86400000 forskellige værdier. Såvidt jeg kan se betyder det at der kun er 86400000 forskellige kombinationer, hvilket betyder at det er ca. 1 gang ud af 1700 for hver gang du genererer 50.000 passwords!
Når man har kaldt med: ID2 = MakePassword(10) Kunne man sige: Se om der findes en record med værdien i databasen Hvis den findes så: ID2 = MakePassword(10) igen End If Tilskriv værdien til databasen
da jeg så skrev den der test kommentar kom det hele igen
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.