Как мне создать случайное целое число в C #?
Random
class используется для создания случайных чисел. (Псевдослучай это конечно.).
Пример:
& Лт;!- язык: c # - >
Random rnd = new Random();
int month = rnd.Next(1, 13); // creates a number between 1 and 12
int dice = rnd.Next(1, 7); // creates a number between 1 and 6
int card = rnd.Next(52); // creates a number between 0 and 51
Если вы собираетесь создать более одного случайного числа, вам следует сохранить экземпляр «Случайный» и повторно использовать его. Если вы создадите новые экземпляры слишком близко во времени, они будут производить ту же серию случайных чисел, что и случайный генератор, посеянный из системных часов.
Вопрос выглядит очень просто, но ответ немного сложен. Если вы видите, почти все предложили использовать класс Random, а некоторые предложили использовать класс криптографии RNG. Но тогда, когда выбирать что.
Для этого нам нужно сначала понять термин RANDOMNESS и философию, стоящую за ним.
Я бы посоветовал вам посмотреть это видео, которое подробно описывает философию RANDOMNESS, используя C # [https://www.youtube.com/watch?v = tCYxc-2-3fY][1]
Первое, давайте поймем философию случайности. Когда мы говорим человеку выбирать между КРАСНЫМ, ЗЕЛЕНЫМ и ЖЕЛТЫМ, что происходит внутри. Что заставляет человека выбирать КРАСНЫЙ или ЖЕЛТЫЙ или ЗЕЛЕНЫЙ?
Некоторая первоначальная мысль приходит в голову людям, которые решают его выбор, это может быть любимый цвет, счастливый цвет и так далее. Другими словами, некоторый начальный триггер, который мы называем в RANDOM как SEED. Этот SEED является начальной точкой, триггером, который побуждает его выбрать значение RANDOM.
Теперь, если SEED легко угадать, тогда такие случайные числа называются PSEUDO , а когда семени трудно угадать, эти случайные числа называются SECURED случайными числами.
Например, человек выбирает цвет в зависимости от погоды и звуковой комбинации, тогда будет трудно угадать начальное семя.
Теперь позвольте мне сделать важное заявление: -
Случайный класс принимает начальные значения из ваших часов процессора, что очень предсказуемо. Другими словами, класс RANDOM C # генерирует псевдослучайные числа, ниже приведен код для того же.
Примечание: .NET Core 2.0.0+
использует другое семя в конструкторе без параметров: вместо часов процессора он использует Guid.NewGuid () .GetHashCode ()
.
var random = new Random();
int randomnumber = random.Next()
В то время как класс RNGCryptoServiceProvider
использует энтропию ОС для генерации семян. Энтропия ОС - это случайное значение, которое генерируется с использованием звука, щелчка мышью и времени работы клавиатуры, тепловой температуры и т. Д. Ниже идет код для того же.
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[5];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
}
Чтобы понять энтропию ОС, смотрите это видео с 14:30 [https://www.youtube.com/watch?v = tCYxc-2-3fY][5], где объясняется логика энтропии ОС. Таким образом, вставляя простые слова, RNG Crypto генерирует БЕЗОПАСНЫЕ случайные числа.
[1]: https://www.youtube.com/watch?v = tCYxc-2-3fY
[5]:
= 14m31sКаждый раз, когда вы делаете новый Random (), он инициализируется . Это означает, что в узком цикле вы получаете одно и то же значение много раз. Вы должны сохранить один случайный экземпляр и продолжать использовать следующий в том же экземпляре.
//Function to get random number
private static readonly Random getrandom = new Random();
public static int GetRandomNumber(int min, int max)
{
lock(getrandom) // synchronize
{
return getrandom.Next(min, max);
}
}
Помните, что new Random ()
посеян на текущей метке времени.
Если вы хотите сгенерировать только один номер , вы можете использовать:
new Random (). Next (int.MinValue, int.MaxValue)
Для получения дополнительной информации посмотрите на < a href = "http://msdn.microsoft.com/en-us/library/system.random.aspx" > Random < / a > класс, хотя обратите внимание:
Однако, поскольку часы имеют конечное разрешение, использование конструктора без параметров для создания различных случайных объектов в тесной последовательности создает генераторы случайных чисел, которые производят идентичные последовательности случайных чисел
Поэтому не используйте этот код для генерации серии случайных чисел.
Я хотел добавить криптографически безопасную версию:
RNGCryptoServiceProvider Class ([MSDN][1] или dotnetperls)
Он реализует IDisposable.
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] randomNumber = new byte[4];//4 for int32
rng.GetBytes(randomNumber);
int value = BitConverter.ToInt32(randomNumber, 0);
}
[1]: https://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider(v = vs.110).aspx
Вы можете использовать метод Джона Скита StaticRandom в библиотеке классов MiscUtil, которую он создал для псевдослучайного числа.
using MiscUtil;
...
for (int i = 0; i < 100;
Console.WriteLine(StaticRandom.Next());
лучше сеять случайный объект с текущими миллисекундами, чтобы обеспечить истинное случайное число, и вы почти не найдете дубликатов, использующих его много раз
Random rand = new Random(DateTime.Now.Millisecond);
Обновить
Я знаю, что new Random ()
использует текущие клещи в качестве семени, но посев с текущими миллисекундами все еще достаточно хорош, так как это хороший случайный старт
Последняя оставшаяся точка заключается в том, что вам не нужно инициализировать new Random ()
каждый раз, когда вам нужно случайное число, инициировать один случайный объект, а затем использовать его столько раз, сколько вам нужно внутри цикла или чего-то еще
Я попробовал все эти решения, исключая ответ COBOL... лол
Ни одно из этих решений не было достаточно хорошим. Мне нужны были рандомы в быстром цикле int, и я получал тонны дублирующих значений даже в очень широких диапазонах. Слишком долго соглашаясь на случайные результаты, я решил окончательно решить эту проблему раз и навсегда.
Это все о семени.
Я создаю случайное целое число, анализируя нецифры из Guid, затем я использую это для создания своего Случайного класса.
public int GenerateRandom(int min, int max)
{
var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
return new Random(seed).Next(min, max);
}
Обновление : посев не требуется, если вы один раз создаете класс Random. Так что было бы лучше создать статический класс и вызвать метод из этого.
public static class IntUtil
{
private static Random random;
private static void Init()
{
if (random == null) random = new Random();
}
public static int Random(int min, int max)
{
Init();
return random.Next(min, max);
}
}
Тогда вы можете использовать статический класс, как это..
for(var i = 0; i < 1000; i++)
{
int randomNumber = IntUtil.Random(1,100);
Console.WriteLine(randomNumber);
}
Я признаю, что мне нравится этот подход лучше.
Измененный ответ из здесь.
Если у вас есть доступ к процессору, совместимому с Intel Secure Key, вы можете генерировать реальные случайные числа и строки, используя эти библиотеки: https://github.com/JebteK/RdRand и https://www.rdrand.com/
Просто скачайте последнюю версию из здесь, включите Jebtek.RdRand и добавьте для нее оператор использования. Тогда все, что вам нужно сделать, это:
// Check to see if this is a compatible CPU
bool isAvailable = RdRandom.GeneratorAvailable();
// Generate 10 random characters
string key = RdRandom.GenerateKey(10);
// Generate 64 random characters, useful for API keys
string apiKey = RdRandom.GenerateAPIKey();
// Generate an array of 10 random bytes
byte[] b = RdRandom.GenerateBytes(10);
// Generate a random unsigned int
uint i = RdRandom.GenerateUnsignedInt();
Если у вас нет совместимого процессора для выполнения кода, просто используйте службы RESTful на rdrand.com. С библиотекой оболочки RdRandom, включенной в ваш проект, вам просто нужно сделать это (при регистрации вы получаете 1000 бесплатных звонков):
string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
Числа, сгенерированные встроенным классом Random
(System.Random), генерируют псевдослучайные числа.
Если вам нужны истинные случайные числа, самое близкое, что мы можем получить, - это «безопасный псевдо-генератор случайных чисел», который можно сгенерировать с помощью криптографических классов в C #, таких как «RNGCryptoServiceProvider».
Тем не менее, если вам все еще нужны истинные случайные числа, вам нужно будет использовать внешний источник, такой как устройства, учитывающие радиоактивный распад, в качестве семени для генератора случайных чисел. Поскольку по определению любое число, сгенерированное чисто алгоритмическими средствами, не может быть действительно случайным.
Это класс, который я использую. Работает как RandomNumber.GenerateRandom (1, 666)
internal static class RandomNumber
{
private static Random r = new Random();
private static object l = new object();
private static Random globalRandom = new Random();
[ThreadStatic]
private static Random localRandom;
public static int GenerateNewRandom(int min, int max)
{
return new Random().Next(min, max);
}
public static int GenerateLockedRandom(int min, int max)
{
int result;
lock (RandomNumber.l)
{
result = RandomNumber.r.Next(min, max);
}
return result;
}
public static int GenerateRandom(int min, int max)
{
Random random = RandomNumber.localRandom;
if (random == null)
{
int seed;
lock (RandomNumber.globalRandom)
{
seed = RandomNumber.globalRandom.Next();
}
random = (RandomNumber.localRandom = new Random(seed));
}
return random.Next(min, max);
}
}
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
Пока это нормально:
Random random = new Random();
int randomNumber = random.Next()
Вы хотели бы контролировать предел (мин и макс мумибер) большую часть времени. Поэтому вам нужно указать, где начинается и заканчивается случайное число.
Метод Next ()
принимает два параметра, min и max.
Так что, если я хочу, чтобы мое случайное число было между 5 и 15, я бы просто сделал
int randomNumber = random.Next(5, 16)
Для сильного случайного семени я всегда использую CryptoRNG, а не Time.
using System;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
var random = new Random(GetSeed());
Console.WriteLine(random.Next());
}
public static int GetSeed()
{
using (var rng = new RNGCryptoServiceProvider())
{
var intBytes = new byte[4];
rng.GetBytes(intBytes);
return BitConverter.ToInt32(intBytes, 0);
}
}
}
Числа, рассчитанные компьютером с помощью детерминированного процесса, по определению не могут быть случайными.
Если вам нужны подлинные случайные числа, случайность исходит от атмосферного шума или радиоактивного распада.
Вы можете попробовать, например, RANDOM.ORG (это снижает производительность)
Я хотел продемонстрировать, что происходит, когда каждый раз используется новый случайный генератор. Предположим, у вас есть два метода или два класса, каждый из которых требует случайного числа. И наивно вы кодируете их как:
public class A
{
public A()
{
var rnd=new Random();
ID=rnd.Next();
}
public int ID { get; private set; }
}
public class B
{
public B()
{
var rnd=new Random();
ID=rnd.Next();
}
public int ID { get; private set; }
}
Как вы думаете, вы получите два разных удостоверения личности? НОП
class Program
{
static void Main(string[] args)
{
A a=new A();
B b=new B();
int ida=a.ID, idb=b.ID;
// ida = 1452879101
// idb = 1452879101
}
}
Решение состоит в том, чтобы always использовать один статический случайный генератор. Нравится:
public static class Utils
{
public static readonly Random random=new Random();
}
public class A
{
public A()
{
ID=Utils.random.Next();
}
public int ID { get; private set; }
}
public class B
{
public B()
{
ID=Utils.random.Next();
}
public int ID { get; private set; }
}
Следующий код возвращает случайное число.& # 160;
int num = random.Next();
Следующий код возвращает случайное число менее 1000.& # 160;
int num = random.Next(1000);
Следующий код возвращает случайное число между минимальным и максимальным диапазоном.
Создать & # 160; a & # 160; random & # 160; число & # 160; между & # 160; два & # 160; числа:
public int RandomNumber(int min, int max)
{
& # 160; & # 160; & # 160; ;
Random random = new Random();
return random.Next(min, max);
}
& # 160; & # 160 ;
Random rand = new Random();
int name = rand.Next()
Поместите все значения, которые вы хотите, во вторые скобки убедитесь, что вы установили имя, написав проп и двойную вкладку для генерации кода