Generating an array of random strings - vb.net

I'm trying to build a static array of randomly generated strings of a specific length. I've based what I have so far from here, but each index in the array has the same string, instead of a different strings. What am I doing wrong?
Dim Target As String
Target = InputBox("Input target string")
Dim StringArray(10) As String
For i = 1 To 10
StringArray(i) = GenerateString(Len(Target))
Debug.Print(StringArray(i))
Next
Function GenerateString(size As Integer) As String
Dim LegalCharacters As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim Rnd As New Random()
Dim Builder As New System.Text.StringBuilder()
Dim Ch As Char
For i As Integer = 0 To size - 1
Ch = LegalCharacters(Rnd.Next(0, LegalCharacters.Length))
Builder.Append(Ch)
Next
Return Builder.ToString()
End Function

This: Dim Rnd As New Random() is where the error happens.
When you instantiate a new Random(), it takes the current time as seed. Since you instantiate it again in every iteration AND all the iteration steps happen at the "same" time (in very fast succession), each Random() generates the same output.
You have to instantiate it once before the iterator and pass it in the function as argument or you could also make it a static property of the class.
TL;DR: You will have to re-use the same Random() instead of creating a new one for each iteration.
This should be the correct code:
Dim Target As String
Target = InputBox("Input target string")
Dim StringArray(10) As String
Dim Rnd As New Random()
For i = 1 To 10
StringArray(i) = GenerateString(Len(Target), Rnd)
Debug.Print(StringArray(i))
Next
Function GenerateString(size As Integer, Rnd as Random) As String
Dim LegalCharacters As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim Builder As New System.Text.StringBuilder()
Dim Ch As Char
For i As Integer = 0 To size - 1
Ch = LegalCharacters(Rnd.Next(0, LegalCharacters.Length))
Builder.Append(Ch)
Next
Return Builder.ToString()
End Function

Related

Parsing binary to BigInteger in VB .NET?

How are you?
I wrote a program manipulating big binary chains (string variables). This said manipulation requires me to store my chains in a variable so I can use them as numbers. The only variable type that I have found big enough to store such lengthy numbers is BigInteger (we are talking 1.0E100+).
I would like to use something like:
val = BigInteger.Parse(bin, 2)
But the second parameter needed is a NumberStyles object, which can only refer to a NumberStyles.HexNumber.
Is there a simple/optimal way to do this?
Thank you very much. :)
This converts a binary string to BigInteger in 8 bit chunks. It assumes that the binary string represents a positive number.
Private Function BinToBI(ByRef binstr As String) As BigInteger
Dim t As New List(Of Byte)
Dim s As String
Dim idx As Integer = binstr.Length
Do While idx > 0
'get 8 bits
If idx >= 8 Then
s = binstr.Substring(idx - 8, 8)
Else
s = binstr.Substring(0, idx).PadLeft(8, "0"c)
End If
'convert to byte and add to list
Dim b As Byte = Convert.ToByte(s, 2)
t.Add(b)
idx -= 8
Loop
'force to positive
If t(t.Count - 1) >= 128 Then
t.Add(0)
End If
Dim rv As New BigInteger(t.ToArray)
Return rv
End Function
for testing
Dim d As Double = 1.0E+101
Debug.WriteLine(d.ToString("n2"))
Dim bi As BigInteger
' Dim bin As String = "1111111111111111111111111111111" 'Integer.MaxValue
' Dim bin As String = "111111111111111111111111111111111111111111111111111111111111111" 'Long.MaxValue
Dim bin As String = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110"
bi = BinToBI(bin)
Debug.WriteLine(bi.ToString("n2"))
This was not well tested but should give you some ideas.

VB.net choose multiple random items from arraylist only once

So I'm trying to make a function where I can input a arraylist and the function randomly picks X amount of items from that arraylist and outputs the result to a new arraylist. This I've got working, the problem I'm having is that after one of the items is picked by the randomize, it's still there which means that it can be picked again. Here is the code I got so far
Dim RandomGeneratorMulti As New ArrayList()
Dim resultMulti As New ArrayList()
RandomGeneratorMulti.Add("Happy")
RandomGeneratorMulti.Add("Sad")
RandomGeneratorMulti.Add("Smart")
RandomGeneratorMulti.Add("Intelegt")
RandomGeneratorMulti.Add("Stupid")
RandomGeneratorMulti.Add("Ugly")
ChooseMulti("5", RandomGeneratorMulti)
TraitsListBox.Items.AddRange(resultMulti.ToArray)
Here is the function
Function ChooseMulti(ByVal Numbers As Integer, ByVal Alist As ArrayList) As ArrayList
Dim rnd = New Random()
For i As Integer = 1 To Numbers
resultMulti.Add(Alist.Item(rnd.Next(0, Alist.Count)))
Next
Return resultMulti
End Function
All help is much appreciated :)
You should use a List(Of String) rather than an ArrayList, but I have written the code below using ArrayList so that it's closer to the original.
You can remove the items that you pick from the list:
Function ChooseMulti(ByVal numbers As Integer, ByVal Alist As ArrayList) As ArrayList
Dim resultMulti As New ArrayList()
Dim rnd = New Random()
For i As Integer = 1 To numbers
Dim index As Integer = rnd.Next(Alist.Count)
resultMulti.Add(Alist.Item(index))
Alist.RemoveAt(index)
Next
Return resultMulti
End Function
Note: As you are returning the list from the function, you should get the return value and put in the resultMulti variable, and not change the variable from inside the function:
resultMulti = ChooseMulti(5, RandomGeneratorMulti)
Another method is to shuffle the list (using Fisher-Yates shuffle) and then take the first items:
Function ChooseMulti(ByVal numbers As Integer, ByVal Alist As ArrayList) As ArrayList
Dim resultMulti As New ArrayList()
Dim rnd = New Random()
For i As Integer = Alist.Count - 1 to 1 Step -1
Dim index = rnd.Next(i + 1)
Dim temp As String = Alist(i)
Alist(i) = Alist(index)
Alist(index) = temp
Next
For i As Integer = 0 To numbers - 1
resultMulti.Add(Alist.Item(i))
Next
Return resultMulti
End Function
Yet another approach is to pick numbers from the list from start to end. That way there can't be duplicates and the original list is left unchanged, but a side effect is that the picked items have the same order as in the original list:
Function ChooseMulti(ByVal numbers As Integer, ByVal Alist As ArrayList) As ArrayList
Dim resultMulti As New ArrayList()
Dim rnd = New Random()
Dim index As Integer = 0
While numbers > 0
If rnd.Next(Alist.Count - index) < numbers Then
resultMulti.Add(Alist.Item(index))
numbers -= 1
EndIf
index += 1
Wend
Return resultMulti
End Function

VB.NET - Randomize() with a function call in a string.replace method

I have a chat system and i want to put a "random string generator".
In my chat i have to write "%random%" and it is replaces with a random string.
I have a problem though, if i type "%random%%random%%random%" for example, it will generate the same string 3 times.
• Here is my function:
Public Function getRandomString(ByVal len As Integer) As String
Randomize()
Dim stringMap as string = "abcdefghijklmnopqrstuwvxyz0123456789"
Dim rndString As String = ""
Dim rnd As New Random()
For i As Integer = 0 To len - 1
Randomize()
rndString &= stringMap.Substring(rnd.Next(0, stringMap.Length), 1)
Next
Return rndString
End Function
• And here is my function call:
Dim msg As String = "Random string: %random%%random%%random%"
msg = msg.Replace("%random%", getRandomString(8))
MsgBox(msg)
The output for example: Random string: 5z15if725z15if725z15if72
I guess this is because it keeps the 1st return value in memory and pastes it, how can i fix that ?
Do i have to make a string.replace function myself ? Thanks
Oh no! You shouldn't call Randomize() here at all! Random is used in combination with the Rnd() function of VB. Creating a new Random object is enough here.
The reason you are getting the same results every time is because you are creating a new Random every time. You should reuse the same object to get different results.
'Create the object once
Private Shared rnd As New Random()
Public Function getRandomString(ByVal len As Integer) As String
Dim stringMap as string = "abcdefghijklmnopqrstuwvxyz0123456789"
Dim rndString As String = ""
For i As Integer = 0 To len - 1
rndString &= stringMap.Substring(rnd.Next(0, stringMap.Length), 1)
Next
Return rndString
End Function
EDIT: I realize that in addition to the above changes, you need to call the getRandomString function for every "%random%". String.Replace only calls the function once and pastes the result everywhere. With Regex, you could do something like this:
msg = new Regex("%random%").Replace(input, Function (match) getRandomString(8))
An easy way to do it is to find the first occurrence of "%random%", replace that, then repeat as necessary.
Written as a console application:
Option Infer On
Module Module1
Dim rand As New Random
Public Function getRandomString(ByVal len As Integer) As String
Dim stringMap As String = "abcdefghijklmnopqrstuwvxyz0123456789"
Dim rndString As String = ""
For i As Integer = 0 To len - 1
rndString &= stringMap.Substring(rand.Next(0, stringMap.Length), 1)
Next
Return rndString
End Function
Function ReplaceRandoms(s As String) As String
Dim stringToReplace = "%random%"
Dim r = s.IndexOf(stringToReplace)
While r >= 0
s = s.Remove(r, stringToReplace.Length).Insert(r, getRandomString(stringToReplace.Length))
r = s.IndexOf(stringToReplace)
End While
Return s
End Function
Sub Main()
Dim msg As String = "Random string: %random%%random%%random%"
msg = ReplaceRandoms(msg)
Console.WriteLine(msg)
Console.ReadLine()
End Sub
End Module

VB.net Split string intro multiple variables

For a school project we need to make a BoardGame, Now I have made a list of location for the NPC.
These locations are stored in a txt file named player2.txt, as followed http://pastebin.com/ZhbSvjSt
Im using the following the code to read them from the file.
http://pastebin.com/UjLSeWrQ
Dim TurnP2 As String = IO.File.ReadAllLines(".\player2.txt")(Turn)
Dim source As String = TurnP2
Dim result() As String = Split(source, ",")
But now I'm stuck, I have no clue how to splits these 3 numbers into variable.
For example Take the first row 1,1,5
I need it to place these numbers in the following variables:
CoX = 1
CoY = 1
CoZ = 5
Can anyone help me further?
Also sorry for using pastebin, but I got a strange error while trying to post.
Regards Jurre
I would create a Class:
Private Class Coords
Public coordX As Integer
Public coordY As Integer
Public coordz As Integer
End Class
And then I would fill a list:
Dim source As String() = System.IO.File.ReadAllLines(".\player2.txt")
Dim ListCoords = New List(Of Coords)
For Each Val As String In source
Dim s As String() = Val.Split(",")
ListCoords.Add(New Coords With {.coordX = s(0).ToString, _
.coordY = s(1).ToString, _
.coordz = s(2).ToString})
Next
You will have a list of loaded coordinates:
You have multiple lines, so are CoX,CoY,CoZ arrays?
You can use a loop to initialize them. Presuming always valid data:
Dim TurnP2 As String() = IO.File.ReadAllLines(".\player2.txt")
Dim CosX(TurnP2.Length - 1) As Int32
Dim CosY(TurnP2.Length - 1) As Int32
Dim CosZ(TurnP2.Length - 1) As Int32
For i As Int32 = 0 To TurnP2.Length - 1
Dim values = TurnP2(i).Split(","c)
CosX(i) = Int32.Parse(values(0))
CosY(i) = Int32.Parse(values(1))
CosZ(i) = Int32.Parse(values(2))
Next

Select any random string from a list

How can I select any random string from a given list of strings? Example:
List1: banana, apple, pineapple, mango, dragon-fruit
List2: 10.2.0.212, 10.4.0.221, 10.2.0.223
When I call some function like randomize(List1) = somevar then it will just take any string from that particular list. The result in somevar will be totally random. How can it be done? Thank you very much :)
Use Random
Dim rnd = new Random()
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Note that you have to reuse the random instance if you want to execute this code in a loop. Otherwise the values would be repeating since random is initialized with the current timestamp.
So this works:
Dim rnd = new Random()
For i As Int32 = 1 To 10
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Console.WriteLine(randomFruit)
Next
since always the same random instance is used.
But this won't work:
For i As Int32 = 1 To 10
Dim rnd = new Random()
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Console.WriteLine(randomFruit)
Next
Create a List of Strings.
Create a random number generator: Random class
Call Random number generator's NextInt() method with List.Count as the upper bound.
Return List[NextInt(List.count)].
Job done :)
Generate a random number between 1 and the size of the list, and use that as an index?
Try this:
Public Function randomize(ByVal lst As ICollection) As Object
Dim rdm As New Random()
Dim auxLst As New List(Of Object)(lst)
Return auxLst(rdm.Next(0, lst.Count))
End Function
Or just for string lists:
Public Function randomize(ByVal lst As ICollection(Of String)) As String
Dim rdm As New Random()
Dim auxLst As New List(Of String)(lst)
Return auxLst(rdm.Next(0, lst.Count))
End Function
You could try this, this is a simple loop to pick every item from a list, but in a random manner:
Dim Rand As New Random
For C = 0 to LIST.Count - 1 'Replace LIST with the collection name
Dim RandomItem As STRING = LIST(Rand.Next(0, LIST.Count - 1)) 'Change the item type if needed (STRING)
'' YOUR CODE HERE TO USE THE VARIABLE NewItem ''
Next