11

Trying to create a random string, x characters in length using 0-9 and a-z/A-Z and can't seem to find a good example, any ideas?

8 Answers8

28
Function RandomString(cb As Integer) As String

    Randomize
    Dim rgch As String
    rgch = "abcdefghijklmnopqrstuvwxyz"
    rgch = rgch & UCase(rgch) & "0123456789"

    Dim i As Long
    For i = 1 To cb
        RandomString = RandomString & Mid$(rgch, Int(Rnd() * Len(rgch) + 1), 1)
    Next

End Function

Please be aware that the built-in random number generator is not cryprographically secure so a function like this should not be used to generate passwords.

Joel Spolsky
  • 33,372
  • 17
  • 89
  • 105
  • "i" should be Long otherwise cb will accept 32767 then overflow at the end of the for-loop. – Oorang May 27 '09 at 13:03
  • 1
    Concatenate using the "&" operator, rather than "+". Note that in VB6, the result of "1" + "2" is 3 (!), while "1" & "2" is "12". In addition, I suggest using a string builder equivalent, such as the one mentioned here {http://stackoverflow.com/questions/93932/out-of-string-space-in-visual-basic-6} or just search vb6 string builder in google – Ron Klein May 30 '09 at 16:41
  • Hi @Joel Spolsky, just a feedback. I test your function in excel for 1 million calculations. Each generate a string of 13 characters and number. But there are 98459 duplicated keys generated (which is about 10%). I think the reason may related to Rnd() function, it may not be random enough so it create quite a large number of duplicated result. – Harry Duong Jan 16 '15 at 00:30
  • I test another code from the link below and it also generate duplicated records for string of 13 characters and number. in 1 million calculation, there are 13,826 duplicated records created. http://stackoverflow.com/questions/22630264/ms-access-visual-basic-generate-random-string-in-text-field – Harry Duong Jan 16 '15 at 00:32
1

I forgot all my VB6 (thank God) but in pseudocode it's pretty easy:

    all_chars = an array of all the valid chars
    seed random number generator
    for i = 1 to x do
        random_index = get a random number between 1 and length of all_chars
        'I remember how to concat and comment in VB6 :-)
        string = string & all_chars[random_index] 
    end for

    done!

So it's just a matter of finding out how to create an array and fill it with characters, how to get the length of the array and how to get a random number between the first and last indexes of said array.

Well, all that and looping of course.

Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
1

Joel's method is fine (except for the integer loop variable, and using "+" for concatenation). (-:

However, the output can be made more interesting in a couple of ways.

First, you can generate strings that have the same approximate frequency distribution as common English text, by creating a seed string with many more Ee and Tt characters than Zz characters. A string of maybe 1000 characters (double that if mixed case) in this approximate mix would work OK.

Add in equal numbers of 0..9 chars in whatever ratio you would like to see in the final output. You could also shuffle this see string to make it look more random, but it doesn't really matter.

Then use a random selector in the range of 1..Len(seedstring) to pick each character, just as in Joel's example.

Why do this? No good reason except that the results will look more familiar.

A second option is to generate two such seed strings, one of the consonants in corpus weight, and the other with the vowels in the same weighting (more E than O than U, etc). I would use just one case, not mixed case.

Then alternate two random selections, first from the consonants, then from the vowels, to generate digraphs like TI, WO, DE, and so on. Chain these together to form "words".

Because the resulting output is pronounceable, it's much more easily remembered. Plus, it looks eerily Japanese. (-:

Our Stamina library (ASM functions for VB/VBA) has routines that do these things, but it's easy enough in pure VB.

Jim Mack
  • 209
  • 1
  • 2
1

Inspired by this question I have asked a similar question where I propose using a GUID to generate the sequence. The short coming of this, as I point out, is that if there are no other flaws in my logic then it will be a random sequence of A through F and 10 digits. If you can live with the fact that letters G through Z are missing then this might be a solution for you.

Community
  • 1
  • 1
Guy
  • 65,082
  • 97
  • 254
  • 325
0

Use Randomize
Int(Rnd * high bound) + (low bound) will generate a random number
Generate an array with values from asc("a") to asc("z") and from asc("0") to asc("9")
Generate random number between 1 and 26 (10+26) and look it up in array.

Don't have VB6 installed anymore.

user1016274
  • 4,071
  • 1
  • 23
  • 19
0

If you are using SQL database you can generate a PrimaryKey like this:

SELECT NEWID() as KeyValue

It's very good way and also very secure.

cavpollo
  • 4,071
  • 2
  • 40
  • 64
adam
  • 11
  • 2
0

Using the algorith of Vinko Vrsalovic, here is the funcionay code, thanks and cya!

all_chars = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","S","T","U","V","W","X","Y","Z")
Randomize
for i = 1 to 4
   random_index = int(Rnd()*25)
clave = clave & all_chars(random_index) 
next
0

You didn't really say what you were using this for. If you need small strings (<=32,766) I think Joel's function will work fine. However if you need something to generate really large strings, this might be useful. On my system it will do a 1,000,000 char string in 0.33291015625 seconds (yes I know... sledgehammer:)) Also you can parametrize the character set so you don't have to change the code every time you want to do something "special":) :

Public Function RandomString( _
    ByVal length As Long, _
    Optional charset As String = "abcdefghijklmnopqrstuvwxyz0123456789" _
    ) As String
    Dim chars() As Byte, value() As Byte, chrUprBnd As Long, i As Long
    If length > 0& Then
        Randomize
        chars = charset
        chrUprBnd = Len(charset) - 1&
        length = (length * 2&) - 1&
        ReDim value(length) As Byte
        For i = 0& To length Step 2&
            value(i) = chars(CLng(chrUprBnd * Rnd) * 2&)
        Next
    End If
    RandomString = value
End Function
Oorang
  • 6,630
  • 1
  • 35
  • 52