Random characters are appearing as the same char in C#? - c#

This program is suppose to generate a random license plate number. The first 3 characters are letters and the second 3 characters are numbers. For some reason the second two letters always appear as the same letter and all three numbers remain as the same number.
For example it will appear like this WKK-555 when I want all characters to be random.
What am I doing wrong?
// This is how the license plates are randomly created.
StringBuilder sb = new StringBuilder();
// first randomly chosen capital alphabetic character.
Random rng1 = new Random();
char C1;
int firstCharIndex = -1;
string specialStr1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
firstCharIndex = rng1.Next(0, specialStr1.Length);
C1 = specialStr1[firstCharIndex];
sb.Append(C1);
// second randomly chosen capital alphabetic character.
Random rng2 = new Random();
char C2;
int secondCharIndex = -1;
string specialStr2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
secondCharIndex = rng2.Next(0, specialStr2.Length);
C2 = specialStr2[secondCharIndex];
sb.Append(C2);
// third randomly chosen capital alphabetic character.
Random rng3 = new Random();
char C3;
int thirdCharIndex = -1;
string specialStr3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
thirdCharIndex = rng2.Next(0, specialStr3.Length);
C3 = specialStr3[thirdCharIndex];
sb.Append(C3);
// hyphen
char C4;
int fourthCharIndex = 0;
string specialStr4 = "-";
C4 = specialStr4[fourthCharIndex];
sb.Append(C4);
// first randomly selected digit.
Random rng5 = new Random();
char C5;
int fifthCharIndex = -1;
string specialStr5 = "0123456789";
fifthCharIndex = rng5.Next(0, specialStr5.Length);
C5 = specialStr5[fifthCharIndex];
sb.Append(C5);
// second randomly selected digit.
Random rng6 = new Random();
char C6;
int sixthCharIndex = -1;
string specialStr6 = "0123456789";
sixthCharIndex = rng6.Next(0, specialStr6.Length);
C6 = specialStr6[sixthCharIndex];
sb.Append(C6);
// third randomly selected digit.
Random rng7 = new Random();
char C7;
int seventhCharIndex = -1;
string specialStr7 = "0123456789";
seventhCharIndex = rng7.Next(0, specialStr7.Length);
C7 = specialStr7[seventhCharIndex];
sb.Append(C7);
// our license plate!!!
LicensePlateTextBox.Text = sb.ToString();

You need to create and use only one instance of Random. When you create them in quick succession, they will have the same seed and return the same values.

The other answers tell you why you aren't getting the proper result. This will generate you a license plate in the format you're looking for and uses less duplicated code (although there's probably a solution that's better still).
Random r = new Random();
string plateNumber = "";
for (int i = 0; i < 3; i++) plateNumber += (char)r.Next(65, 90);
plateNumber += "-";
for (int i = 0; i < 3; i++) plateNumber += r.Next(0, 9).ToString();

You're instantiating a new Randomevery time. The seed by default is the current tickcount.
Since this runs very fast, they will all have the same seed and thus the first value will always be the same. To prevent this, create a single Random and call the next method several times

Instantiate your RNG just once as everybody sez. Here you go, a thread-safe license plate number generator:
class RandomLicensePlateNumberGenerator
{
static readonly Random Randomizer = new Random() ;
public string Generate( string pattern )
{
if ( string.IsNullOrWhiteSpace(pattern)) throw new ArgumentOutOfRangeException("pattern") ;
return new string( pattern.Select( RandomCharacter ).ToArray() ) ;
}
public IEnumerable<string> Stream( string pattern )
{
while ( true )
{
yield return Generate( pattern ) ;
}
}
public char RandomCharacter( char c )
{
char value ;
lock ( Randomizer )
{
switch ( c )
{
case 'A' : case 'a' : value = (char) Randomizer.Next( 'A' , 'Z' + 1 ) ; break ;
case '#' : case '9' : value = (char) Randomizer.Next( '0' , '9' + 1 ) ; break ;
default : value = c ; break ;
}
}
return value ;
}
}
class Program
{
static void Main()
{
RandomLicensePlateNumberGenerator licensePlates = new RandomLicensePlateNumberGenerator();
int i = 0 ;
foreach ( string s in licensePlates.Stream( "AAA-999" ).Take(1000) )
{
Console.WriteLine( "{0,6:#,##0}: {1}",++i,s) ;
}
return ;
}
}

Related

User input to chose an amount of letter and number from an array in C#

I am trying to learn C# and I am making a password generator. I have set an array with the letters and number I want the program to use.
String alphabet[] = {"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
I am trying to write a piece of code in a for loop that will pick random letters or numbers any amount of length that the user inputs.
Example for
(y in alphabet (PwLength));
I just can't figure out how to get it to cycle through the loop choosing random letters.
You can use infinite random chars generator:
IEnumerable<char> GetRandomChars()
{
string alphabet =
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new Random();
while (true)
yield return alphabet[random.Next(alphabet.Length)];
}
Take first N random characters and create string:
var result = new String(GetRandomChars().Take(length).ToArray());
You should use Random here. The idea is to get the password length from user and set the allowed characters and then use Random to generate the password.
public static string CreatePassword(int passwordLength)
{
const string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!#$?_-";
char[] chars = new char[passwordLength];
Random rd = new Random();
for (int i = 0; i < passwordLength; i++)
chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
return new string(chars);
}
String password = "";
for(int i = 0; i < USERINPUTLENGTH; i++)
{
//Get Random Char
String randomChar = alphabet[Random.next(alphabet.length)];
password += randomChar;
}
You don't need to loop over the alphabet, but loop once for each character you want in the generated password.
string GeneratePassword(int pwLength)
{
string alphabet = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var builder = new StringBuilder();
var random = new Random();
for(var i = 0; i < pwLength; i += 1) {
builder.Append(alphabet[random.Next(alphabet.Length)]);
}
return builder.ToString();
}

How do I swap two characters in a string variable?

I have a string variable. I want to swap the two characters in the string word.
I want to randomly swap two characters which are close to each other.
This is what I have done:
I have done like this but in some words I get error.
string word = txtWord.Text;
Random rand = new Random();
int randomNumber= rand.Next(0, word.Length);
string swappedWord = SwapCharacters(lastWord, randomNumber, randomNumber + 1);
private string SwapCharacters(string value, int position1, int position2)
{
char[] array = value.ToCharArray(); // Convert a string to a char array
char temp = array[position1]; // Get temporary copy of character
array[position1] = array[position2]; // Assign element
array[position2] = temp; // Assign element
return new string(array); // Return string
}
Use a StringBuilder:
//If you want to replace
StringBuilder sb = new StringBuilder(theString);
sb[index] = newChar;
theString = sb.ToString();
//Swap
string input = "AXBYCZ"; //Sample String
StringBuilder output = new StringBuilder();
char[] characters = input.ToCharArray();
for (int i = 0; i < characters.Length; i++)
{
if (i % 2 == 0)
{
if((i+1) < characters.Length )
{
output.Append(characters[i + 1]);
}
output.Append(characters[i]);
}
}
Just change the line as below:
int randomNumber= rand.Next(0, word.Length -1 );
Let's see if it works.
Try this. Also add checks if the word is empty.
int randomNumber= rand.Next(0, word.Length - 1);
Try this code. It is easiest to change your code
int randomNumber= rand.Next(0, word.Length-2);

Pick random char

i have some chars:
chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
now i'm looking for a method to return a random char from these.
I found a code which maybe can be usefull:
static Random random = new Random();
public static char GetLetter()
{
// This method returns a random lowercase letter
// ... Between 'a' and 'z' inclusize.
int num = random.Next(0, 26); // Zero to 25
char let = (char)('a' + num);
return let;
}
this code returns me a random char form the alphabet but only returns me lower case letters
Well you're nearly there - you want to return a random element from a string, so you just generate a random number in the range of the length of the string:
public static char GetRandomCharacter(string text, Random rng)
{
int index = rng.Next(text.Length);
return text[index];
}
I'd advise against using a static variable of type Random without any locking, by the way - Random isn't thread-safe. See my article on random numbers for more details (and workarounds).
This might work for you:
public static char GetLetter()
{
string chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random rand = new Random();
int num = rand.Next(0, chars.Length);
return chars[num];
}
You can use it like;
char[] chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
Random r = new Random();
int i = r.Next(chars.Length);
Console.WriteLine(chars[i]);
Here is a DEMO.
I had approximate issue and I did it by this way:
public static String GetRandomString()
{
var allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
var length = 15;
var chars = new char[length];
var rd = new Random();
for (var i = 0; i < length; i++)
{
chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
}
return new String(chars);
}
Instead of 26 please use size of your CHARS buffer.
int num = random.Next(0, chars.Length)
Then instead of
let = (char)('a' + num)
use
let = chars[num]
I'm not sure how efficient it is as I'm very new to coding, however, why not just utilize the random number your already creating? Wouldn't this "randomize" an uppercase char as well?
int num = random.Next(0,26);
char let = (num > 13) ? Char.ToUpper((char)('a' + num)) : (char)('a' + num);
Also, if you're looking to take a single letter from your char[], would it be easier to just use a string?
string charRepo = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random rando = new Random();
int ranNum = rando.Next(0, charRepo.Length);
char ranChar = charRepo[ranNum];
private static void Main(string[] args)
{
Console.WriteLine(GetLetters(6));
Console.ReadLine();
}
public static string GetLetters(int numberOfCharsToGenerate)
{
var random = new Random();
char[] chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
var sb = new StringBuilder();
for (int i = 0; i < numberOfCharsToGenerate; i++)
{
int num = random.Next(0, chars.Length);
sb.Append(chars[num]);
}
return sb.ToString();
}
Your Code is good, you just need to change 'a' to 'A'
static Random random = new Random();
public static char GetLetter()
{
// This method returns a random lowercase letter
// ... Between 'a' and 'z' inclusize.
int num = random.Next(0, 26); // Zero to 25
char let = (char)('A' + num);
return let;
}
This code same as mentioned in the question , just change char let = (char)('A' + num); , it returns upper case letters.
Thanks!!!
I wish This code helps you :
string s = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random random = new Random();
int num = random.Next(0, s.Length -1);
MessageBox.Show(s[num].ToString());
Getting Character from ASCII number:
private string GenerateRandomString()
{
Random rnd = new Random();
string txtRand = string.Empty;
for (int i = 0; i <8; i++) txtRand += ((char)rnd.Next(97, 122)).ToString();
return txtRand;
}
You can try this :
public static string GetPassword()
{
string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random rnd = new Random();
int index = rnd.Next(0,51);
string char1 = Characters[index].ToString();
return char1;
}
Now you can play with this code block as per your wish. Cheers!

How to generate 8 characters, 900000 Upper alpha/numeric unique keys with C#?

I'm trying to generate 900,000 keys and store them to a db.
Each value has to be 8 chars and different from generated ones.
Here is my code look like, it's doing ok but it's too slow...
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.Visible = false;
Generate();
}
public int num = 0;
private void Den1()
{
for (int i = 0; i < 900000; i++)
{
string randomStr = RandomString(8);
string textToSearchFor = randomStr;
int index = richTextBox1.Text.IndexOf(textToSearchFor, StringComparison.OrdinalIgnoreCase);
if (index >= 0)
{
MessageBox.Show("Duplicate ignored from 1!");
i--;
}
else
{
richTextBox1.Text += randomStr + "\n";
num++;
}
label1.Text = "" + num;
}
richTextBox1.Visible = true;
}
public void Generate()
{
CheckForIllegalCrossThreadCalls = false;
Thread thread1 = new Thread(Deneme1);
thread1.Start();
}
private string RandomString(int length, string allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
{
if (length < 0) throw new ArgumentOutOfRangeException("length", "length cannot be less than zero.");
if (string.IsNullOrEmpty(allowedChars)) throw new ArgumentException("allowedChars may not be empty.");
const int byteSize = 0x100;
var allowedCharSet = new HashSet<char>(allowedChars).ToArray();
if (byteSize < allowedCharSet.Length) throw new ArgumentException(String.Format("allowedChars may contain no more than {0} characters.", byteSize));
// Guid.NewGuid and System.Random are not particularly random. By using a
// cryptographically-secure random number generator, the caller is always
// protected, regardless of use.
using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
{
var result = new StringBuilder();
var buf = new byte[128];
while (result.Length < length)
{
rng.GetBytes(buf);
for (var i = 0; i < buf.Length && result.Length < length; ++i)
{
// Divide the byte into allowedCharSet-sized groups. If the
// random value falls into the last group and the last group is
// too small to choose from the entire allowedCharSet, ignore
// the value in order to avoid biasing the result.
var outOfRangeStart = byteSize - (byteSize % allowedCharSet.Length);
if (outOfRangeStart <= buf[i]) continue;
result.Append(allowedCharSet[buf[i] % allowedCharSet.Length]);
}
}
return result.ToString();
}
}
}
Well to start with, I would generate them all and then put them into the UI. I also wouldn't use string.IndexOf to find if you've already got a match. Use a HashSet<string>:
HashSet<string> codes = new HashSet<string>();
while (codes.Count < 900000)
{
codes.Add(RandomString(8));
}
// Then do what you want with the codes
You also shouldn't be setting CheckForIllegalCrossThreadCalls to false. Just generate them all in the background and then use Invoke to get to the UI thread to update your UI. If you really want to update as you go, you could do so periodically... although I wouldn't put them all into a single text box.
Next, I'd look at the RandomString method. Do you really need to create a new RNGCryptoServiceProvider on every iteration? Why not create one and then reuse it?
Likewise, why bother creating a new HashSet<char> and calling ToArray on every call? It sounds like you should probably have a separate class as a RandomCodeGenerator which remembers:
The size of code you're generating
The random number generator
The allowed characters
That will let you get away from doing a lot of setup work on every iteration.
I'd then personally create a char[] of the right size and just iterate until you've filled it, then create a string from that... I don't see the need for StringBuilder... but that's probably not hurting you.
You could use a Guid to quickly generate your keys:
Guid guid = Guid.NewGuid();
string theString = guid.ToString().Replace("-", string.Empty).Substring(0, 8).ToUpperInvariant();
You could do that directly in SQL, like: https://stackoverflow.com/a/9631898/403335
But even if you do that with code, I would fill a container with a sequence of all the possible values.
Then randomly select elements from the sequence container, use the element and delete it from the container. This way you will surely get all the numbers, without wasting time in finding a "hole" number (not already picked up).
In code:
Random random = new Random();
List<string> uniqueStrings = new List<string>(900000);
List<string> randomString = new List<string>(900000);
for (char c1 = 'A'; c1 <= 'Z'; ++c1)
for (char c2 = 'A'; c2 <= 'Z'; ++c2)
for (char c3 = 'A'; c3 <= 'Z'; ++c3)
for (char c4 = 'A'; c4 <= 'Z'; ++c4)
for (char c5 = 'A'; c5 <= 'Z'; ++c5)
for (char c6 = 'A'; c6 <= 'Z'; ++c6)
for (char c7 = 'A'; c7 <= 'Z'; ++c7)
for (char c8 = 'A'; c8 <= 'Z'; ++c8)
uniqueStrings.Add(string.Format("{0}{1}{2}{3}{4}{5}{6}{7}", c1, c2, c3, c4, c5, c6, c7, c8));
for (int i = 0; i < uniqueStrings.Count; i++)
{
const int index = random.Next(uniqueStrings.Count) + 1;
randomString.Add(uniqueStrings[index]);
uniqueStrings.RemoveAt(index);
}
First of all RichTextBox is not an appropriate value store. The IndexOf method of the TextBox is most likely the slowest part of your code you need to replace it with something else, I would rather use a HashSet<string> to figure out of there are duplicates.
I think this code may be helpful
public static string GeneratePassword()
{
string strPwdchar = "abcdefghijklmnopqrstuvwxyz0123456789#+#&$ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string strPwd = "";
Random rnd = new Random();
for (int i = 0; i <= 7; i++)
{
int iRandom = rnd.Next(5, strPwdchar.Length - 1);
strPwd += strPwdchar.Substring(iRandom, 1);
}
return strPwd;
}
Iterate it 90,000 times on a mouse click event.....I hope things will work
Have a look at this discussion.
My preferred solution, which I use for generating +100.000 unique strings is the linked answer

attempting to create string of random values

I'm trying to generate a string of a random length which consists out of random chars.
To do so I have this code:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
MyString test = new MyString();
test.Random();
Console.WriteLine(test.Value);
}
Console.ReadLine();
}
}
public class MyString
{
private string value = string.Empty;
private Random r = new Random();
public string Value
{
get { return this.value; }
set { this.value = value; }
}
public void Random()
{
int length = (r.Next() % (100)) + 1;
for(int i = 0; i < length; i++)
{
value = value + RandomChar();
}
}
public char RandomChar()
{
// 32 to 126
int c = (r.Next() % 95) + 32;
char ch = (char)c;
return ch;
}
}
Now, lets look at a part of the output:
As you can see, the output is far from random, it contains a lot of repeating strings. How is this possible, and how do I solve it?
It looks like you are creating a new instance of the Random class every time your MyString constructor is called. The Random class probably seeds itself based on the current time (to some resolution). Random number generators seeded with the same value will generate the same pseudo-random sequence.
The solution is to construct one instance of Random and use that everywhere.
http://msdn.microsoft.com/en-us/library/system.io.path.getrandomfilename.aspx
string randomName = Path.GetRandomFileName();
randomName = randomName.Replace(".", string.Empty);
// take substring...

Categories