Author | Message | Time |
---|---|---|
BreW | Help! This random string function seems to be repeating a lot, I have no idea what to do in order to make it more random. It's supposed to generate a random alphanumeric string with more then 3 characters, but less then 15. Here's what I got: [code] Public Function Rand() As String Dim i#, Name$, Char$, Limit# Randomize Top: Name = vbNullString Limit = Fix(Rnd * 15) + 12 Do Until Len(Name) = Limit Char = Chr(Fix(Rnd * 126)) If Char Like "*[!A-Za-z0-9]*" Then GoTo Top Name = Name & Char Loop If Len(Name) > 15 Then GoTo Top Rand = Name End Function [/code] | March 18, 2007, 12:34 AM |
Barabajagal | This should be in the VB Programming section, not the General Programming section. Also, that's some of the most terribly inefficient and poorly written code I've seen in a while. | March 18, 2007, 12:44 AM |
BreW | I know, very improper use of the Goto keyword and I was tired when I wrote that. But it works! Also why would this have to be in the vb6 programming section? This doesn't really apply to JUST vb, but could to other languages too. Therefore this is why I put it in the general programming section. EDIT*** Okay, I made it a little better [code] Public Function Rand() As String Dim i#, Name$, Char$, Limit# Randomize Limit = Fix(Rnd * 15) + 12 Do Until Len(Name) = Limit Char = Chr(Fix(Rnd * 126)) If Char Like "*[!A-Za-z0-9]*" Then Char = Fix(Rnd * 10) Name = Name & Char Loop If Len(Name) > 15 Then Name = Left(Name, 15) Rand = Name End Function [/code] Still, any suggestions? | March 18, 2007, 12:57 AM |
Barabajagal | You're asking for help with vb, so it goes in the vb section. Here's some 'help': 1) Define a variable to store the length of the string to create and set it to a random int between 4 and 14. 2) Do a For... Next loop to generate each random character. 3) Don't use GoTo, don't use "Like" (I've never even HEARD of that keyword before), and don't use Fix, use CInt or just Int. | March 18, 2007, 1:09 AM |
BreW | Okay, reality. 1). Limit = Fix(Rnd * 15) + 12 I have no idea how I would do "a random number between 4 and 14". That would be GREAT if there was some simple easy way to do that but there isn't. 2). Why a For loop? I want this to keep executing until the length of the string is equal to the limit, obviously. Nothing else. 3). I took the goto out, and what's wrong with Fix? Then... I have to use Like or I have nothing to work with. IF I don't use Like how would I say "if it doesn't have a character between a-z, A-Z, or 0-9"? Just because you've never heard of Like doesn't mean you can't use it. It's always nice to try new things. | March 18, 2007, 1:18 AM |
Barabajagal | Here's how I'd do it [code]Private Function CreateString() Dim iStrLen As Integer Dim iChar As Integer Dim I As Integer Dim strString As String iStrLen = Int(Rnd * 10) + 4 For I = 1 To iStrLen iChar = Int(Rnd * 62) If iChar >= 0 And iChar <= 9 Then strString = strString & Chr$(iChar + 48) ElseIf iChar >= 10 And iChar <= 35 Then strString = strString & Chr$(iChar + 55) ElseIf iChar >= 36 And iChar <= 61 Then strString = strString & Chr$(iChar + 61) End If Next I CreateString = strString End Function[/code] Note that this isn't fully tested, and I may have made some mistakes some places. | March 18, 2007, 1:39 AM |
BreW | [quote author=[RealityRipple] link=topic=16498.msg166864#msg166864 date=1174181940] Here's how I'd do it [code]Private Function CreateString() Dim iStrLen As Integer Dim iChar As Integer Dim I As Integer Dim strString As String iStrLen = Int(Rnd * 10) + 4 For I = 1 To iStrLen iChar = Int(Rnd * 62) If iChar >= 0 And iChar <= 9 Then strString = strString & Chr$(iChar + 48) ElseIf iChar >= 10 And iChar <= 35 Then strString = strString & Chr$(iChar + 55) ElseIf iChar >= 36 And iChar <= 61 Then strString = strString & Chr$(iChar + 61) End If Next I CreateString = strString End Function[/code] Note that this isn't fully tested, and I may have made some mistakes some places. [/quote] Thanks, reality. | March 18, 2007, 1:39 AM |
Ante | [quote author=[RealityRipple] link=topic=16498.msg166864#msg166864 date=1174181940] Here's how I'd do it [code]Private Function CreateString() Dim iStrLen As Integer Dim iChar As Integer Dim I As Integer Dim strString As String iStrLen = Int(Rnd * 10) + 4 For I = 1 To iStrLen iChar = Int(Rnd * 62) If iChar >= 0 And iChar <= 9 Then strString = strString & Chr$(iChar + 48) ElseIf iChar >= 10 And iChar <= 35 Then strString = strString & Chr$(iChar + 55) ElseIf iChar >= 36 And iChar <= 61 Then strString = strString & Chr$(iChar + 61) End If Next I CreateString = strString End Function[/code] Note that this isn't fully tested, and I may have made some mistakes some places. [/quote] that's extremely inefficient. it would be better if you replaced all Int's with CInt, since they work faster. Something better is iStrLen = Fix(Rnd * 11) + 4, so that 4 and 14 have equal as many chances as the rest of the numbers. (cint rounds UP for 0.5 and higher, but Fix rounds down) Your way makes 4 and 14 half as likely as the other numbers you could change iChar = Int(Rnd * 62) If iChar >= 0 And iChar <= 9 Then strString = strString & Chr$(iChar + 48) ElseIf iChar >= 10 And iChar <= 35 Then strString = strString & Chr$(iChar + 55) ElseIf iChar >= 36 And iChar <= 61 Then strString = strString & Chr$(iChar + 61) End If into iChar = Fix(Rnd * 62) 'Int would allow 62, which wouldnt generate any character If iChar <= 9 Then iChar=iChar+48 ElseIf iChar <= 35 Then iChar=iChar+55 Else iChar=iChar+61 End If strString=strString & chr$(iChar+61) This code isn't much faster, but it does take up less room when compiled and it won't allow the possibility of iChar being 62. It also reduces many times that checking is wasted. Lastly, after modifying it a bit more, this is a better function: (This is based on RealityRipple's calculations for which char numbers work) [Code] Private Function CreateString() Dim iStrLen As Integer Dim iChar As Integer Dim I As Integer Dim strString As String iStrLen = Fix(Rnd * 10) + 4 For I = 1 To iStrLen iChar = Fix(Rnd * 62) + 48 If iChar > 9 And iChar < 36 Then iChar = iChar + 7 Else iChar = iChar + 13 End If strString = strString & Chr$(iChar) Next I CreateString = strString End Function [/Code] You can eliminate the variable I by replacing For I = 1 to iStrLen with Do until Len(strString)=iStrLen and Next I with Loop | March 22, 2007, 10:54 PM |
Barabajagal | like i said, i didn't check it at all. and Int(Rnd * 62) wouldn't allow 62. [code]Dim randval As Integer Randomize Do Until randval = 62 randval = Int(Rnd * 62) Debug.Print randval Loop MsgBox "Done"[/code] run that. it will never end. | March 22, 2007, 11:01 PM |
Ante | Brew's real problem is that no matter how he tries to make it, its gonna generate some repeats. He wants it to have no repeats. [quote author=[RealityRipple] link=topic=16498.msg167058#msg167058 date=1174604469] like i said, i didn't check it at all. and Int(Rnd * 62) wouldn't allow 62. [code]Dim randval As Integer Randomize Do Until randval = 62 randval = Int(Rnd * 62) Debug.Print randval Loop MsgBox "Done"[/code] run that. it will never end. [/quote] oh sorry i forgot that the rounding up is only with CInt also, just make sure that its int (or Fix)(rnd*11)+4 for the strlen | March 22, 2007, 11:03 PM |
Barabajagal | I don't see it saying anything about no repeats. I see it's repeating too much, and he wants it more random... | March 22, 2007, 11:42 PM |
BreW | Yes more random would be nice.. And since Rnd resets every time the program is reset, maybe i should store the last Rnd on form unload in maybe... the registry or a config file. then on the random name function I use the stored rnd value as a base value for my own random function... salted with Rnd... and creating more randomized chars yet again... | March 23, 2007, 8:15 PM |
Barabajagal | uhm... Randomize sets the random seed. Put it at the top of your function. | March 23, 2007, 8:34 PM |
BreW | [quote author=[RealityRipple] link=topic=16498.msg167130#msg167130 date=1174682040] uhm... Randomize sets the random seed. Put it at the top of your function. [/quote] I did and it's still very un-random No worries though... It's not a problem anymore. | March 23, 2007, 11:28 PM |