it-swarm.xyz

Как мне сгенерировать случайное число int?

Как мне генерировать случайное целое число в C #?

1692
Rella

Random class используется для создания случайных чисел. (Псевдослучайный, конечно.).

Пример:

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 и использовать его повторно. Если вы создаете новые экземпляры слишком близко по времени, они будут производить ту же серию случайных чисел, что и генератор случайных чисел, высеянный из системных часов.

2233
Guffa

Каждый раз, когда вы делаете новый Random (), он инициализируется. Это означает, что в тесном цикле вы получаете одно и то же значение много раз. Вы должны сохранить один экземпляр Random и продолжать использовать Next на том же экземпляре.

//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);
    }
}
211
Pankaj Mishra

Вопрос выглядит очень простым, но ответ немного сложен. Если вы видите, почти все предложили использовать класс Random, а некоторые предложили использовать крипто-класс RNG. Но тогда когда выбирать что.

Для этого нам нужно сначала понять термин СЛУЧАЙНОСТЬ и его философию.

Я бы посоветовал вам посмотреть это видео, которое углубленно раскрывает философию случайности с использованием C # https://www.youtube.com/watch?v=tCYxc-2-3fY

Прежде всего, давайте поймем философию СЛУЧАЙНОСТИ. Когда мы говорим человеку выбирать между КРАСНЫМ, ЗЕЛЕНЫМ и ЖЕЛТЫМ, что происходит внутри. Что заставляет человека выбирать красный, желтый или зеленый?

c# Random

Некоторая начальная мысль приходит в ум человека, который решает его выбор, это может быть любимый цвет, счастливый цвет и так далее. Другими словами, некоторый начальный триггер, который мы называем в СЛУЧАЙНОМ как SEED. Этот SEED является начальной точкой, триггером, побуждающим его выбрать СЛУЧАЙНОЕ значение.

Теперь, если SEED легко угадать, то случайные числа такого типа называются ПСЕВДО, а когда семени трудно угадать, эти случайные числа ЗАЩИЩЕННЫЕ случайные числа.

Например, человек выбирает цвет в зависимости от сочетания погоды и звука, тогда будет трудно угадать начальное зерно.

c# Random

Теперь позвольте мне сделать важное заявление:

* "Случайный" класс генерирует только случайное число PSEUDO, и для генерации БЕЗОПАСНОГО случайного числа нам нужно использовать класс "RNGCryptoServiceProvider".

c# Random

Случайный класс берет начальные значения из вашего процессора, что очень предсказуемо. Другими словами, случайный класс C # генерирует псевдослучайные числа, ниже приведен код этого же.

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 где объясняется логика энтропии ОС. Таким образом, говоря простыми словами, RNG Crypto генерирует БЕЗОПАСНЫЕ случайные числа.

209
Shivprasad Koirala

Помните, что new Random() засеян на текущую метку времени.

Если вы хотите сгенерировать только одно число , вы можете использовать:

new Random().Next( int.MinValue, int.MaxValue )

Для получения дополнительной информации посмотрите на класс Random , хотя, пожалуйста, обратите внимание:

Однако, поскольку часы имеют конечное разрешение, использование конструктора без параметров для создания различных случайных объектов в тесной последовательности создает генераторы случайных чисел, которые создают идентичные последовательности случайных чисел.

Поэтому не используйте этот код для генерации серии случайных чисел.

85
Fyodor Soikin
Random r = new Random();
int n = r.Next();
45
Joren

Я хотел добавить криптографически безопасную версию:

Класс RNGCryptoServiceProvider ( MSDN или dotnetperls )

Он реализует IDisposable.

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
   byte[] randomNumber = new byte[4];//4 for int32
   rng.GetBytes(randomNumber);
   int value = BitConverter.ToInt32(randomNumber, 0);
}
27
joordan831

Вы можете использовать метод Джона Скита StaticRandom внутри библиотеки классов MiscUtil, которую он построил для псевдослучайного числа.

using MiscUtil;
...

for (int i = 0; i < 100; 
    Console.WriteLine(StaticRandom.Next());
16
mbcrump

лучше заполнить объект Random текущими миллисекундами, чтобы обеспечить истинное случайное число, и вы почти не найдете дубликаты, использующие его много раз

Random Rand = new Random(DateTime.Now.Millisecond);

Обновление

Я знаю, что new Random() использует текущие тики в качестве начального числа, но затравка с текущими миллисекундами все еще достаточно хороша, так как это хороший случайный запуск

Последний оставшийся момент заключается в том, что вам не нужно инициализировать new Random() каждый раз, когда вам нужно случайное число, инициируйте один объект Random, затем используйте его столько раз, сколько вам нужно внутри цикла или что-то еще

15
Mohamed Selim

Я перепробовал все эти решения, кроме ответа на COBOL ... LOL

Ни одно из этих решений не было достаточно хорошим. Мне нужны были случайные числа в быстром для цикла int, и я получал тонны повторяющихся значений даже в очень широких диапазонах. Слишком долго соглашаясь на случайные результаты, я решил, наконец, решить эту проблему раз и навсегда.

Это все о семени.

Я создаю случайное целое число, анализируя не-цифры из Guid, а затем использую это для создания экземпляра моего класса Random.

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); 
}

Я признаю, что мне нравится этот подход лучше.

12
Proximo

Числа, генерируемые встроенным классом Random (System.Random), генерируют псевдослучайные числа.

Если вам нужны истинные случайные числа, самое близкое, что мы можем получить - это "безопасный генератор псевдослучайных данных", который можно сгенерировать с помощью криптографических классов в C #, таких как RNGCryptoServiceProvider.

Тем не менее, если вам все еще нужны true случайные числа, вам нужно будет использовать внешний источник, такой как устройства, учитывающие радиоактивный распад, в качестве начального числа для генератора случайных чисел. Поскольку, по определению, любое число, сгенерированное чисто алгоритмическими средствами, не может быть действительно случайным.

9
Anshita Arya

Я использую код ниже, чтобы иметь случайное число:

var random = new Random((int)DateTime.Now.Ticks);
var randomValue = random.Next(startValue, endValue + 1);
7
shA.t

Модифицированный ответ от здесь .

Если у вас есть доступ к процессору, совместимому с 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>");
5
JebaDaHut

Это класс, который я использую. Работает как 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);
    }
}
5
AskethZ
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
4
ReRoute

Для сильных случайных семян я всегда использую 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);
        }
    }
}
3
Davit Tvildiani

Пока это нормально

Random random = new Random();
int randomNumber = random.Next()

Вы бы хотели контролировать лимит (минимальное и максимальное количество) большую часть времени. Поэтому вам нужно указать, где случайное число начинается и заканчивается.

Метод Next() принимает два параметра, min и max.

Так что, если я хочу, чтобы мое случайное число было между 5 и 15, я бы просто сделал

int randomNumber = random.Next(5, 16)
3
ojonugwa ochalifu

Числа, рассчитанные компьютером с помощью детерминированного процесса, по определению не могут быть случайными.

Если вам нужны настоящие случайные числа, случайность происходит из-за атмосферного шума или радиоактивного распада.

Вы можете попробовать, например, RANDOM.ORG (это снижает производительность)

2
Stefano Lonati

Я хотел продемонстрировать, что происходит, когда каждый раз используется новый генератор случайных чисел. Предположим, у вас есть два метода или два класса, каждый из которых требует случайного числа. И вы наивно кодируете их так:

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; }
}

Как вы думаете, вы получите два разных идентификатора? NOPE

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
    }
}

Решение состоит в том, чтобы всегда использовать один статический генератор случайных чисел. Как это:

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; }
}
2
ja72
Random Rand = new Random();
int name = Rand.Next()

Поместите любые значения во вторые скобки, чтобы убедиться, что вы установили имя, написав prop и double tab для генерации кода.

2
user3773367

Вы можете попробовать со случайным начальным значением, используя ниже:

var rnd = new Random(11111111); //note: seed value is 11111111

string randomDigits = rnd.Next();

var requestNumber = $"SD-{randomDigits}";
0
Rejwanul Reja

Самый простой способ - это, вероятно, просто Random.range(1, 3) Это сгенерирует число от 1 до 2.

0
Gustav Petersen

Я предполагаю, что вы хотите равномерно распределенный генератор случайных чисел, как показано ниже. Случайные числа в большинстве языков программирования, включая C # и C++, неправильно перетасовываются перед их использованием. Это означает, что вы будете получать одно и то же число снова и снова, что на самом деле не случайно. Чтобы не рисовать одно и то же число снова и снова, вам нужно семя. Как правило, тики во времени хорошо для этой задачи. Помните, что вы будете получать одно и то же число снова и снова, если будете использовать одно и то же семя каждый раз. Поэтому старайтесь всегда использовать разные семена. Время является хорошим источником для семян, потому что они всегда растеряны.

int GetRandomNumber(int min, int max)
{
    Random Rand = new Random((int)DateTime.Now.Ticks);
    return Rand.Next(min, max);
}

если вы ищете генератор случайных чисел для нормального распределения, вы можете использовать преобразование Бокса-Мюллера. Проверьте ответ по yoyoyoyosef в вопросе о случайной гауссовой переменной. Так как вы хотите целое число, вы должны привести двойное значение к целому в конце.

Random Rand = new Random(); //reuse this if you are generating many
double u1 = 1.0-Rand.NextDouble(); //uniform(0,1] random doubles
double u2 = 1.0-Rand.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
         Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal =
         mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)

случайные гауссовские переменные

0
auto9817