I need to generate random strings in vb.net, which must consist of (randomly chosen) letters A-Z (must be capitalized) and with random numbers interspersed. It needs to be able to generate them with a set length as well.
Thanks for the help, this is driving me crazy!
If you can convert this to VB.NET (which is trivial) I'd say you're good to go (if you can't, use this or any other tool for what's worth):
/// <summary>
/// The Typing monkey generates random strings - can't be static 'cause it's a monkey.
/// </summary>
/// <remarks>
/// If you try hard enough it will eventually type some Shakespeare.
/// </remarks>
class TypingMonkey
{
private const string legalCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
static Random random = new Random();
/// <summary>
/// The Typing Monkey Generates a random string with the given length.
/// </summary>
/// <param name="size">Size of the string</param>
/// <returns>Random string</returns>
public string TypeAway(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = legalCharacters[random.Next(0, legalCharacters.Length)];
builder.Append(ch);
}
return builder.ToString();
}
}
Then all you've got to do is:
TypingMonkey myMonkey = new TypingMonkey();
string randomStr = myMonkey.TypeAway(size);
Why don't you randomize a number 1 to 26 and get the relative letter.
Something like that:
Dim output As String = ""
Dim random As New Random()
For i As Integer = 0 To 9
output += ChrW(64 + random.[Next](1, 26))
Next
Edit: ChrW added.
Edit2: To have numbers as well
Dim output As String = ""
Dim random As New Random()
Dim val As Integer
For i As Integer = 0 To 9
val = random.[Next](1, 36)
output += ChrW(IIf(val <= 26, 64 + val, (val - 27) + 48))
Next
C#
public string RandomString(int length)
{
Random random = new Random();
char[] charOutput = new char[length];
for (int i = 0; i < length; i++)
{
int selector = random.Next(65, 101);
if (selector > 90)
{
selector -= 43;
}
charOutput[i] = Convert.ToChar(selector);
}
return new string(charOutput);
}
VB.Net
Public Function RandomString(ByVal length As Integer) As String
Dim random As New Random()
Dim charOutput As Char() = New Char(length - 1) {}
For i As Integer = 0 To length - 1
Dim selector As Integer = random.[Next](65, 101)
If selector > 90 Then
selector -= 43
End If
charOutput(i) = Convert.ToChar(selector)
Next
Return New String(charOutput)
End Function
How about:
Private Function GenerateString(len as integer) as String
Dim stringToReturn as String=""
While stringToReturn.Length<len
stringToReturn&= Guid.NewGuid.ToString().replace("-","")
End While
Return left(Guid.NewGuid.ToString(),len)
End Sub
Here's a utility class I've got to generate random passwords. It's similar to JohnIdol's Typing Monkey, but has a little more flexibility in case you want generated strings to contain uppercase, lowercase, numeric or special characters.
public static class RandomStringGenerator
{
private static bool m_UseSpecialChars = false;
#region Private Variables
private const int m_MinimumLength = 8;
private const string m_LowercaseChars = "abcdefghijklmnopqrstuvqxyz";
private const string m_UppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private const string m_NumericChars = "123456890";
private const string m_SpecialChars = "~?/##!£$%^&*+-_.=|";
#endregion
#region Public Methods
/// <summary>
/// Generates string of the minimum length
/// </summary>
public static string Generate()
{
return Generate(m_MinimumLength);
}
/// <summary>
/// Generates a string of the specified length
/// </summary>
/// <param name="length">The number of characters to generate</param>
public static string Generate(int length)
{
return Generate(length, Environment.TickCount);
}
#endregion
#region Private Methods
/// <summary>
/// Generates a string of the specified length using the specified seed
/// </summary>
private static string Generate(int length, int seed)
{
// Generated strings must contain at least 3 of the following character groups: uppercase letters, lowercase letters
// numerals, and special characters (!, #, $, £, etc)
// The generated string must be at least 4 characters so that we can add a single character from each group.
if (length < 4) throw new ArgumentException("String length must be at least 4 characters");
StringBuilder SB = new StringBuilder();
Random rand = new Random(seed);
// Ensure that we add all of the required groups first
SB.Append(GetRandomCharacter(m_LowercaseChars, rand));
SB.Append(GetRandomCharacter(m_UppercaseChars, rand));
SB.Append(GetRandomCharacter(m_NumericChars, rand));
if (m_UseSpecialChars)
SB.Append(GetRandomCharacter(m_SpecialChars, rand));
// Now add random characters up to the end of the string
while (SB.Length < length)
{
SB.Append(GetRandomCharacter(GetRandomString(rand), rand));
}
return SB.ToString();
}
private static string GetRandomString(Random rand)
{
int a = rand.Next(3);
switch (a)
{
case 1:
return m_UppercaseChars;
case 2:
return m_NumericChars;
case 3:
return (m_UseSpecialChars) ? m_SpecialChars : m_LowercaseChars;
default:
return m_LowercaseChars;
}
}
private static char GetRandomCharacter(string s, Random rand)
{
int x = rand.Next(s.Length);
string a = s.Substring(x, 1);
char b = Convert.ToChar(a);
return (b);
}
#endregion
}
To use it:
string a = RandomStringGenerator.Generate(); // Generate 8 character random string
string b = RandomStringGenerator.Generate(10); // Generate 10 character random string
This code is in C# but should be fairly easy to convert to VB.NET using a code converter.
Just be simple. for vb just do:
Public Function RandomString(size As Integer, Optional validchars As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz") As String
If size < 1 Or validchars.Length = 0 Then Return ""
RandomString = ""
Randomize()
For i = 1 To size
RandomString &= Mid(validchars, Int(Rnd() * validchars.Length) + 1, 1)
Next
End Function
This function allows for a base subset of chars to use or user can choose anything. For example you could send ABCDEF0123456789 and get random Hex. or "01" for binary.
Try this, it's the top answer already converted to VB!
Private Function randomStringGenerator(size As Integer)
Dim random As Random = New Random()
Dim builder As Text.StringBuilder = New Text.StringBuilder()
Dim ch As Char
Dim legalCharacters As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
For cntr As Integer = 0 To size
ch = legalCharacters.Substring(random.Next(0, legalCharacters.Length), 1)
builder.Append(ch)
Next
Return builder.ToString()
End Function
Related
I have this conversion in my Kotlin class for Android:
val binary = "01000100000111001011011011100010111000110011010111010110"
val hexadecimal = BigInteger(binary, 2).toString(16)
Which is producing the expected value of 441CB6E2E335D6.
Now I want to reproduce this in Visual Basic and I am doing something like this:
Dim binary = "01000100000111001011011011100010111000110011010111010110"
Dim hexadecimal = BigInteger.Parse(binary, 2).ToString("X")
Which is producing 0A7108304A751AFEC876F740BC1F2CB59772FB7C6C753E.
I am not an expert in Visual Basic, but from what I researched, I think this is the right way to convert a binary to hexadecimal. What I am doing wrong?
You can write a simple parser for the string representing the bits:
Dim sb As StringBuilder = New StringBuilder()
For pos As Integer = 0 To binary.Length - 8 Step 8
sb.Append(Convert.ToByte(binary.Substring(pos, 8), 2).ToString("X2"))
Next
Console.WriteLine(sb) will print "441CB6E2E335D6"
Or use a Module to add an extension method to the string data type:
Imports System.Runtime.CompilerServices
Imports System.Text
Module modStringExtensions
<Extension()>
Public Function ToHexFromBits(ByVal Value As String) As String
If (Not (Value.Length Mod 8 = 0)) Then Throw New FormatException("Invalid string length")
Dim sb As StringBuilder = New StringBuilder()
For pos As Integer = 0 To Value.Length - 8 Step 8
sb.Append(Convert.ToByte(Value.Substring(pos, 8), 2).ToString("X2"))
Next
Return sb.ToString()
End Function
End Module
Then use the extension to convert the bits string to a HEX representation:
Dim result As String = binary.ToHexFromBits()
Following code is c#, but might not be too hard to translate it to vb.net.
string BinToHex(string value)
{
var res = new char[(int)(value.Length / 4)];
int j = res.Length-1;
for (int i = value.Length - 1; i > 0; i -= 4)
{
int x = ((int)value[i]-48)
+((int)value[i-1]-48)*2
+((int)value[i-2]-48)*4
+((int)value[i-3]-48)*8;
res[j--] = x.ToString("X")[0];
}
return new string(res);
}
Beware: it won't handle input that has not the proper number of bits (multiple of 4). Anyway, the idea is that you can translate between base 2 and base 16 without the use of base 10. You could even step from left to right.
I have such entries in Winforms ComboBox:
Font 8 pt
Font 9 pt
Font 10 pt
Font 12 pt
Font 14 pt
Then I have search string " 9 ".
Is here native way to find index by search string without looping?
I try this:
Dim a As Integer = myComboBox.FindString(" 9 ", 0)
... but without good result.
First, no, there is no available method in the framework that searches for sub-string in combobox items and returns the index of the first item which contains the search parameter.
But even ComboBox.FindString uses a loop as you can see in the source.
So there is nothing bad in using one, you could write an extension method for this:
public static class ControlExtensions
{
public static int FindSubStringIndex(this ComboBox combo, string subString, StringComparison comparer = StringComparison.CurrentCulture)
{
// Sanity check parameters
if(combo == null) throw new ArgumentNullException("combo");
if (subString == null) {
return -1;
}
for (int index = 0; index < combo.Items.Count; index++)
{
object obj = combo.Items[index];
if(obj == null) continue;
string item = Convert.ToString(obj, CultureInfo.CurrentCulture);
if (string.IsNullOrWhiteSpace(item) && string.IsNullOrWhiteSpace(subString))
return index;
int indexInItem = item.IndexOf(subString, comparer);
if (indexInItem >= 0)
return index;
}
return -1;
}
}
Now you can use it in this way:
int index = combo.FindSubStringIndex("9");
Whoops, VB.NET:
Public Module ControlExtensions
<System.Runtime.CompilerServices.Extension> _
Public Function FindSubStringIndex(combo As ComboBox, subString As String, Optional comparer As StringComparison = StringComparison.CurrentCulture) As Integer
' Sanity check parameters
If combo Is Nothing Then
Throw New ArgumentNullException("combo")
End If
If subString Is Nothing Then
Return -1
End If
For index As Integer = 0 To combo.Items.Count - 1
Dim obj As Object = combo.Items(index)
If obj Is Nothing Then
Continue For
End If
Dim item As String = Convert.ToString(obj, CultureInfo.CurrentCulture)
If String.IsNullOrWhiteSpace(item) AndAlso String.IsNullOrWhiteSpace(subString) Then
Return index
End If
Dim indexInItem As Integer = item.IndexOf(subString, comparer)
If indexInItem >= 0 Then
Return index
End If
Next
Return -1
End Function
End Module
Why, hello everyone!
I've got this program i've been working on for months. Basic back story of it is, its supposed to be able to transport and install applications for windows in the background, like iCloud does for apps!
Anywho, i'm using a serialize/deserialize method to save the properties (eg admin username and passwordhash, directories, ports, etc.).
I have a class called 'PropertyNest' representing the properties and links to memory allocations. I'll cut it down to only the parts that the XMLSerializer looks at and saves.
Public Class PropertyNest
'Huge bunch of functions that we dont need to look at
'#######################
Public _wasLoadedFromFile As Boolean = False
Private _port As Integer = 201
Private _httpPort As Integer = 202
Private _rootFolder As String = "\appstreamRoot"
Private _adminUser As String = "Admin"
Private _adminPass As String = "21232F297A57A5A743894A0E4A801FC3" 'admin
Private _appstreamServerType As appStreamServerType = appStreamServerType.http
Private _useDES3forserver As Boolean = True
Private _encDES3pswd As String = "21232F297A57A5A743894A0E4A801FC3" 'admin
'Properties and descriptors for 'PropertyGrid' object go here \|/
'=================================================================
End Class
And its declared in the main window, serverMain like this,
Public Shared Property_Nest As AdvancedSettings.PropertyNest
and initialized later in like this,
If settingsfilename = "" Then
Property_Nest = New AdvancedSettings.PropertyNest()
Else
If propFileEncrypted = False Then
WriteLog("From unprotected file...", False)
Try
Property_Nest = AdvancedSettings.PropertyNest.LoadFrom(settingsfilename)
Catch ex As Exception
WriteLog("FAILED! Making default property nest...")
Property_Nest = New AdvancedSettings.PropertyNest()
End Try
Else
WriteLog("From encrypted file...", False)
Try
Property_Nest = AdvancedSettings.PropertyNest.LoadFrom(settingsfilename, True, propFilePswd)
Catch ex As Exception
WriteLog("FAILED! Making default property nest...", False)
Property_Nest = New AdvancedSettings.PropertyNest()
End Try
End If
End If
Thats all well and good. Loading it from the file that its saved to is the problem. Inside the PropertyNest class, I have 2 serializers programmed like so:
(Sorry its a bunch, there's optional encrypting of the serialized products with TrippleDES)
Public Sub SaveAs(ByVal filename As String, Optional ByVal Encrypted As Boolean = False)
Dim extra As String
If Encrypted = True Then : extra = "Encrypted? : Yes." : Else : extra = "Encrypted? : No."
End If
If filename = Nothing Then
Exit Sub
End If
writeLog2("Saving Property Nest to: " & filename & vbCrLf & extra, False)
If Encrypted = False Then
Dim writer As New Xml.Serialization.XmlSerializer(GetType(PropertyNest))
Dim file As New System.IO.StreamWriter(filename)
writer.Serialize(file, Me)
file.Close()
Else
Dim writer As New Xml.Serialization.XmlSerializer(GetType(PropertyNest))
Dim memstream As New System.IO.MemoryStream
writer.Serialize(memstream, Me)
memstream.Seek(0, IO.SeekOrigin.Begin)
Dim file As New System.IO.StreamWriter(filename)
Dim memstreamReader As New System.IO.StreamReader(memstream)
Do
file.WriteLine(serverMain.admin_des3Manager.Encrypt(memstreamReader.ReadLine()))
Loop Until memstreamReader.EndOfStream = True
file.Close()
End If
writeLog2("OK!")
End Sub
Shared Function LoadFrom(ByVal filename As String, Optional ByVal EncryptedWithPswd As Boolean = False, Optional ByVal Password As String = "") As PropertyNest
Dim reader As New Xml.Serialization.XmlSerializer(GetType(PropertyNest))
Dim file As New System.IO.StreamReader(filename)
Dim newPropNest As PropertyNest
If EncryptedWithPswd = False Then
newPropNest = reader.Deserialize(file) 'Error in XML Document(11, 3)
Else
If Password = "" Then
Dim convertedStream As New System.IO.MemoryStream
Dim convertedWriter As New System.IO.StreamWriter(convertedStream)
Do
convertedWriter.WriteLine(serverMain.admin_des3Manager.Decrypt(file.ReadLine()))
Loop Until file.EndOfStream = True
convertedWriter.Close()
newPropNest = reader.Deserialize(convertedStream)
Else
Dim tempDES3 As New DES3(Password)
Dim convertedStream As New System.IO.MemoryStream
Dim convertedWriter As New System.IO.StreamWriter(convertedStream)
Do
convertedWriter.WriteLine(tempDES3.Decrypt(file.ReadLine()))
Loop Until file.EndOfStream = True
convertedWriter.Close()
newPropNest = reader.Deserialize(convertedStream)
End If
End If
Return newPropNest
End Function
I marked the error in there.
Phew. Almost done.
i'm only worried about unencrypted right now, so i did my duty to save a custom, non default property nest, and it wrote to the file like so:
<?xml version="1.0" encoding="utf-8"?>
<PropertyNest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<_wasLoadedFromFile>false</_wasLoadedFromFile>
<ServerPort>2010</ServerPort>
<AdminUser>Matthew</AdminUser>
<AdminPasswordHash>21232F297A57A5A743894A0E4A801FC3</AdminPasswordHash>
<AppStreamPort>2020</AppStreamPort>
<AppStream_ServerRoot>\appstreamRoot</AppStream_ServerRoot>
<UseDES3>true</UseDES3>
<EncDES3Pswd>21232F297A57A5A743894A0E4A801FC3</EncDES3Pswd>
</PropertyNest>
Awesome! now.... If you look at the 'LoadFrom' function, you'll see i commented the line where i get the error... I dont see an error at 11, 3. Please help!
Thanks so much :D
Your XML is valid, however the class you need to deserialise, should be like this according to visual studio, copy you XML to the clipboard, go to the edit menu, paste special and past XML as classes give you this, give it a try see if it works, you can use a c# to vb converter to change to VB if you need to.
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class PropertyNest
{
private bool _wasLoadedFromFileField;
private ushort serverPortField;
private string adminUserField;
private string adminPasswordHashField;
private ushort appStreamPortField;
private string appStream_ServerRootField;
private bool useDES3Field;
private string encDES3PswdField;
/// <remarks/>
public bool _wasLoadedFromFile
{
get
{
return this._wasLoadedFromFileField;
}
set
{
this._wasLoadedFromFileField = value;
}
}
/// <remarks/>
public ushort ServerPort
{
get
{
return this.serverPortField;
}
set
{
this.serverPortField = value;
}
}
/// <remarks/>
public string AdminUser
{
get
{
return this.adminUserField;
}
set
{
this.adminUserField = value;
}
}
/// <remarks/>
public string AdminPasswordHash
{
get
{
return this.adminPasswordHashField;
}
set
{
this.adminPasswordHashField = value;
}
}
/// <remarks/>
public ushort AppStreamPort
{
get
{
return this.appStreamPortField;
}
set
{
this.appStreamPortField = value;
}
}
/// <remarks/>
public string AppStream_ServerRoot
{
get
{
return this.appStream_ServerRootField;
}
set
{
this.appStream_ServerRootField = value;
}
}
/// <remarks/>
public bool UseDES3
{
get
{
return this.useDES3Field;
}
set
{
this.useDES3Field = value;
}
}
/// <remarks/>
public string EncDES3Pswd
{
get
{
return this.encDES3PswdField;
}
set
{
this.encDES3PswdField = value;
}
}
}
I have a string looking like this:
a:391:i:0;s:12:"jnKKPkvpNnfn";i:1;s:12:"ic9VAk3PvQ3j";i:2;s:12:"PEBFuE6bGepr";i:3;s:12:"bwuxRkH6QbGp";i:4;s:12:"LSRDQbAKXc9q";i:5;s:12:"eLuVbSAxQCgo";}
And I want to get the text inside the quotations and send them to a listbox.
I know sort of how to do it, but in an ineffective way that might now work... So I'm asking for advice with an example on how to do it.
Thanks
This should get you started; the method will run through an input string and return an array of strings that are contained within quotes.
string[] ParseQuotes(string input)
{
List<string> matches = new List<string>();
bool open = false;
int index = -1;
for (int i = 0; i < input.Length; i++)
{
if (input[i] == '"')
{
if (!open)
{
open = true;
index = i;
}
else
{
open = false;
string match = input.Substring(index + 1, index - i - 1);
matches.Add(match);
}
}
}
return matches.ToArray();
}
Converted to VB...
Private Function ParseQuotes(input As String) As String()
Dim matches As New List(Of String)()
Dim open As Boolean = False
Dim index As Integer = -1
For i As Integer = 0 To input.Length - 1
If input(i) = """"C Then
If Not open Then
open = True
index = i
Else
open = False
Dim match As String = input.Substring(index + 1, index - i - 1)
matches.Add(match)
End If
End If
Next
Return matches.ToArray()
End Function
In your main code:
cbYourcomboBox.Items.Clear()
cbYourcomboBox.Items.AddRange(GetList(str).ToArray)
and then the function itself:
Public Function GetList(ByVal str As String) As List(Of String)
Dim ar As String()
Dim ar2 As List(Of String) = New List(Of String)
ar = Split(str, Chr(34))
' making sure there is a matching closing quote with - (UBound(ar) And 1)
For a As Integer = 1 To UBound(ar) - (UBound(ar) And 1) Step 2
ar2.Add(ar(a))
Next a
Return ar2
End Function
I have a Tlist that contains addresses. When I sort the list, numbers in the address are considered a string, and it doesn't sort correctly. How should I sort the list ascending?
Dim sortme As List(Of data) = tempdata 'main list containing addresses as strings.
sortme.Sort(Function(p1 As data, p2 As data) numorder(p1.Value).CompareTo(numorder(p2.Value)))
Private Function numorder(ByVal str As String)
Try
Dim words() As String = str.Split(" "c) 'read string up to first space (for number)
Return Convert.ToInt32(words(0))
Catch ex As Exception
End Try
End Function
Example of current output:
1001 street name
103 street name
1021 street name
It should be:
103 street name
1001 street name
1021 street name
The idea is to write your own comparer which will firs consider the number prefix and then the string itself. This comparer can be then used anywhere, for instance in LINQ OrderBy(). Here an example in c# see full VB.NET version below.
public class StreetComparer : IComparer<string>
{
public int Compare(string x, string y)
{
int indexOfSpaceX = x.IndexOf(' ');
string numericalPartX = x.Substring(0, indexOfSpaceX);
int indexOfSpaceY = y.IndexOf(' ');
string numericalPartY = y.Substring(0, indexOfSpaceY);
int numberX;
int numberY;
if(!int.TryParse(numericalPartX, out numberX) ||
!int.TryParse(numericalPartY, out numberY))
{
//Some code to handle the case where number is missing
throw new ArgumentException();
}
if (numberX!=numberY)
{
return numberX-numberY;
}
string textPartX = x.Substring(indexOfSpaceX + 1);
string textPartY = x.Substring(indexOfSpaceY + 1);
return String.Compare(textPartX, textPartY, true, CultureInfo.CurrentCulture);
}
}
class Program
{
static void Main(string[] args)
{
var myStreets = new[] {"01 aaa", "02 bbb"};
var result = myStreets.OrderBy(s => s, new StreetComparer());
}
}
Now a VB.NET version adapted exactly to your use case a List with classes sorted by property:
Public Class StreetComparer
Implements IComparer(Of String)
Public Function Compare(x As String, y As String) As Integer
Dim indexOfSpaceX As Integer = x.IndexOf(" "C)
Dim numericalPartX As String = x.Substring(0, indexOfSpaceX)
Dim indexOfSpaceY As Integer = y.IndexOf(" "C)
Dim numericalPartY As String = y.Substring(0, indexOfSpaceY)
Dim numberX As Integer
Dim numberY As Integer
If Not Integer.TryParse(numericalPartX, numberX) OrElse Not Integer.TryParse(numericalPartY, numberY) Then
'Some code to handle the case where number is missing
Throw New ArgumentException()
End If
If numberX <> numberY Then
Return numberX - numberY
End If
Dim textPartX As String = x.Substring(indexOfSpaceX + 1)
Dim textPartY As String = x.Substring(indexOfSpaceY + 1)
Return [String].Compare(textPartX, textPartY, True, CultureInfo.CurrentCulture)
End Function
End Class
Public Class Person
Public Property Value() As String
Get
Return m_Value
End Get
Set
m_Value = Value
End Set
End Property
Private m_Value As String
Public Sub New(value__1 As String)
Value = value__1
End Sub
End Class
Class Program
Private Shared Sub Main(args As String())
Dim sortme As New List(Of Person)(New () {New Person("1001 street name"), New Person("103 street name"), New Person("1021 street name")})
Dim result = sortme.OrderBy(Function(p) p.Value, New StreetComparer())
For Each person As var In result
Console.WriteLine(person.Value)
Next
Console.ReadKey()
End Sub
End Class