none
VB.NET Generate a random string of numbers and letters RRS feed

  • Question

  • How can I generate a random string of 8 numbers and letters and send them to text file line by line ?
    Tuesday, April 2, 2019 7:30 AM

Answers


  • when i edit the checking duplicates code it takes about 10 min

    and then  error message "Collection was modified; enumeration operation may not execute."

    and this is my code 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim rng As Random = New Random
            Dim str As String = ""
            Dim used As List(Of String) = New List(Of String)
            used.Capacity = 10000000
            For tep As Integer = 1 To 10000000
                str = ""
    
                For n As Integer = 1 To 40
                    Dim x As Integer = rng.Next(62)
                    If x > 35 Then
                        x -= 36
                        x += &H61
                    ElseIf x > 9 Then
                        x -= 10
                        x += &H41
                    Else
                        x += &H30
                    End If
                    str &= ChrW(x)
                Next
                used.Add(str)
            Next
    
            Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test2.txt", True)
                For Each s In used
                    used.Sort()
                    Dim prev As String = used.Item(0)
                    For c As Integer = 1 To used.Count - 1
                        If prev = used.Item(c) Then
                            MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
                        End If
                        prev = used.Item(c)
                    Next
                    file.WriteLine(s)
                Next
            End Using
        End Sub


    >when i edit the checking duplicates code it takes about 10 min

    You're saying it takes 10 minutes to generate and verify that there are no
    duplicates when you create 10,000,000 - TEN million - strings of 40 characters
    each. Is that a problem? Your previously stated goal was 1,000,000 in less
    than an hour with 8-character strings.

    But if you had added the check for duplicates code correctly it would take
    less time. I can generate and check for duplicates 10,000,000 40-character
    strings in 1 minute and 20 seconds. (00:01:20.5319840)

    You've messed up the check for duplicates routine. The logic you're using is
    now illogical. Why did you put the checking code inside a loop that iterates
    as many times as there are strings in the List?  It causes the List to be
    sorted and verified over and over again - ten million times in the code
    you posted. Why did you do that?

    The verification should be done ONCE *before* the file writing is done. All you
    had to do was to insert the check for duplicates *between* the generation and
    the file writing. Here is the complete code as you should have combined the
    pieces. Note that I have switched it to use Stringbuilder instead of String
    for a slight performance gain, especially when longer strings are being
    created. I also added a Stopwatch for more precise timing checks.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rng As Random = New Random
        Dim str As StringBuilder = New StringBuilder("")
        Dim used As List(Of String) = New List(Of String)
        used.Capacity = 10000000
    
        Dim stpw As Stopwatch = Stopwatch.StartNew
        For tep As Integer = 1 To 10000000
            str.Clear()
            For n As Integer = 1 To 40
                Dim x As Integer = rng.Next(62)
                If x > 35 Then
                    x -= 36
                    x += &H61
                ElseIf x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str.Append(ChrW(x))
            Next
            used.Add(str.ToString)
        Next
    
        used.Sort()
        Dim prev As String = used.Item(0)
        For c As Integer = 1 To used.Count - 1
            If prev = used.Item(c) Then
                MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
            End If
            prev = used.Item(c)
        Next
    
        Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test2.txt", True)
            For Each s In used
                file.WriteLine(s)
            Next
        End Using
        stpw.Stop()
        Debug.WriteLine(stpw.Elapsed)
    End Sub
    

    >and then  error message "Collection was modified; enumeration operation may not execute."

    Because of your flawed logic. You are sorting the collection "used" inside a
    loop that is iterating over that same collection. Fix the code as above and
    that message will not occur.

    - Wayne

    Thursday, April 4, 2019 11:40 AM

All replies

  • How can I generate a random string of 8 numbers and letters and send them to text file line by line ?

    Before someone impetuously gives you the complete code, perhaps you can explain
    in some detail which part of this task you can't handle. 

    Do you know how to generate random numbers? 

    Do you know how to build a string?

    Do you know how to create a text file and write lines to it?

    You should be able to do at least some of this task yourself. If so, then you
    should show us what you have been able to code so far. Then we can help with
    the missing pieces, rather than providing a full solution for you to copy.

    - Wayne

    Tuesday, April 2, 2019 7:56 AM
  • Hi,

    I made a demo,you can try it,add a random string of 8 numbers and letters into txt file.

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            
        End Sub
        Public Function GenerateRandom(ByVal Length As Integer) As String
            Dim constant As Char() = {"0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c, "a"c, "b"c, "c"c, "d"c, "e"c, "f"c, "g"c, "h"c, "i"c, "j"c, "k"c, "l"c, "m"c, "n"c, "o"c, "p"c, "q"c, "r"c, "s"c, "t"c, "u"c, "v"c, "w"c, "x"c, "y"c, "z"c, "A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
    
            Dim newRandom As System.Text.StringBuilder = New System.Text.StringBuilder(constant.Length)
            Dim rd As Random = New Random()
    
            For i As Integer = 0 To Length - 1
                newRandom.Append(constant(rd.[Next](constant.Length)))
            Next
    
            Return newRandom.ToString()
    
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test.txt", True)
                file.WriteLine(GenerateRandom(8))
            End Using
        End Sub
    End Class

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.



    Tuesday, April 2, 2019 7:58 AM
  • hi alex 

    thanks for your reply

    i tried your function but every time i run it after code correction its give me the same random text

    in all lines 

    all what i need to create new random string in every line

    my head 

    any idea

    thanks more

    Hossam

    Tuesday, April 2, 2019 8:41 AM
  • Hi,

    I tried my code,it doesn't appear as you say the same random text problem,please provide your code.

    

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 2, 2019 8:49 AM
  • Imports System.IO
    Imports System.Text
    Public Class Form1
        Public Function GenerateRandom(ByVal Length As Integer) As String
            Dim constant As Char() = {"0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c, "a"c, "b"c, "c"c, "d"c, "e"c, "f"c, "g"c, "h"c, "i"c, "j"c, "k"c, "l"c, "m"c, "n"c, "o"c, "p"c, "q"c, "r"c, "s"c, "t"c, "u"c, "v"c, "w"c, "x"c, "y"c, "z"c, "A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
            Dim newRandom As System.Text.StringBuilder = New System.Text.StringBuilder(constant.Length)
            Dim rd As Random = New Random()
            For i As Integer = 0 To Length - 1
                newRandom.Append(constant(rd.[Next](constant.Length)))
            Next
            Return newRandom.ToString()
        End Function
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                End Sub
        
        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            For i As Integer = 1 To 10
                Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test.txt", True)
                    file.WriteLine(GenerateRandom(40))
                End Using
            Next
        End Sub

    Tuesday, April 2, 2019 9:06 AM
  • hi alex 

    i tried your function but every time i run it after code correction its give me the same random text

    in all lines 

    all what i need to create new random string in every line


    While you're playing with Alex's demo, here's another example for you to
    experiment with:

    Sub Main()
        Dim rng As Random = New Random
        Dim str As String = ""
    
        For tep As Integer = 1 To 20
            str = ""
    
            For n As Integer = 1 To 8
                Dim x As Integer = rng.Next(36)
                If x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str &= ChrW(x)
            Next
            Console.WriteLine(str)
    
        Next
    
        Console.ReadLine()
    End Sub
    

    Sample output:

    D1HWOTJW
    M35FGNPG
    KXVVWNAK
    ZIL9KHGY
    7NY52B2W
    2G0QODP3
    6RCEO6RQ
    QWW57AC4
    N68TPJD8
    UZTGNKWM
    TH2S52A1
    V8E6EXOR
    4V2H5WEN
    D3JOCB26
    Z9BQ7JZL
    W6XG57TX
    B1BRHFHX
    2FF1ILOK
    5865LXKK
    WHLYYXH6

    - Wayne

    Tuesday, April 2, 2019 9:07 AM
  • ok king wayne 

    can you convert your code adding 40 completely different string in the last 40 lines in text file ( with 

    one button click )


    Tuesday, April 2, 2019 9:21 AM
  • Hi,

    try the code:

      For i As Integer = 1 To 10
                Threading.Thread.Sleep(50)
                Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test.txt", True)
                    file.WriteLine(GenerateRandom(40))
    
                End Using
            Next

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 2, 2019 9:22 AM
  • too long time creation

    and when i edit the sleeping time its duplicate some lines

    i think i tried this method before 

    Tuesday, April 2, 2019 9:52 AM
  • Hi,

    If you don't want to reduce execution efficiency,fix the GenerateRandom function:

    full code:

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        End Sub
        Public Function GenerateRandom(ByVal Length As Integer) As String
            Dim constant As Char() = {"0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c, "a"c, "b"c, "c"c, "d"c, "e"c, "f"c, "g"c, "h"c, "i"c, "j"c, "k"c, "l"c, "m"c, "n"c, "o"c, "p"c, "q"c, "r"c, "s"c, "t"c, "u"c, "v"c, "w"c, "x"c, "y"c, "z"c, "A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
    
            Dim newRandom As System.Text.StringBuilder = New System.Text.StringBuilder(constant.Length)
    
    
            For i As Integer = 0 To Length - 1
                newRandom.Append(constant(New Random(Guid.NewGuid().GetHashCode()).Next(constant.Length)))
    
            Next
    
            Return newRandom.ToString()
    
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            For i As Integer = 1 To 10
                Dim t As String = GenerateRandom(40)
                Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test.txt", True)
                    file.WriteLine(t)
                End Using
            Next
        End Sub
    End Class
    

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 2, 2019 10:01 AM
  • ok king wayne 

    can you convert your code adding 40 completely different string in the last 40 lines in text file ( with 

    one button click )


    Well sure I *can*, but I don't see why I should do it. I'm sure you know how
    to add button click event code to your program. You also have an example already
    of writing lines to a text file. Do you not intend to do any programming yourself?

    *Most* of us in these forums resist requests to provide complete programs.
    The forums are not intended to be a source of free programming. Providing
    complete solutions is what many of the professionals who reply here do for
    a living. The forums also are not supposed to be used for helping students
    plagiarize.

    As to your added requirement that there be no duplicate lines, mathematical
    probability suggests that it is unlikely to happen. However, to guarantee that
    it doesn't you simply have to keep track of the strings used and skip any
    duplicates. You can use any container of choice, but a List is probably the
    easiest and most suitable. My example again with code added to prevent
    duplicates:

    Sub Main()
        Dim rng As Random = New Random
        Dim str As String = ""
        Dim used As List(Of String) = New List(Of String)
    
        For tep As Integer = 1 To 40
            str = ""
    
            For n As Integer = 1 To 8
                Dim x As Integer = rng.Next(36)
                If x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str &= ChrW(x)
            Next
            If used.Contains(str) Then
                'Console.WriteLine("Skipping duplicate {0}", str)
                'Console.ReadLine()
                tep -= 1
            Else
                Console.WriteLine(str)
                used.Add(str)
            End If
    
        Next
    
        Console.ReadLine()
    End Sub
    

    - Wayne

    Tuesday, April 2, 2019 10:56 AM
  • too long time creation

    and when i edit the sleeping time its duplicate some lines

    i think i tried this method before 

    If you're still having issues with duplicates using Alex's code, try moving
    the random object outside of the method. Make it a class object instead:

    Public Class Form1
        Dim rd As Random = New Random()
        Public Function GenerateRandom(ByVal Length As Integer) As String
            Dim constant As Char() = {"0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c, "a"c, "b"c, "c"c, "d"c, "e"c, "f"c, "g"c, "h"c, "i"c, "j"c, "k"c, "l"c, "m"c, "n"c, "o"c, "p"c, "q"c, "r"c, "s"c, "t"c, "u"c, "v"c, "w"c, "x"c, "y"c, "z"c, "A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
            Dim newRandom As System.Text.StringBuilder = New System.Text.StringBuilder(constant.Length)
            'Dim rd As Random = New Random()
    
    

    - Wayne

    Tuesday, April 2, 2019 10:59 AM
  • ok king wayne 

    can you convert your code adding 40 completely different string in the last 40 lines in text file ( with 

    one button click )


    You can try this adaptation of my example in a WinForms app:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rng As Random = New Random
        Dim str As String = ""
        Dim used As List(Of String) = New List(Of String)
    
        For tep As Integer = 1 To 40
            str = ""
    
            For n As Integer = 1 To 8
                Dim x As Integer = rng.Next(36)
                If x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str &= ChrW(x)
            Next
            If used.Contains(str) Then
                tep -= 1
            Else
                used.Add(str)
            End If
    
        Next
    
        Using file As System.IO.StreamWriter = New System.IO.StreamWriter("testout.txt", True)
            For Each s In used
                file.WriteLine(s)
            Next
        End Using
    End Sub
    

    Note that this doesn't check for duplicates already in the file before adding
    new lines. It only ensures that there are no duplicates in the lines being added.

    - Wayne

    Tuesday, April 2, 2019 11:19 AM
  • If you want both upper and lower case letters using my examples:

        For n As Integer = 1 To 8
            Dim x As Integer = rng.Next(62)
            If x > 35 Then
                x -= 36
                x += &H61
            ElseIf x > 9 Then
                x -= 10
                x += &H41
            Else
                x += &H30
            End If
            str &= ChrW(x)
        Next
    

    - Wayne

    Tuesday, April 2, 2019 11:50 AM
  • Hello,

    Here is a solution with random chars and numbers with a length of 8 written to a file in the executable folder.

    Imports System.IO
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) _
            Handles Button1.Click
    
            Dim fileName As String = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "serialNumbers.txt")
    
            Dim serialNumbersList As New List(Of String)
    
            For index = 1 To 10
                serialNumbersList.Add(GetSerialNumber())
            Next
    
            File.WriteAllLines(fileName, serialNumbersList.ToArray())
        End Sub
        Private Function GetSerialNumber() As String
    
            Dim serialGuid As Guid = Guid.NewGuid()
            Dim uniqueSerial As String = serialGuid.ToString("N")
            Dim uniqueSerialLength As String = uniqueSerial.Substring(0, 8).ToUpper()
    
            Dim serialArray As Char() = uniqueSerialLength.ToCharArray()
            Dim finalSerialNumber As String = ""
    
            Dim outerIndex As Integer = 0
    
            For innerIndex As Integer = 0 To 7
                For outerIndex = innerIndex To 4 + (innerIndex - 1)
                    finalSerialNumber += serialArray(outerIndex)
                Next
                If outerIndex = 8 Then
                    Exit For
                Else
                    innerIndex = (outerIndex) - 1
                    finalSerialNumber += ""
                End If
            Next
    
            Return finalSerialNumber
        End Function
    End Class
    
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, April 2, 2019 12:00 PM
    Moderator
  • This function shows the generation of random strings of specified length.  Apps only need one Random.

        Private Shared PRNG As New Random
        Const ValidChars As String = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Private Function GenRand(Len As Integer) As String
            Dim rv As New System.Text.StringBuilder
            For idx As Integer = 1 To Len
                rv.Append(ValidChars(PRNG.Next(ValidChars.Length)))
            Next
            Return rv.ToString
        End Function

    Then to write lines to file

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'create path of file 
            Dim p As String
            p = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            p = IO.Path.Combine(p, "test.txt")
            Dim sb As New System.Text.StringBuilder
            If Not IO.File.Exists(p) Then
                IO.File.WriteAllText(p, sb.ToString)
            End If
            sb.Append(IO.File.ReadAllText(p)) 'get file contents
            For x As Integer = 1 To 5 'write five lines
                Dim s As String = GenRand(8)
                sb.AppendLine(s)
            Next
            IO.File.WriteAllText(p, sb.ToString)
    
            'file contents
            'r2Vk9C7Y
            'NWhO7wgJ
            'wYWL2Snu
            'bTYbyQAv
            'RJe08NwA
    
        End Sub
    


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein



    • Edited by dbasnett Tuesday, April 2, 2019 5:13 PM
    Tuesday, April 2, 2019 1:27 PM
  • more and more and more

    this method just used the upper case letters 

    i need all ( upper and lower case and numbers from 0 to 9 )

    thanks all

    Tuesday, April 2, 2019 4:31 PM
  • Are we having fun yet?

    Here's another variation:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rng As Random = New Random
        Dim str As String = ""
        Dim used As List(Of String) = New List(Of String)
        For tep As Integer = 1 To 40
            str = ""
            Dim x As Integer = 0
            For n As Integer = 1 To 8
                Dim y As Int32 = rng.Next(1, 4)
                If y = 1 Then x = rng.Next(48, 58)  ' 0-9
                If y = 2 Then x = rng.Next(65, 91)  ' A-Z
                If y = 3 Then x = rng.Next(97, 123) ' a-z
                str &= ChrW(x)
            Next
            If used.Contains(str) Then
                tep -= 1
            Else
                used.Add(str)
            End If
        Next
    
        Using file As System.IO.StreamWriter = New System.IO.StreamWriter("testout.txt", True)
            For Each s In used
                file.WriteLine(s)
            Next
        End Using
    End Sub
    

    - Wayne

    Tuesday, April 2, 2019 5:01 PM

  •             If y = 1 Then x = rng.Next(48, 58)  ' 0-9
                If y = 2 Then x = rng.Next(65, 91)  ' A-Z
                If y = 3 Then x = rng.Next(97, 123) ' a-z
    

    In my last example, if you're not comfortable with using the numeric values
    for the characters, you can use this instead:

    If y = 1 Then x = rng.Next(AscW("0"), AscW("9") + 1)  ' 0-9
    If y = 2 Then x = rng.Next(AscW("A"), AscW("Z") + 1)  ' A-Z
    If y = 3 Then x = rng.Next(AscW("a"), AscW("z") + 1)  ' a-z
    

    - Wayne

    Tuesday, April 2, 2019 5:43 PM
  • more and more and more

    this method just used the upper case letters 

    i need all ( upper and lower case and numbers from 0 to 9 )

    thanks all

    Your question never indicated lower and upper case characters


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, April 2, 2019 6:29 PM
    Moderator
  • I cant let everyone else have all the fun!

    Here is my 2 cents. This will use Now.Milliseconds as a seed but only if its a different Millis every iteration.

    Public Class FormRandomNum
        Dim Millis As Integer = 0
        Private Sub ButtonRdm_Click(sender As Object, e As EventArgs) Handles ButtonRdm.Click
            Dim SerialsToWrite As Integer = 100
            Dim SerialLength As Integer = 10
            Dim MySavePath As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\MySerials.txt"
    
            Dim MySerials = My.Computer.FileSystem.OpenTextFileWriter(MySavePath, True)
    
            For i As Integer = 0 To SerialsToWrite
                MySerials.WriteLine(GetRnd(SerialLength))
            Next
    
            MySerials.Close()
        End Sub
    
        Private Function GetRnd(ByVal Len As Integer) As String
            While Millis = Now.Millisecond
                Millis = Now.Millisecond
            End While
            Millis = Now.Millisecond
    
            Dim Chars() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray
            Dim RandNum As New Random(Millis)
            Dim ReturnStr As String = String.Empty
            Do Until ReturnStr.Length = Len
                ReturnStr += Chars(RandNum.Next(0, Chars.Length))
            Loop
            Return ReturnStr
        End Function
    
    End Class


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi

    Tuesday, April 2, 2019 9:37 PM
  • Okay, this one does upper/lower/digits

    RandomKeyGenerator code.

    Regular expression.

    Imports System.IO
    Imports System.Text
    
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) _
            Handles Button1.Click
    
            Dim fileName As String = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "serialNumbers.txt")
    
            Dim serialNumbersList As New List(Of String)
            Dim serialNumberCount As Integer = 0
            Dim keyGen As RandomKeyGenerator
            Dim numberToTry As Integer = 20
            Dim randomKey As String
    
            keyGen = New RandomKeyGenerator With {
                .KeyLetters = "abcdefghijklmnopqrstuvwxyz",
                .KeyNumbers = "0123456789",
                .KeyChars = 8
            }
    
            Dim mustHaveUpperLowerDigitSpecificLen =
                    "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$"
    
            For index As Integer = 1 To numberToTry
                randomKey = keyGen.Generate()
                If RegularExpressions.Regex.IsMatch(randomKey, mustHaveUpperLowerDigitSpecificLen) Then
                    serialNumberCount += 1
                    serialNumbersList.Add(randomKey)
                End If
    
                If serialNumberCount = 10 Then
                    Exit For
                End If
    
            Next
    
            File.WriteAllLines(fileName, serialNumbersList.ToArray())
    
        End Sub
    End Class
    
    Public Class RandomKeyGenerator
        Dim _keyLetters As String
        Dim _keyNumbers As String
        Dim _keyChars As Integer
        Dim _lettersArray As Char()
        Dim _numbersArray As Char()
    
        Protected Friend WriteOnly Property KeyLetters() As String
            Set
                _keyLetters = Value
            End Set
        End Property
        Protected Friend WriteOnly Property KeyNumbers() As String
            Set(value As String)
                _keyNumbers = value
            End Set
        End Property
        Protected Friend WriteOnly Property KeyChars() As Integer
            Set
                _keyChars = Value
            End Set
        End Property
        Function Generate() As String
            Dim random1 As Single
            Dim arrIndex As Short
            Dim sb As New StringBuilder
            Dim randomLetter As String
    
            _lettersArray = _keyLetters.ToCharArray
            _numbersArray = _keyNumbers.ToCharArray
    
            For index = 1 To _keyChars
                Randomize()
                random1 = Rnd()
                arrIndex = -1
    
                If (CType(random1 * 111, Integer)) Mod 2 = 0 Then
                    Do While arrIndex < 0
                        arrIndex =
                         Convert.ToInt16(_lettersArray.GetUpperBound(0) _
                         * random1)
                    Loop
                    randomLetter = _lettersArray(arrIndex)
    
                    If (CType(arrIndex * random1 * 99, Integer)) Mod 2 <> 0 Then
                        randomLetter = _lettersArray(arrIndex).ToString
                        randomLetter = randomLetter.ToUpper
                    End If
                    sb.Append(randomLetter)
                Else
                    Do While arrIndex < 0
                        arrIndex = Convert.ToInt16(_numbersArray.GetUpperBound(0) * random1)
                    Loop
                    sb.Append(_numbersArray(arrIndex))
                End If
            Next
    
            Return sb.ToString
    
        End Function
    End Class


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, April 2, 2019 10:54 PM
    Moderator
  • Thirty minutes and just 66k keys

    my target is 1m keys less than 1 hour

    Is there a faster way

    Wednesday, April 3, 2019 8:11 AM
  • Thirty minutes and just 66k keys

    my target is 1m keys less than 1 hour

    Is there a faster way

    Since many of us don't use the "threaded view" when reading these forums it is
    impossible for us to know which post and suggested code you have timed. Always
    give a clue in your replies as to what your are referring.

    Since you were given multiple suggested techniques, if you want to know which 
    is fastest you need to time all of them under the same conditions. That means 
    you have to ensure that nothing else runs at the same time that might steal
    cycles. Or profile each of them.

    I would suggest that the fastest will probably be which ever one makes the least
    number of calls to library functions. The more compact and self-contained code
    will probably be the fastest. Or you can upgrade the hardware which you are using.
    Or use a different language which provides better optimization customization.

    Incidentally, constantly changing the specifications or requirements after code
    has been provided is a good way to annoy people as it can be perceived as
    wasting others' time IMO.

    - Wayne


    • Edited by WayneAKing Wednesday, April 3, 2019 10:19 AM
    Wednesday, April 3, 2019 10:17 AM

  • Is there a faster way

    Don't forget to time Release builds and not Debug builds. Also be sure to try
    with Optimizations enabled in the project's Advanced Compiler Settings.

    - Wayne

    Wednesday, April 3, 2019 10:25 AM
  • Thirty minutes and just 66k keys

    my target is 1m keys less than 1 hour

    Is there a faster way

    I didnt realize there was this requirement.

    A slight alteration of my previous suggestion, this should give you 1,000,000 serials at 16chars each in about 5 seconds (change SerialsToWrite value to 1000000)

    Public Class FormRandomNum
        Dim SeedCount As Integer = 0
        Private Sub ButtonRdm_Click(sender As Object, e As EventArgs) Handles ButtonRdm.Click
            Dim StWtch As New Stopwatch
            StWtch.Start()
            Dim SerialsToWrite As Integer = 10000
            Dim SerialLength As Integer = 16
            Dim MySavePath As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\MySerials.txt"
    
            Dim MySerials = My.Computer.FileSystem.OpenTextFileWriter(MySavePath, True)
    
            For i As Integer = 0 To SerialsToWrite
                MySerials.WriteLine(GetRnd(SerialLength))
                SeedCount += 1
            Next
    
            MySerials.Close()
            MsgBox(StWtch.ElapsedMilliseconds)
        End Sub
    
        Private Function GetRnd(ByVal Len As Integer) As String
            Dim Chars() As Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray
            Dim RandNum As New Random(SeedCount)
            Dim ReturnStr As String = String.Empty
    
            Do Until ReturnStr.Length = Len
                ReturnStr += Chars(RandNum.Next(0, Chars.Length))
            Loop
    
            Return ReturnStr
        End Function
    
    End Class


    Live as if you were going to die today, learn as if you were going to live forever -Mahatma Gandhi


    • Edited by Gtripodi Wednesday, April 3, 2019 1:32 PM
    Wednesday, April 3, 2019 12:31 PM
  • Thirty minutes and just 66k keys

    my target is 1m keys less than 1 hour

    Is there a faster way

    This code generated 100,000 8 character keys in less than 40 ms.

        Private Shared PRNG As New Random
        Const ValidChars As String = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Private Function GenRand(Len As Integer) As String
            Dim rv As New System.Text.StringBuilder
            For idx As Integer = 1 To Len
                rv.Append(ValidChars(PRNG.Next(ValidChars.Length)))
            Next
            Return rv.ToString
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'create path of file 
            Dim p As String
            p = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            p = IO.Path.Combine(p, "test.txt")
            Dim sb As New System.Text.StringBuilder(1024 * 1024 * 10)
            Dim stpw As Stopwatch = Stopwatch.StartNew
            If Not IO.File.Exists(p) Then
                IO.File.WriteAllText(p, sb.ToString)
            End If
            sb.Append(IO.File.ReadAllText(p)) 'get file contents
            For x As Integer = 1 To 100000
                Dim s As String = GenRand(8)
                sb.AppendLine(s)
            Next
            IO.File.WriteAllText(p, sb.ToString)
            stpw.Stop()
            Debug.WriteLine(stpw.Elapsed)
        End Sub
    


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Wednesday, April 3, 2019 1:06 PM
  • Thirty minutes and just 66k keys

    my target is 1m keys less than 1 hour

    Is there a faster way

    FWIW, if you run my original code *without* the shown method of checking each
    number for duplication - via the used.contains() - then it will generate
    1,000,000 strings in 5 seconds or less.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rng As Random = New Random
        Dim str As String = ""
        Dim used As List(Of String) = New List(Of String)
        used.Capacity = 1000000
        For tep As Integer = 1 To 1000000
            str = ""
    
            For n As Integer = 1 To 8
                Dim x As Integer = rng.Next(62)
                If x > 35 Then
                    x -= 36
                    x += &H61
                ElseIf x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str &= ChrW(x)
            Next
            used.Add(str)
        Next
    
        Using file As System.IO.StreamWriter = New System.IO.StreamWriter("testW.txt", True)
            For Each s In used
                file.WriteLine(s)
            Next
        End Using
    End Sub
    

    Adding code to check the list for duplicate strings after creation and before
    writing to the file added a few more seconds: Approximately 10 seconds in total.

    used.Sort()
    Dim prev As String = used.Item(0)
    For c As Integer = 1 To used.Count - 1
        If prev = used.Item(c) Then
            MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
        End If
        prev = used.Item(c)
    Next
    

    On repeated tests, most of the time there were no duplicate strings in the
    1 million generated. Occasionally there was one in a million.

    Note that not all of the solutions suggested in this thread *explicitly* check
    for duplicate strings.

    - Wayne

    Wednesday, April 3, 2019 2:46 PM
  • @WayneAKing - FWIW, you are aware that the reason the code takes so long to generate 1,000,000 is because of how you create them and how they are written to the file.  I re-ran my code to see how long it took to generate 1,000,000 and it was the same as 100,000. 

    When I appended a million keys to the existing million the run time was still less that 40 ms.

    The timings I have do not surprise me because I am running in the VS IDE in debug mode.


    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein


    • Edited by dbasnett Wednesday, April 3, 2019 3:29 PM
    Wednesday, April 3, 2019 3:29 PM
  • @WayneAKing - FWIW, you are aware that the reason the code takes so long to generate 1,000,000 is because of how you create them and how they are written to the file.  I re-ran my code to see how long it took to generate 1,000,000 and it was the same as 100,000. 

    When I appended a million keys to the existing million the run time was still less that 40 ms.


    I don't know where you get "takes so long" from - since I said my code took
    "5 seconds or less" to generate 1,000,000 strings. A considerable improvement
    over what the OP was complaining about with the code that took

    "Thirty minutes and just 66k keys"

    That time of < 5 secs was "eyeballed" using a sweep second hand from the time
    I clicked on the button. By actual measurement using Stopwatch I'm seeing
    times to generate the lines to a file (without including a "paranoid' check
    for duplicates) such as 00:00:01.5400842

    That's well within the OP's requirement of generating 1 million strings in
    under an hour.

    >When I appended a million keys to the existing million the run time was still
    >less that 40 ms.

    You may be seeing times such as that on *your* system, but it needs a "YMMV"
    attached. Running *your* code on *my* system I see times such as

    00:00:00.5501265
    00:00:00.6355056
    00:00:00.5133958
    00:00:00.6515533

    That's 513-651 ms. Nowhere close to what you're reporting.

    In any event, I'm not one to sweat the small stuff. If my method takes 1.5
    seconds and yours takes .5 seconds, that's optimal enough for the purposes
    of this thread as far as I'm concerned. If NASA makes me an offer I can't
    refuse I may alter my sleep and work habits, but not for this thread. And
    not without adequate compensation. ;-)

    - Wayne

    Wednesday, April 3, 2019 5:28 PM
  • I don't know where you get "takes so long" from - since I said my code took
    "5 seconds or less" to generate 1,000,000 strings. A considerable improvement
    over what the OP was complaining about with the code that took

    "Thirty minutes and just 66k keys"

    That time of < 5 secs was "eyeballed" using a sweep second hand from the time
    I clicked on the button. By actual measurement using Stopwatch I'm seeing
    times to generate the lines to a file (without including a "paranoid' check
    for duplicates) such as 00:00:01.5400842

    That's well within the OP's requirement of generating 1 million strings in
    under an hour.

    >When I appended a million keys to the existing million the run time was still
    >less that 40 ms.

    You may be seeing times such as that on *your* system, but it needs a "YMMV"
    attached. Running *your* code on *my* system I see times such as

    00:00:00.5501265
    00:00:00.6355056
    00:00:00.5133958
    00:00:00.6515533

    That's 513-651 ms. Nowhere close to what you're reporting.

    In any event, I'm not one to sweat the small stuff. If my method takes 1.5
    seconds and yours takes .5 seconds, that's optimal enough for the purposes
    of this thread as far as I'm concerned. If NASA makes me an offer I can't
    refuse I may alter my sleep and work habits, but not for this thread. And
    not without adequate compensation. ;-)

    - Wayne

    The times were ancillary to the real point I was trying to make, how you generated the keys.  A lot of us that post here frequently understand what your code does.  I wonder if the OP does?  It just surprised me.

    Search Documentation

    SerialPort Info

    Multics - An OS ahead of its time.

     "Those who use Application.DoEvents have no idea what it does

        and those who know what it does never use it."    former MSDN User JohnWein

    Wednesday, April 3, 2019 7:42 PM
  • Quoting myself:

    By actual measurement using Stopwatch I'm seeing
    times to generate the lines to a file (without including a "paranoid' check
    for duplicates) such as 00:00:01.5400842

    Footnote: Motivated purely by curiosity I tried my example code again using
    Stringbuilder instead of String to create the 8-character strings. It reduced
    the sample execution times for 1,000,000 strings to values such as:

    00:00:00.8943471
    00:00:00.8631372
    00:00:00.8544377

    - Wayne

    Wednesday, April 3, 2019 8:26 PM
  • dear wayne

    when i edit the checking duplicates code it takes about 10 min

    and then  error message "Collection was modified; enumeration operation may not execute."

    and this is my code 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim rng As Random = New Random
            Dim str As String = ""
            Dim used As List(Of String) = New List(Of String)
            used.Capacity = 10000000
            For tep As Integer = 1 To 10000000
                str = ""
    
                For n As Integer = 1 To 40
                    Dim x As Integer = rng.Next(62)
                    If x > 35 Then
                        x -= 36
                        x += &H61
                    ElseIf x > 9 Then
                        x -= 10
                        x += &H41
                    Else
                        x += &H30
                    End If
                    str &= ChrW(x)
                Next
                used.Add(str)
            Next
    
            Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test2.txt", True)
                For Each s In used
                    used.Sort()
                    Dim prev As String = used.Item(0)
                    For c As Integer = 1 To used.Count - 1
                        If prev = used.Item(c) Then
                            MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
                        End If
                        prev = used.Item(c)
                    Next
                    file.WriteLine(s)
                Next
            End Using
        End Sub


    Thursday, April 4, 2019 9:26 AM

  • when i edit the checking duplicates code it takes about 10 min

    and then  error message "Collection was modified; enumeration operation may not execute."

    and this is my code 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim rng As Random = New Random
            Dim str As String = ""
            Dim used As List(Of String) = New List(Of String)
            used.Capacity = 10000000
            For tep As Integer = 1 To 10000000
                str = ""
    
                For n As Integer = 1 To 40
                    Dim x As Integer = rng.Next(62)
                    If x > 35 Then
                        x -= 36
                        x += &H61
                    ElseIf x > 9 Then
                        x -= 10
                        x += &H41
                    Else
                        x += &H30
                    End If
                    str &= ChrW(x)
                Next
                used.Add(str)
            Next
    
            Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test2.txt", True)
                For Each s In used
                    used.Sort()
                    Dim prev As String = used.Item(0)
                    For c As Integer = 1 To used.Count - 1
                        If prev = used.Item(c) Then
                            MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
                        End If
                        prev = used.Item(c)
                    Next
                    file.WriteLine(s)
                Next
            End Using
        End Sub


    >when i edit the checking duplicates code it takes about 10 min

    You're saying it takes 10 minutes to generate and verify that there are no
    duplicates when you create 10,000,000 - TEN million - strings of 40 characters
    each. Is that a problem? Your previously stated goal was 1,000,000 in less
    than an hour with 8-character strings.

    But if you had added the check for duplicates code correctly it would take
    less time. I can generate and check for duplicates 10,000,000 40-character
    strings in 1 minute and 20 seconds. (00:01:20.5319840)

    You've messed up the check for duplicates routine. The logic you're using is
    now illogical. Why did you put the checking code inside a loop that iterates
    as many times as there are strings in the List?  It causes the List to be
    sorted and verified over and over again - ten million times in the code
    you posted. Why did you do that?

    The verification should be done ONCE *before* the file writing is done. All you
    had to do was to insert the check for duplicates *between* the generation and
    the file writing. Here is the complete code as you should have combined the
    pieces. Note that I have switched it to use Stringbuilder instead of String
    for a slight performance gain, especially when longer strings are being
    created. I also added a Stopwatch for more precise timing checks.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rng As Random = New Random
        Dim str As StringBuilder = New StringBuilder("")
        Dim used As List(Of String) = New List(Of String)
        used.Capacity = 10000000
    
        Dim stpw As Stopwatch = Stopwatch.StartNew
        For tep As Integer = 1 To 10000000
            str.Clear()
            For n As Integer = 1 To 40
                Dim x As Integer = rng.Next(62)
                If x > 35 Then
                    x -= 36
                    x += &H61
                ElseIf x > 9 Then
                    x -= 10
                    x += &H41
                Else
                    x += &H30
                End If
                str.Append(ChrW(x))
            Next
            used.Add(str.ToString)
        Next
    
        used.Sort()
        Dim prev As String = used.Item(0)
        For c As Integer = 1 To used.Count - 1
            If prev = used.Item(c) Then
                MessageBox.Show("Warning! string " & prev & " has duplicate(s)!")
            End If
            prev = used.Item(c)
        Next
    
        Using file As System.IO.StreamWriter = New System.IO.StreamWriter("D:\test2.txt", True)
            For Each s In used
                file.WriteLine(s)
            Next
        End Using
        stpw.Stop()
        Debug.WriteLine(stpw.Elapsed)
    End Sub
    

    >and then  error message "Collection was modified; enumeration operation may not execute."

    Because of your flawed logic. You are sorting the collection "used" inside a
    loop that is iterating over that same collection. Fix the code as above and
    that message will not occur.

    - Wayne

    Thursday, April 4, 2019 11:40 AM
  • dear wayne

    in fact my pc was heated with some virus encryped all my 10 years data

    i didn't find any decrypter on the internet can help me to decrypt my files

    and now i try to generate all 40 character keys we can make with vb in text file

    and try to decrypt 1kb file with those keys one by one for 10000 tries per click

    i put all keys in .txt file

    every line contain one key

    first 10000 lines meaning 10000 keys meaning 10000 tries

    if false then delete them

    and take next 10000 lines or keys etc.

    that is all 

    best thanks to you All

    Hossam




    Thursday, April 4, 2019 12:25 PM