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

<p>как мне генерировать случайное целое число в c #?</p>

<p> <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random"><code>random</code> class</a> используется для создания случайных чисел. (псевдослучайный, конечно.).</p><p>пример:</p><pre class="lang-cs prettyprint-override"><code>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 </code></pre><p>если вы собираетесь создать более одного случайного числа, вам следует сохранить экземпляр <code>random</code> и использовать его повторно. если вы создаете новые экземпляры слишком близко по времени, они будут производить ту же серию случайных чисел, что и генератор случайных чисел, высеянный из системных часов.</p>

<p>каждый раз, когда вы делаете новый random (), он инициализируется. это означает, что в тесном цикле вы получаете одно и то же значение много раз. вы должны сохранить один экземпляр random и продолжать использовать next на том же экземпляре.</p><pre><code>//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); } } </code></pre>

<p>вопрос выглядит очень простым, но ответ немного сложен. если вы видите, почти все предложили использовать класс random, а некоторые предложили использовать крипто-класс rng. но тогда когда выбирать что.</p><p>для этого нам нужно сначала понять термин случайность и его философию.</p><p>я бы посоветовал вам посмотреть это видео, которое углубленно раскрывает философию случайности с использованием c # <a href="https://www.youtube.com/watch?v=tcyxc-2-3fy">https://www.youtube.com/watch?v=tcyxc-2-3fy</a> </p><p>прежде всего, давайте поймем философию случайности. когда мы говорим человеку выбирать между красным, зеленым и желтым, что происходит внутри. что заставляет человека выбирать красный, желтый или зеленый?</p><p> <a href="https://i.stack.imgur.com/nsoql.png"><img src="https://i.stack.imgur.com/nsoql.png" alt="c# random"></a> </p><p>некоторая начальная мысль приходит в ум человека, который решает его выбор, это может быть любимый цвет, счастливый цвет и так далее. другими словами, некоторый начальный триггер, который мы называем в случайном как seed. этот seed является начальной точкой, триггером, побуждающим его выбрать случайное значение.</p><p>теперь, если seed легко угадать, то случайные числа такого типа называются <strong>псевдо</strong>, а когда семени трудно угадать, эти случайные числа <strong>защищенные</strong> случайные числа.</p><p>например, человек выбирает цвет в зависимости от сочетания погоды и звука, тогда будет трудно угадать начальное зерно.</p><p> <a href="https://i.stack.imgur.com/vq9y5.png"><img src="https://i.stack.imgur.com/vq9y5.png" alt="c# random"></a> </p><p>теперь позвольте мне сделать важное заявление:</p><p>* "случайный" класс генерирует только случайное число pseudo, и для генерации безопасного случайного числа нам нужно использовать класс "rngcryptoserviceprovider".</p><p> <a href="https://i.stack.imgur.com/jj93t.png"><img src="https://i.stack.imgur.com/jj93t.png" alt="c# random"></a> </p><p>случайный класс берет начальные значения из вашего процессора, что очень предсказуемо. другими словами, случайный класс c # генерирует псевдослучайные числа, ниже приведен код этого же.</p><pre><code>var random = new random(); int randomnumber = random.next() </code></pre><p>в то время как класс rngcryptoserviceprovider использует энтропию ос для генерации начальных чисел. энтропия ос - это случайное значение, которое генерируется с использованием звука, времени щелчка мыши и клавиатуры, температуры и т.д. ниже приведен код для того же самого.</p><pre><code>using (rngcryptoserviceprovider rg = new rngcryptoserviceprovider()) { byte[] rno = new byte[5]; rg.getbytes(rno); int randomvalue = bitconverter.toint32(rno, 0); } </code></pre><p>чтобы понять энтропию ос, посмотрите это видео с 14:30 <a href="https://youtu.be/tcyxc-2-3fy?t=14m31s">https://www.youtube.com/watch?v=tcyxc-2-3fy</a> где объясняется логика энтропии ос. таким образом, говоря простыми словами, rng crypto генерирует безопасные случайные числа.</p>

<p>помните, что <code>new random()</code> засеян на текущую метку времени.</p><p>если вы хотите сгенерировать <strong> только одно число </strong>, вы можете использовать:</p><p><code>new random().next( int.minvalue, int.maxvalue )</code></p><p>для получения дополнительной информации посмотрите на класс <a href="http://msdn.microsoft.com/en-us/library/system.random.aspx">random</a> , хотя, пожалуйста, обратите внимание:</p><blockquote> <p>однако, поскольку часы имеют конечное разрешение, использование конструктора без параметров для создания различных случайных объектов в тесной последовательности создает генераторы случайных чисел, которые создают идентичные последовательности случайных чисел.</p> </blockquote><p>поэтому не используйте этот код для генерации серии случайных чисел.</p>

<pre><code>random r = new random(); int n = r.next(); </code></pre>

<p>я хотел добавить криптографически безопасную версию:</p><p>класс rngcryptoserviceprovider ( <a href="https://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider(v=vs.110).aspx">msdn</a> или <a href="http://www.dotnetperls.com/rngcryptoserviceprovider">dotnetperls</a> )</p><p>он реализует idisposable.</p><pre><code>using (rngcryptoserviceprovider rng = new rngcryptoserviceprovider()) { byte[] randomnumber = new byte[4];//4 for int32 rng.getbytes(randomnumber); int value = bitconverter.toint32(randomnumber, 0); } </code></pre>

<p>вы можете использовать метод джона скита <a href="http://www.yoda.arachsys.com/csharp/miscutil/">staticrandom</a> внутри библиотеки классов miscutil, которую он построил для псевдослучайного числа.</p><pre><code>using miscutil; ... for (int i = 0; i < 100; console.writeline(staticrandom.next()); </code></pre>

<p>лучше заполнить объект random текущими миллисекундами, чтобы обеспечить истинное случайное число, и вы почти не найдете дубликаты, использующие его много раз</p><pre><code>random rand = new random(datetime.now.millisecond); </code></pre><p><strong>обновление</strong></p><p>я знаю, что <code>new random()</code> использует текущие тики в качестве начального числа, но затравка с текущими миллисекундами все еще достаточно хороша, так как это хороший случайный запуск</p><p>последний оставшийся момент заключается в том, что вам не нужно инициализировать <code>new random()</code> каждый раз, когда вам нужно случайное число, инициируйте один объект random, затем используйте его столько раз, сколько вам нужно внутри цикла или что-то еще</p>

<p>я перепробовал все эти решения, кроме ответа на cobol ... lol</p><p>ни одно из этих решений не было достаточно хорошим. мне нужны были случайные числа в быстром для цикла int, и я получал тонны повторяющихся значений даже в очень широких диапазонах. слишком долго соглашаясь на случайные результаты, я решил, наконец, решить эту проблему раз и навсегда.</p><p>это все о семени.</p><p>я создаю случайное целое число, анализируя не-цифры из guid, а затем использую это для создания экземпляра моего класса random.</p><pre><code>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); } </code></pre><p><strong>обновление</strong>: заполнение не требуется, если вы создаете экземпляр класса random один раз. так что было бы лучше создать статический класс и вызвать метод из этого.</p><pre><code>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); } } </code></pre><p>тогда вы можете использовать статический класс следующим образом.</p><pre><code>for(var i = 0; i < 1000; i++) { int randomnumber = intutil.random(1,100); console.writeline(randomnumber); } </code></pre><p>я признаю, что мне нравится этот подход лучше.</p>

<p>числа, генерируемые встроенным классом <code>random</code> (system.random), генерируют псевдослучайные числа.</p><p>если вам нужны истинные случайные числа, самое близкое, что мы можем получить - это "безопасный генератор псевдослучайных данных", который можно сгенерировать с помощью криптографических классов в c #, таких как <code>rngcryptoserviceprovider</code>.</p><p>тем не менее, если вам все еще нужны <em>true</em> случайные числа, вам нужно будет использовать внешний источник, такой как устройства, учитывающие радиоактивный распад, в качестве начального числа для генератора случайных чисел. поскольку, по определению, любое число, сгенерированное чисто алгоритмическими средствами, не может быть действительно случайным.</p>

<p>я использую код ниже, чтобы иметь случайное число:</p><pre><code>var random = new random((int)datetime.now.ticks); var randomvalue = random.next(startvalue, endvalue + 1); </code></pre>

<p>модифицированный ответ от <a href="https://stackoverflow.com/questions/1122483/random-string-generator-returning-same-string/22801467#22801467">здесь</a> .</p><p>если у вас есть доступ к процессору, совместимому с intel secure key, вы можете генерировать реальные случайные числа и строки, используя следующие библиотеки: <a href="https://github.com/jebtek/rdrand">https://github.com/jebtek/rdrand</a> и <a href="https://www.rdrand.com/">https://www.rdrand.com/</a> </p><p>просто скачайте последнюю версию с <a href="https://github.com/jebtek/rdrand/tree/master/versions">здесь</a> , включите jebtek.rdrand и добавьте оператор использования для него. затем все, что вам нужно сделать, это:</p><pre><code>// 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(); </code></pre><p>если у вас нет совместимого процессора для выполнения кода, просто используйте службы restful на rdrand.com. с библиотекой оболочки rdrandom, включенной в ваш проект, вам просто нужно сделать это (вы получаете 1000 бесплатных звонков при регистрации):</p><pre><code>string ret = randomizer.generatekey(<length>, "<key>"); uint ret = randomizer.generateuint("<key>"); byte[] ret = randomizer.generatebytes(<length>, "<key>"); </code></pre>

<p>это класс, который я использую. работает как <code>randomnumber.generaterandom(1, 666)</code></p><pre><code>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); } } </code></pre>

<pre><code>random random = new random (); int randomnumber = random.next (lowerbound,upperbound); </code></pre>

<p>для сильных случайных семян я всегда использую cryptorng, а не time.</p><pre><code>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); } } } </code></pre>

<p>пока это нормально</p><pre><code>random random = new random(); int randomnumber = random.next() </code></pre><p>вы бы хотели контролировать лимит (минимальное и максимальное количество) большую часть времени. поэтому вам нужно указать, где случайное число начинается и заканчивается.</p><p>метод <code>next()</code> принимает два параметра, min и max.</p><p>так что, если я хочу, чтобы мое случайное число было между 5 и 15, я бы просто сделал</p><pre><code>int randomnumber = random.next(5, 16) </code></pre>

<p>числа, рассчитанные компьютером с помощью детерминированного процесса, по определению не могут быть случайными.</p><p>если вам нужны настоящие случайные числа, случайность происходит из-за атмосферного шума или радиоактивного распада.</p><p>вы можете попробовать, например, random.org (это снижает производительность)</p>

<p>я хотел продемонстрировать, что происходит, когда каждый раз используется новый генератор случайных чисел. предположим, у вас есть два метода или два класса, каждый из которых требует случайного числа. и вы наивно кодируете их так:</p><pre><code>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; } } </code></pre><p>как вы думаете, вы получите два разных идентификатора? <strong>nope</strong></p><pre><code>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 } } </code></pre><p>решение состоит в том, чтобы <em> всегда </em> использовать один статический генератор случайных чисел. как это:</p><pre><code>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; } } </code></pre>

<pre><code>random rand = new random(); int name = rand.next() </code></pre><p>поместите любые значения во вторые скобки, чтобы убедиться, что вы установили имя, написав prop и double tab для генерации кода.</p>

<p>вы можете попробовать со случайным начальным значением, используя ниже:</p><pre><code>var rnd = new random(11111111); //note: seed value is 11111111 string randomdigits = rnd.next(); var requestnumber = $"sd-{randomdigits}"; </code></pre>

<p>самый простой способ - это, вероятно, просто <code>random.range(1, 3)</code> это сгенерирует число от 1 до 2.</p>

<p>я предполагаю, что вы хотите равномерно распределенный генератор случайных чисел, как показано ниже. случайные числа в большинстве языков программирования, включая c # и c++, неправильно перетасовываются перед их использованием. это означает, что вы будете получать одно и то же число снова и снова, что на самом деле не случайно. чтобы не рисовать одно и то же число снова и снова, вам нужно семя. как правило, тики во времени хорошо для этой задачи. помните, что вы будете получать одно и то же число снова и снова, если будете использовать одно и то же семя каждый раз. поэтому старайтесь всегда использовать разные семена. время является хорошим источником для семян, потому что они всегда растеряны.</p><pre><code>int getrandomnumber(int min, int max) { random rand = new random((int)datetime.now.ticks); return rand.next(min, max); } </code></pre><p>если вы ищете генератор случайных чисел для нормального распределения, вы можете использовать преобразование бокса-мюллера. проверьте ответ по yoyoyoyosef в вопросе о случайной гауссовой переменной. так как вы хотите целое число, вы должны привести двойное значение к целому в конце.</p><pre><code>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) </code></pre><p> <a href="https://stackoverflow.com/questions/218060/random-gaussian-variables">случайные гауссовские переменные</a> </p>