HOWTO - generate a alphanumeric string of a given length

  • Thread starter Thread starter Crirus
  • Start date Start date
C

Crirus

Is there a function that return some random ID like string alphanumeric?
Like this:
A35sDsd1dSGsH

Thanks
Crirus
 
Try this - OHM

Public Class StringGenerator

Public Shared Function RandomString(length As Integer) As String
Const zero As Integer = CInt("0"c)
Const nine As Integer = CInt("9"c)
Const capA As Integer = CInt("A"c)
Const capZ As Integer = CInt("Z"c)

Dim guid As Byte() = Guid.NewGuid().ToByteArray()
Dim seed As Integer = guid(0) + Machine.Shift.Left(guid(1), 8) +
Machine.Shift.Left(guid(2), 16) + Machine.Shift.Left(guid(3), 24)

Dim r As New Random(seed)

Dim s As String = Nothing
Dim i As Integer
For i = 0 To length - 1
Dim n As Integer
Do
n = r.Next(zero, capZ)
Loop While Not(n >= zero And n <= nine Or(n >= capA And n <= capZ))
s += CChar(n)
Next i

Return s
End Function 'RandomString
End Class 'StringGenerator
 
Is there a function that return some random ID like string alphanumeric?
Like this:
A35sDsd1dSGsH

Thanks
Crirus

How long do you want it?

Dim id As String = Guid.NewGuid().ToString().Replace("-", String.Empty)
Console.WriteLine(id)

That will produce a 32 character string of hex digits (0-9 and a-f),
that is statistically unique (basically, it is pretty much guarented
that it will never be duplicated).
 
What's that CInt("0"c)? doesn't work here although Asc("0"c) does, as does
Asc("0").
What's that Machine.Shift.Left? doesn't work here. I understand what it's
meant to do though.(number between 0 and &HFFFFFFFF).
I like that Random class, hadn't seen that before, but, according to the
documentation, for best performance Random should only be created once.
StringBuilder.Append is faster than String +=.
You missed the LCase characters.

My much simpler version of that same function, with default time based
seeding of Random:

Private r As New Random
'I think 255 characters should be enough, although there's no reason that
'you can't use Integer or Short instead of Byte, and have more.
Private Function RandomString(ByVal Stringlength As Byte) As String

Dim s As String = _
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim sb As New System.Text.StringBuilder

Do
sb.Append(s.Chars(r.Next(0, 61)))
Loop While sb.Length < Stringlength

Return sb.ToString

End Function

My version generated 100000 * 255character strings in 4 secs as opposed to
yours (updated to use stringbuilder and default seeding for comparison)
taking 6 secs(making the Random object a Class level Private object reduced
this to 5 secs). Without Stringbuilder yours took 23 secs and 21 secs.

Before that Random Class I used the old Rnd function and the fastest I could
get, even using Stringbuilder, was 28 secs.

So I learned something useful Today.
Thankyou

Mick Doherty
 
What version of .NET framework are you using




Mick said:
What's that CInt("0"c)? doesn't work here although Asc("0"c) does, as
does Asc("0").
What's that Machine.Shift.Left? doesn't work here. I understand what
it's meant to do though.(number between 0 and &HFFFFFFFF).
I like that Random class, hadn't seen that before, but, according to
the documentation, for best performance Random should only be created
once. StringBuilder.Append is faster than String +=.
You missed the LCase characters.

My much simpler version of that same function, with default time based
seeding of Random:

Private r As New Random
'I think 255 characters should be enough, although there's no reason
that 'you can't use Integer or Short instead of Byte, and have more.
Private Function RandomString(ByVal Stringlength As Byte) As String

Dim s As String = _
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim sb As New System.Text.StringBuilder

Do
sb.Append(s.Chars(r.Next(0, 61)))
Loop While sb.Length < Stringlength

Return sb.ToString

End Function

My version generated 100000 * 255character strings in 4 secs as
opposed to yours (updated to use stringbuilder and default seeding
for comparison) taking 6 secs(making the Random object a Class level
Private object reduced this to 5 secs). Without Stringbuilder yours
took 23 secs and 21 secs.

Before that Random Class I used the old Rnd function and the fastest
I could get, even using Stringbuilder, was 28 secs.

So I learned something useful Today.
Thankyou

Mick Doherty
 
Actually, this was converted from C# ( from an earlier version ) , so I
hadnt tested it in VB.NET.

Never mind the basic phlisophy was there.

OHM
 
It would certainly appear that way.
If, rather than a time based seed, you want a randomized seed like OHM's
original example you can update the function as follows.

\\\
Imports System.Security.Cryptography
Imports System.Text

Private Function RandomString(ByVal Stringlength As Byte) As String
Dim s As String = _
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim sb As New StringBuilder
'It's back inside the function but still only gets called once.
Static r As Random = Nothing

If r Is Nothing Then
'4 bytes needed to make an Integer (0 to 3).
Dim seed() As Byte = New Byte(3) {}
Dim rng As New RNGCryptoServiceProvider
'set the byte contents of seed() to random values.
rng.GetBytes(seed)
'use BitConverter to convert the bytearray to an Integer
r = New Random(BitConverter.ToInt32(seed, 0))
End If

Do
sb.Append(s.Chars(r.Next(0, 61)))
Loop While sb.Length < Stringlength

Return sb.ToString

End Function
///
 
Back
Top