Forum Moderators: open

Message Too Old, No Replies

random sequence of letters

how to generate a truly random sequence of letters

         

topr8

3:17 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



am having a problem generating a truly random sequence of letters in asp,

am using the following code to write a string of 15 letters ...

For intCounter = 1 To 15
' Generate a random number between 65 and 90.
Randomize
intDecimal = Int((26 * Rnd) + 1) + 96
str = str & Chr(intDecimal)
Next

but it turns out that it is not generating a unique string as i thought it would, they are coming out unique but a great many are duplicates, am i doing something wrong, or is my error entirely elsewhere. thanks

john_k

3:25 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Randomize uses the current time as the default seed. So in your code, it is likely being repeatedly called within the same millisecond. Move it up above the For statement and that should clear it up.

john_k

3:30 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I should have added, if you are calling this function from another loop, then the Randomize should take place before that (for the same reason).

Btw - here is a ASP/vbScript class that I utilize for generating random strings. It returns alpha-numeric strings, but could easily be adapted to only return letters.

Also, as you will see, the CASE statements in vbScript are limiting. If this is adapted to Visual Basic or a SQL Stored Procedure, it can be cleaned up quite a bit by using ranges in the CASEs.


<SCRIPT LANGUAGE=VBScript RUNAT=Server>
' #########################################################################
' clsPwdGenerator
'
' Password Generator Class
'
' This class has one method, CreatePassword, that can be used to generate
' a random password with a variable length consisting of alpha-numeric
' characters.
' #########################################################################
Class clsPwdGenerator

Public Function CreatePassword(nMinLen, nMaxLen)

Dim i
Dim nLen
Dim sPwd
Dim sChar

sPwd = ""
nLen = (Int(Rnd * ((nMaxLen - nMinLen) + 1))) + nMinLen
For i = 1 To nLen
Do
sChar = RndChar
Loop While (sChar = "o") Or (sChar = "O") Or (sChar = "l")
sPwd = sPwd & sChar
Next

CreatePassword = sPwd

End Function

Private Function RndChar()

Dim nVal
Dim nChar

nVal = Int(Rnd * 62)
Select Case nVal
Case 0, 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
' Returns a lower case letter a-z
nChar = nVal + 97
Case 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
' Returns a digit 0-9
nChar = nVal + 22
Case 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61
' Returns an uppercase letter A-Z
nChar = nVal + 29
End Select

RndChar = Chr(nChar)

End Function

Private Sub Class_Initialize

Randomize

End Sub

End Class
</SCRIPT>

[edited by: john_k at 3:40 pm (utc) on April 8, 2004]

topr8

3:39 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



ok thanks very much, have changed it to this ...

Randomize
For intCounter = 1 To 15
' Generate a random number between 65 and 90.

intDecimal = Int((26 * Rnd) + 1) + 96
str = str & Chr(intDecimal)
Next

so far seems to work, eg just ran it a few times with no dupes, whereas before it was beginning to produce a dupe almost every time - as it had already generated 20,000 uniques.

is this what you meant? will it continue to produce unique numbers, the total number will be around 1 million at some point, i should think this should be ok, of course i check for dupes but it slows it down to keep regenerating on a dupe.

topr8

3:42 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



ok thanks a lot again, was posting while you were posting that long reply, i'm going to adapt that i think.

john_k

3:44 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



will it continue to produce unique numbers

No. It will produce random numbers.

If you want guaranteed unique numbers (but in a random order), then you will need another means.

You could use a GUID (globally unique identifier), or you could simply extract all or part of the current time and date and then add that on to the random number you are generating.

topr8

3:53 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



ok, may have to rethink and create a unique number based on the time, is there a simple way to do this?

john_k

4:05 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What is going to be done with the number? If you are simply using it as an account number (or similar type of ID), then you can let your database crank them out.

If you are using SQL Server, you have two options:
- Use an Identity column. If you don't want to ever get small numbers, then just set the initial seed to something other than 1 (which is the default).
- Otherwise you can create a column with the "Is GUID" property.

Other DBs have similar options.

To convert time and date elements to numbers, use the Now function and strip out non-numeric characters. You can also use the Second, Minute, Hour, Day, Month, and Year functions.

Once you have reasonably small increment of time, then append a random string to the end of it. You should still check for duplicates, but there should be a lot fewer collisions. And more importantly, the rate of collisions should remain stable. (with your current method, the rate will climb as you store more values)

topr8

4:17 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



the purpose is to set a unique value for a cookie, to track the visitor but also to write "last visited pages list" to the page - didn't want to use the session cookie