число - криптографический генератор случайных чисел c#




Как создать случайный номер int в C#? (18)

Быстро и просто для встроенного, используйте следующий код:

new Random().Next(min, max);

// for example unique name
strName += "_" + new Random().Next(100, 999);

Как создать случайное целое число в C #?


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

Для этого нам нужно сначала понять термин RANDOMNESS и философию, стоящую за ним.

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

Во-первых, давайте понять философию RANDOMNESS. Когда мы говорим человеку, чтобы выбрать между RED, GREEN и YELLOW, что происходит внутри страны. Что заставляет человека выбирать КРАСНЫЙ или ЖЕЛТЫЙ или ЗЕЛЕНЫЙ?

Некоторая первоначальная мысль идет в ум людей, который решает его выбор, это может быть любимый цвет, удачный цвет и так далее. Другими словами, некоторый начальный триггер, который мы называем RANDOM как SEED. Этот SEED является начальной точкой, триггером, который подталкивает его к выбору значения RANDOM.

Теперь, если SEED легко догадаться, тогда такие случайные числа называются PSEUDO, и когда семя трудно угадать, эти случайные числа называются SECURED случайными числами.

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

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

* «Случайный» класс генерирует только случайное число PSEUDO и генерирует безопасное случайное число, которое нам нужно использовать для класса «RNGCryptoServiceProvider».

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

Random rnd= new Random();
int rndnumber = rnd.Next()

В то время как класс RNGCryptoServiceProvider использует энтропию OS для генерации семян. Энтропия ОС - это случайное значение, которое генерируется с использованием звука, щелчка мышью и таймингов клавиатуры, термической температуры и т. Д. Ниже приведен код для того же самого.

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 генерирует безопасные случайные числа.


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

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

string randomDigits = rnd.Next().ToString().Substring(0, 8);

var requestNumber = $"SD-{randomDigits}";

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

Модифицированный ответ here .

Если у вас есть доступ к совместимому с Intel Secure Key процессору, вы можете генерировать реальные случайные числа и строки, используя эти библиотеки: https://github.com/JebteK/RdRand и https://www.rdrand.com/

Просто скачайте последнюю версию here , включите Jebtek.RdRand и добавьте в нее инструкцию для использования. Затем все, что вам нужно сделать, это:

bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
string key = RdRandom.GenerateKey(10); //Generate 10 random characters
string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int

Если у вас нет совместимого процессора для выполнения кода, просто используйте службы RESTful на rdrand.com. С библиотекой обертки RdRandom, включенной в ваш проект, вам просто нужно это сделать (вы получаете 1000 бесплатных звонков при регистрации):

string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");

Остерегайтесь того, что new Random() выставляется на текущую временную метку.

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

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

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

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

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


Пока все в порядке:

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

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

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

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

int randomNumber = random.Next(5, 16)

Попробуйте эти простые шаги для создания случайных чисел:

Создать функцию:

private int randomnumber(int min, int max)
{
    Random rnum = new Random();
    return rnum.Next(min, max);
}

Используйте вышеуказанную функцию в том месте, где вы хотите использовать случайные числа. Предположим, вы хотите использовать его в текстовом поле.

textBox1.Text = randomnumber(0, 999).ToString();

0 - мин, а 999 - макс. Вы можете изменить значения так, как хотите.


У меня всегда есть методы, которые генерируют случайные числа, которые помогают в различных целях. Надеюсь, это тоже поможет:

public class RandomGenerator  
{  
    public int RandomNumber(int min, int max)  
    {  
        Random random = new Random();  
        return random.Next(min, max);  
    }  

    public string RandomString(int size, bool lowerCase)  
    {  
        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 (lowerCase)  
            return builder.ToString().ToLower();  
        return builder.ToString();  
    }  
}

Числа, генерируемые встроенным классом 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);
    }
}

Я использую ниже код для случайного числа:

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

Я пробовал все эти решения, исключая ответ 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); 
}

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


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

Класс 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);
}

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

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

Обновить

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

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


Класс Random используется для создания случайных чисел. (Конечно, это случайная случайность).

Пример:

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


Random r = new Random();
int n = r.Next();

Random rand = new Random();
int name = rand.Next()

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





random