Two random class returning same value [duplicate] - c#

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 7 years ago.
i tried to create random string contains both int and string. Below is the classes of how i get random string and int.
private int RandomNumber1(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
private int RandomNumber2(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
private string RandomStringSatu(int size, bool uppercase)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
if (uppercase)
return builder.ToString().ToUpper();
return builder.ToString();
}
private string RandomStringDua(int size, bool uppercase)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
if (uppercase)
return builder.ToString().ToUpper();
return builder.ToString();
}
And here is the way i set up those classes to get a random string.
StringBuilder sb = new StringBuilder();
sb.Append(RandomStringSatu(1, true));
sb.Append(RandomNumber1(1, 9));
sb.Append(RandomStringDua(1, true));
sb.Append(RandomNumber2(1, 9));
string rdmKode = sb.ToString();
this is the result that i get :
Result
On the picture you can see that the first two caracters has same value with the last two caracter.
Now, the question is what should i do, if i want to get different caracter.
So, the output should be looks like "D2B1"
Thanks

If you move your Random random = new Random(); line from RandomNumber1 and RandomNumber2 to global to outside of methods, than use that rundom field in that RandomNumber1 and RandomNumber2 methods result will be differente.
Thanx Jamaxack

Using an answer from this stackoverflow question
You are looking to seed when you create a new instance.
Random random = new Random(Guid.NewGuid().GetHashCode());

Provide different seed values when you create instances of Random() to generate different values. Check documentation here, https://msdn.microsoft.com/en-us/library/ctssatww%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Related

lottery vector with for loop without duplicates [duplicate]

I've searched for a while and been struggling to find this, I'm trying to generate several random, unique numbers is C#. I'm using System.Random, and I'm using a DateTime.Now.Ticks seed:
public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
MyNumber = a.Next(0, 10);
}
I'm calling NewNumber() regularly, but the problem is I often get repeated numbers. Some people suggested because I was declaring the random every time I did it, it would not produce a random number, so I put the declaration outside my function. Any suggestions or better ways than using System.Random ? Thank you
I'm calling NewNumber() regularly, but the problem is I often get
repeated numbers.
Random.Next doesn't guarantee the number to be unique. Also your range is from 0 to 10 and chances are you will get duplicate values. May be you can setup a list of int and insert random numbers in the list after checking if it doesn't contain the duplicate. Something like:
public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode());
// Since similar code is done in default constructor internally
public List<int> randomList = new List<int>();
int MyNumber = 0;
private void NewNumber()
{
MyNumber = a.Next(0, 10);
if (!randomList.Contains(MyNumber))
randomList.Add(MyNumber);
}
You might try shuffling an array of possible ints if your range is only 0 through 9. This adds the benefit of avoiding any conflicts in the number generation.
var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();
// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
int randomIndex = rnd.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
Console.WriteLine(nums[i]);
NOTE, I dont recommend this :).
Here's a "oneliner" as well:
var result = Enumerable.Range(0,9).OrderBy(g => Guid.NewGuid()).ToArray();
I'm posting a correct implementation of a shuffle algorithm, since the other one posted here doesn't produce a uniform shuffle.
As the other answer states, for small numbers of values to be randomized, you can simply fill an array with those values, shuffle the array, and then use however many of the values that you want.
The following is an implementation of the Fisher-Yates Shuffle (aka the Knuth Shuffle). (Read the "implementation errors" section of that link (search for "always selecting j from the entire range of valid array indices on every iteration") to see some discussion about what is wrong with the other implementation posted here.)
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
static class Program
{
static void Main(string[] args)
{
Shuffler shuffler = new Shuffler();
List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
shuffler.Shuffle(list);
foreach (int value in list)
{
Console.WriteLine(value);
}
}
}
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
public Shuffler()
{
_rng = new Random();
}
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private System.Random _rng;
}
}
This is a unity only answer:
Check this ready-to-use method: Give in a range & count of number you want to get.
public static int[] getUniqueRandomArray(int min, int max, int count) {
int[] result = new int[count];
List<int> numbersInOrder = new List<int>();
for (var x = min; x < max; x++) {
numbersInOrder.Add(x);
}
for (var x = 0; x < count; x++) {
var randomIndex = UnityEngine.Random.Range(0, numbersInOrder.Count);
result[x] = numbersInOrder[randomIndex];
numbersInOrder.RemoveAt(randomIndex);
}
return result;
}
Same as #Habib's answer, but as a function:
List<int> randomList = new List<int>();
int UniqueRandomInt(int min, int max)
{
var rand = new Random();
int myNumber;
do
{
myNumber = rand.Next(min, max);
} while (randomList.Contains(myNumber));
return myNumber;
}
If randomList is a class property, UniqueRandomInt will return unique integers in the context of the same instance of that class. If you want it to be unique globally, you will need to make randomList static.
Depending on what you are really after you can do something like this:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO14473321
{
class Program
{
static void Main()
{
UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
for (int i = 0; i < 10; i++)
{
Console.Write("{0} ",u.Next());
}
}
}
class UniqueRandom
{
private readonly List<int> _currentList;
private readonly Random _random = new Random();
public UniqueRandom(IEnumerable<int> seed)
{
_currentList = new List<int>(seed);
}
public int Next()
{
if (_currentList.Count == 0)
{
throw new ApplicationException("No more numbers");
}
int i = _random.Next(_currentList.Count);
int result = _currentList[i];
_currentList.RemoveAt(i);
return result;
}
}
}
And here my version of finding N random unique numbers using HashSet.
Looks pretty simple, since HashSet can contain only different items.
It's interesting - would it be faster then using List or Shuffler?
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class RnDHash
{
static void Main()
{
HashSet<int> rndIndexes = new HashSet<int>();
Random rng = new Random();
int maxNumber;
Console.Write("Please input Max number: ");
maxNumber = int.Parse(Console.ReadLine());
int iter = 0;
while (rndIndexes.Count != maxNumber)
{
int index = rng.Next(maxNumber);
rndIndexes.Add(index);
iter++;
}
Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
foreach (int num in rndIndexes)
{
Console.WriteLine(num);
}
Console.ReadKey();
}
}
}
I noted that the accepted answer keeps adding int to the list and keeps checking them with if (!randomList.Contains(MyNumber)) and I think this doesn't scale well, especially if you keep asking for new numbers.
I would do the opposite.
Generate the list at startup, linearly
Get a random index from the list
Remove the found int from the list
This would require a slightly bit more time at startup, but will scale much much better.
public class RandomIntGenerator
{
public Random a = new Random();
private List<int> _validNumbers;
private RandomIntGenerator(int desiredAmount, int start = 0)
{
_validNumbers = new List<int>();
for (int i = 0; i < desiredAmount; i++)
_validNumbers.Add(i + start);
}
private int GetRandomInt()
{
if (_validNumbers.Count == 0)
{
//you could throw an exception here
return -1;
}
else
{
var nextIndex = a.Next(0, _validNumbers.Count - 1);
var number = _validNumbers[nextIndex];
_validNumbers.RemoveAt(nextIndex);
return number;
}
}
}
It's may be a little bit late, but here is more suitable code, for example when you need to use loops:
List<int> genered = new List<int>();
Random rnd = new Random();
for(int x = 0; x < files.Length; x++)
{
int value = rnd.Next(0, files.Length - 1);
while (genered.Contains(value))
{
value = rnd.Next(0, files.Length - 1);
}
genered.Add(value);
returnFiles[x] = files[value];
}
with Functional way*
static Func<int> GetNextUniqueIntegerFunc(int min, int max)
{
var list = new List<int>();
var random = new Random();
int getNextValue()
{
while (true)
{
var random_number = random.Next(min, max);
if (!list.Contains(random_number))
{
list.Add(random_number);
return random_number;
}
}
}
return getNextValue;
}
unique random number from 0 to 9
int sum = 0;
int[] hue = new int[10];
for (int i = 0; i < 10; i++)
{
int m;
do
{
m = rand.Next(0, 10);
} while (hue.Contains(m) && sum != 45);
if (!hue.Contains(m))
{
hue[i] = m;
sum = sum + m;
}
}
You could also use a dataTable storing each random value, then simply perform the random method while != values in the dataColumn
randomNumber function return unqiue integer value between 0 to 100000
bool check[] = new bool[100001];
Random r = new Random();
public int randomNumber() {
int num = r.Next(0,100000);
while(check[num] == true) {
num = r.Next(0,100000);
}
check[num] = true;
return num;
}
hi here i posted one video ,and it explains how to generate unique random number
public List<int> random_generator(){
Random random = new Random();
List<int> random_container = new List<int>;
do{
int random_number = random.next(10);
if(!random_container.contains(random_number){
random_container.add(random_number)
}
}
while(random_container.count!=10);
return random_container;
}
here ,,, in random container you will get non repeated 10 numbers starts from 0 to 9(10 numbers) as random.. thank you........
You can use basic Random Functions of C#
Random ran = new Random();
int randomno = ran.Next(0,100);
you can now use the value in the randomno in anything you want but keep in mind that this will generate a random number between 0 and 100 Only and you can extend that to any figure.
Try this:
private void NewNumber()
{
Random a = new Random(Guid.newGuid().GetHashCode());
MyNumber = a.Next(0, 10);
}
Some Explnations:
Guid : base on here : Represents a globally unique identifier (GUID)
Guid.newGuid() produces a unique identifier like "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"
and it will be unique in all over the universe base on here
Hash code here produce a unique integer from our unique identifier
so Guid.newGuid().GetHashCode() gives us a unique number and the random class will produce real random numbers throw this
Sample:
https://rextester.com/ODOXS63244
generated ten random numbers with this approach with result of:
-1541116401
7
-1936409663
3
-804754459
8
1403945863
3
1287118327
1
2112146189
1
1461188435
9
-752742620
4
-175247185
4
1666734552
7
we got two 1s next to each other, but the hash codes do not same.

Seeing the same results from the function that returns random string [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 6 years ago.
I am new to C#, I have a code that calls the same function 3 times that returns a random sting. For some reason my code is returning the same string all the time. Please help.
public static String randomString()
{
String chars = "QWERTYUIOPASDFGHJKLZXCVBNM";
Random rand = new Random();
String finalstring = null;
for (int i = 0; i < 8; i++)
{
finalstring += chars[rand.Next(0, chars.Length - 1)];
}
return finalstring;
}
public void SecondTest()
{
Console.WriteLine(Class1.randomString());
Console.WriteLine(Class1.randomString());
Console.WriteLine(Class1.randomString());
}
Sample Output observing:
AXCFSDRG
AXCFSDRG
AXCFSDRG
You're constructing three separate Random objects, rather than reusing a single Random object (which would be better practice).
Random objects, if you don't provide a seed, are seeded with the current time. In this case, your randomString() method returns so fast that all three Random objects get the same seed, and thus get the same sequence of outputs.
Based from this SO Answer.
Every time you do new Random() it is initialized using the clock. This
means that in a tight loop you get the same value lots of times. You
should keep a single Random instance and keep using Next on the same
instance.
//Function to get random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}
Use RNGCryptoServiceProvider class:
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider(v=vs.110).aspx
Look at RNGCryptoServiceProvider: generate random numbers in the range [0, randomMax)
If you use the extension method in the answer and the following:
public static String randomString()
{
String chars = "QWERTYUIOPASDFGHJKLZXCVBNM";
Random rand = new Random();
String finalstring = null;
for (int i = 0; i < 8; i++)
{
finalstring += chars[GenerateRandomNumber(8)];
}
return finalstring;
}
public static int GenerateRandomNumber(int length)
{
using (var randomNumberGenerator = new RNGCryptoServiceProvider())
{
return randomNumberGenerator.GetNextInt32(length);
}
}
The result will be different each time.

Unique 4 digit random number in C#

I want to generate an unique 4 digit random number. This is the below code what I have tried:
Code for generating random number
//Generate RandomNo
public int GenerateRandomNo()
{
int _min = 0000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
The problem is I have received a random no with value 241 which is not a 4 digit number. Is there any problems with the code?
//Generate RandomNo
public int GenerateRandomNo()
{
int _min = 1000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
you need a 4 digit code, start with 1000
private Random _random = new Random();
public string GenerateRandomNo()
{
return _random.Next(0, 9999).ToString("D4");
}
241 is a four digit number, if you use leading zeros: 0241.
Display the returned number with a format string like this:
String.Format("{0:0000}", n);
Just one line code
int num = new Random().Next(1000, 9999);
0 is the same as 0000.
241 is the same as 0241.
You could format the integer to a string with a leading zero.
Random generator = new Random();
string number = generator.Next(1, 10000).ToString("D4");
use: int _min = 1000;
or use leading 0 in case if you want 0241
I suggest to create new list and check if this list contains any of number
var IdList = new List<int>();
do
{
billId = random.Next(1, 9000);
} while (IdList.Contains(billId));
IdList.Add(billId);
int NoDigits = 4;
Random rnd = new Random();
textBox2.Text = rnd.Next((int)Math.Pow(10, (NoDigits - 1)), (int)Math.Pow(10, NoDigits) -1).ToString();
Expanding on the answer from brij but with 0000 to 9999 rather than 1000 to 9999
string formatting = "0000"; //Will pad out to four digits if under 1000
int _min = 0;
int _max = 9999;
Random randomNumber = new Random();
var randomNumberString = randomNumber.Next(_min, _max).ToString(formatting);
or if you want to minimalize lines:
Random randomNumber = new Random();
var randomNumberString = randomNumber.Next(0, 9999).ToString("0000");
Using this you will avoid starting numbers with 00[...] and you can also specify the length.
string RandomNumbers(int Length)
{
Random Rand = new Random();
StringBuilder SB = new StringBuilder();
for (int i = 0; i < Length; i++)
SB.Append(Rand.Next(0, 9));
return SB.ToString();
}
RandomNumbers(4) // OUTPUT: 9301, 4936, 0692, etc ...
Here is Method to generate any digits number. The loop inside will regenerate the number if it contains duplicate digits, so the random number will consist from unique digits only.
using System.Linq;
public static int GenerateRandomNum()
{
// Number of digits for random number to generate
int randomDigits = 4;
int _max = (int)Math.Pow(10, randomDigits);
Random _rdm = new Random();
int _out = _rdm.Next(0, _max);
while (randomDigits != _out.ToString().ToArray().Distinct().Count())
{
_out = _rdm.Next(0, _max);
}
return _out;
}
You can consider something like this.
int length = 4;
int number = 50;
string asString = number.ToString("D" + length);
The above code gives the result 0050.
Similarly you can try converting to string and verify.

Non duplicate random numbers in C# [duplicate]

This question already has answers here:
Random.Next returns always the same values [duplicate]
(4 answers)
Closed 9 years ago.
I am trying to create a range of non duplicate random numbers between 1 - 10, I planned on doing this by storing each random number I made in to an array and then checking that array every time to make sure I ain't already used the number.
My problem is that instead of creating different random numbers such as 1, 2, 3 I just keep getting the same random number over and over.
randomNumber();
Label1.Text = randomRow + "";
randomNumber();
Label2.Text = randomRow + "";
randomNumber();
Label3.Text = randomRow + "";
public int randomNumber()
{
List<int> numbers = new List<int>();
int num = 0;
Random randNum = new Random();
num = randNum.Next(1, 11);
if (numbers.Contains(num))
{
num = randNum.Next(1, 11);
}
else
{
randomRow = num;
numbers.Add(num);
}
return randomRow;
}
Problem : everytime you are creating the RandomNumber object in too close time.
When you create a Random object, it's seeded with a value from the system clock. If you create Random instances too close in time, they will all be seeded with the same random sequence.
From Here
When you create a Random object, it's seeded with a value from the
system clock. If you create Random instances too close in time, they
will all be seeded with the same random sequence.
Solution :
move Random randNum = new Random(); outside the function randomNumber().
Try This:
Random randNum = new Random();
public int randomNumber()
{
List<int> numbers = new List<int>();
int num = 0;
num = randNum.Next(1, 11);
if (numbers.Contains(num))
{
num = randNum.Next(1, 11);
}
else
{
randomRow = num;
numbers.Add(num);
}
return randomRow;
}
My best gues is that you are using this in a loop. In this case because you declare
Random randNum = new Random();
evry time this will generate tha same number. Just declare it BEFORE the loop and it should be fine.
Also you should consider a different approch because it is not a good practice. Like:
int[] array = {1,2,3,4,5,6,7,8,9,10};
Random randNum = new Random();
int rand=0;
int temp;
for(int i = 0; i<10;i++)
{
rand = randNum.next(1,10-i);
temp=array[rand];
array[rand]=array[9-i];
array[9-i]=temp;
}

generating string from exited characters

I have a character array as shown below :
char[] pwdCharArray = "abcdefghijklmnopqrstuvwxyzABCDEFG" +
"HIJKLMNOPQRSTUVWXYZ0123456789`~!##$%^&*()-_=+[]{}\\|;:'\",<" +
".>/?".ToCharArray();
and from this char array, i want to generate a string of minimum length 7 and all the characters in the string should be from the above char array.
How to do this operation?
What's the maximum length? (You may want to parameterize the methods below to specify a minimum and maximum length.) Here's a simple way of doing it for exactly 7 characters:
Here's the C# version:
public string GeneratePassword(Random rng)
{
char[] chars = new char[7];
for (int i = 0; i < chars.Length; i++)
{
chars[i] = pwdCharArray[rng.Next(pwdCharArray.Length)];
}
return new string(chars);
}
Note that the Random instance should be passed in to avoid the common problem of creating many instances of Random. I have an article describing this problem and ways around it. In essence, you should use one instance of Random per thread - don't create a new instance every time you want to use one, and don't reuse the same instance across multiple threads.
In fact, for a genuine password which is guarding sensitive information, you probably shouldn't be using Random at all, but rather something like RNGCryptoServiceProvider (or less directly, the results of RandomNumberGenerator.Create()). This can be somewhat harder to use, but will give you much more secure random numbers.
In Java it would be pretty similar, but then I'd use SecureRandom (which is fortunately rather easier to use than its .NET counterpart). In this case, you can create a new instance each time:
public String generatePassword() {
char[] chars = new char[7];
SecureRandom rng = new SecureRandom();
for (int i = 0; i < chars.length; i++) {
chars[i] = pwdCharArray[nextInt(pwdCharArray.length)];
}
return new String(chars);
}
Generate 7 random numbers between 0 and yourArray.length -1.
Pick the corresponding char in the array and put it in your final String.
Here is the code with a StringBuilder:
StringBuilder sb = new StringBuilder();
Random random = new Randdom();
for(int i=0; i<7; i++) {
sb.append(pwdCharArray[random.nextInt(0, pwdCharArray.length -1)]);
}
return sb.toString();
(C# example)
Random rand = new Random();
char[] arr = new char[rand.Next(7,15)];
for(int i = 0 ; i < arr.Length ; i++) {
arr[i] = pwdCharArray[rand.Next(pwdCharArray.Length)];
}
string pwd = new string(arr);
Here is a solution in Java, with variable length of the word, and test of working:
import java.util.*;
public class RandomWord {
// Valid characters
private static String VALID_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFG" +
"HIJKLMNOPQRSTUVWXYZ0123456789`~!##$%^&*()-_=+[]{}\\|;:'\",<.>/?";
// Minimal length thw word can have
private static int MIN_LENGTH = 7;
// Maximal length will be MIN_LENGTH + THRESHOLD - 1
private static int THRESHOLD = 10;
// Generate a random number generator.
// The time in millis is used as seed prevents the numbers to be always the same in same order
Random randomGenerator = new Random(System.currentTimeMillis());
public String generateWord () {
// Actual length of the word (from MIN_LENGTH to MIN_LENGTH + THRESHOLD - 1)
int length = MIN_LENGTH + randomGenerator.nextInt(THRESHOLD);
// Loop for every character
StringBuilder word = new StringBuilder();
for (int i = 0; i < length; i++) {
// Appends one more random char
word.append(VALID_CHARACTERS.charAt(randomGenerator.nextInt(VALID_CHARACTERS.length())));
}
// Returns the random word
return word.toString();
}
// Test the class
public static void main (String[] args) {
// Instantiates and tests the class
RandomWord randomWord = new RandomWord();
for (int i = 0; i < 30; i++) {
String word = randomWord.generateWord();
System.out.println(word + " (" + word.length() + ")");
}
}
}

Categories