Random number - no duplicates

Posted on 2006-05-02
Last Modified: 2008-02-01

I have the following code:

dim low, high

low = 2
high = 99

Function ran()
ran = Int((high - low + 1) * Rnd()) + low
End Function

The function gives me a random value between 1 and 100. However, I get do I adjust the code to get rid of the duplicate-problem?

The number does not necessarily have to be an integer.

Any ideas much appreciated!
Question by:zeybrandt
    LVL 16

    Expert Comment

    What are you using the random codes for? Are you storing them anywhere? in an array or db? If you are, you can do a check to see if it matches before continuing.

    Found this code at ASP 101:

    Dim intLowerBound    ' Lower bound of the random number range
    Dim intUpperBound    ' Upper bound of the random number range

    Dim intRangeSize     ' Size of the range
    Dim sngRandomValue   ' A random value from 0 to intRangeSize
    Dim intRandomInteger ' Our final result - random integer to return

    ' Retrieve lower and upper bound requests if they're there
    ' o/w set to defaults of 0 and 100
    If IsNumeric(Request.QueryString("lowerbound")) Then
          intLowerBound = CLng(Request.QueryString("lowerbound"))
          intLowerBound = 0
    End If

    If IsNumeric(Request.QueryString("upperbound")) Then
          intUpperBound = CLng(Request.QueryString("upperbound"))
          ' Add a line to deal with default case of 0 to 0.
          ' This really isn't neccessary, but I do it so the
          ' sample doesn't default to generating a number between
          ' 0 and 0 and always return 0 when no bounds are provided.
          If intLowerBound = 0 And intUpperBound = 0 Then intUpperBound = 100
          intUpperBound = 100
    End If

    ' Check for people asking for a number from in an inappropriate
    ' range (ie: 50 to 10) and swap the bounds
    If intLowerBound > intUpperBound Then
          ' I really should've declared a temporary variable for this
          ' swapping, but I was lazy and this one was already defined
          ' and I don't use it till later... oh all right I'll do it
          ' the "right" way... actually even this is bad... I should've
          ' defined this up top... so sue me... hey it's free code what
          ' do you want from me?
          Dim iTemp
          iTemp = intLowerBound
          intLowerBound = intUpperBound
          intUpperBound = iTemp
    End If

    ' Initialize the random number generator.
    ' Randomize can actually take parameters telling it how to initialize
    ' things, but for the most you'll just want to call it without passing
    ' it anything.

    ' Generate our random number.
    ' The Rnd function does most of the work.  It returns a value in the
    ' range 0 <= value < 1 so to generate a random integer in the specified
    ' range we need to do some calculation.  Specifically we take the size
    ' of the range in which we want to generate the number (add 1 so the
    ' upper bound can be generated!) and then multiply it by our random
    ' element.  Then to place the value into the correct range of numbers
    ' we add the lower bound.  Finally we truncate the number leaving us
    ' with the integer portion which is always somewhere between the
    ' lower bound and upper bound (inclusively).

    ' Find range size
    intRangeSize = intUpperBound - intLowerBound + 1

    ' Get a random number from 0 to the size of the range
    sngRandomValue = intRangeSize * Rnd()

    ' Center the range of possible random numbers over the desired result set
    sngRandomValue = sngRandomValue + intLowerBound

    ' Convert our value to an integer
    intRandomInteger = Int(sngRandomValue)

    ' The above 4 lines are equivilent to the popular shorter version
    ' below.  I split it up so I could indicate what each step is doing.
    ' intRandomInteger = Int((intUpperBound - intLowerBound + 1) * Rnd + intLowerBound)

    ' Show out output indicating what we've done and our result.
    You asked for a random number between <B><%= intLowerBound %></B> and <B><%= intUpperBound %></B>.<BR>
    The computer returned: <B><%= intRandomInteger %></B><BR>

    <!-- Build the form for user input -->
    <FORM ACTION="random_number.asp" METHOD="get" NAME="frmRandomNumberBounds">

    Generate a random number between
    <INPUT TYPE="text" NAME="lowerbound" VALUE="<%= intLowerBound %>" SIZE="5" MAXLENGTH="5"></INPUT>
    <INPUT TYPE="text" NAME="upperbound" VALUE="<%= intUpperBound %>" SIZE="5" MAXLENGTH="5"></INPUT>

    <INPUT TYPE="submit"></INPUT>

    LVL 1

    Author Comment

    Thx for your answer.

    I removed the Int from the code above which means that I'll get a few decimals. The probability that I get duplicates is low - at least if I only use it for 128 different records.

    The problem with duplicates still exists though, it would be fun to know how to solve it.

    The value is stored in an access database.
    LVL 63

    Expert Comment

    My method is different and less coding.
    You define a List with the dimension of elements you need.
    You preset all elements in sequence order.
    Then you go from first element to last and swap that element with a random element from the List.
    That way you know that every element is occuring only once in the List.

    LVL 1

    Author Comment


    thx for your answer. I am not sure that I understand. Could you give me an example of code?

    LVL 63

    Expert Comment

    I tryed to install my IIS and it failed. So I cannot do the tested example.
    Show my your code snippet and I wil convert it to standalone VBScript with my random method.
    I mean, the upper Ran() definition gives a single shot and cannot know what previous ten or next ten hits will be.
    If you need a simelar Ran() function that hits one shot, then you need also a List and let the Ran() function take the next element from the list in the RoundRobin sequence, from first to last and then from first again.

    Like this:
    dim low, high, r, h, n
    dim rNum(99)
    low = 2
    high = 99
    For i:=0 to high
      rNum(i) = i+1
    End For
    For i:=0 to high
      r = Int(100 * Rnd())
      h = rNum(r)
      rNum(r) =  rNum(i)
      rNum(i) = h
    End For

    n = 0
    Function ran()
      ran = rNum(n)
      n = n+1
      if (n>ubound(rNum)) Then n = 0
    End Function

    LVL 12

    Accepted Solution

    Why not just create an autonumber field in Access and use that?  If you really must create a unique number on your own, you could also combine what you have with some elements of a timestamp to insure that it is unique:

    Response.Write Month(Now) & Day(Now) & Year(Now) & Hour(Now) & Minute(Now) & Second(Now) & Int((100 - 1 + 1) * Rnd()) + 1
    LVL 1

    Author Comment


    for a second I actually thought that I had forgotten the most obvious, i.e. using the Autonumber Field. But, luckily, things are a bit more complicated :)

    Your idea with the timestamp is great. Thanks!


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Top 6 Sources for Identifying Threat Actor TTPs

    Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

    Suggested Solutions

    Have you ever needed to get an ASP script to wait for a while? I have, just to let something else happen. Or in my case, to allow other stuff to happen while I was murdering my MySQL database with an update. The Original Issue This was written…
    This demonstration started out as a follow up to some recently posted questions on the subject of logging in: and…
    This video discusses moving either the default database or any database to a new volume.
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    761 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now