Jak wygenerować losową liczbę całkowitą?


1918

Jak wygenerować losową liczbę całkowitą w C #?

Odpowiedzi:


2501

RandomKlasa służy do tworzenia liczb losowych. (To oczywiście pseudolosowe).

Przykład:

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

Jeśli zamierzasz utworzyć więcej niż jedną liczbę losową, powinieneś zachować Randominstancję i użyć jej ponownie. Jeśli utworzysz nowe wystąpienia zbyt blisko siebie, wygenerują one tę samą serię liczb losowych, jak generator losowy jest wysyłany z zegara systemowego.


183
Tylko uwaga dla użytkowników Unity C #, musisz podać „System.Random ()”, ponieważ Unity ma „UnityEngine.Random ()”, który się koliduje (zwróć uwagę, że „UnityEngine.Random ()” nie ma możliwości generowania losowego liczby). Ponieważ jedność nie zawsze domyślnie importuje System, może to powodować pewne zamieszanie.
Joehot200,

2
Aby go ponownie użyć, możesz zadeklarować rndjako statici / lub ustawić go tylko raz podczas inicjalizacji kodu.
Junior Mayhé,

4
@JuniorM: Tak, można ustawić statyczne użycie, ale należy zachować ostrożność, aby nie uzyskać dostępu do wielu wątków, ponieważ nie jest to bezpieczne dla wątków (jak to zwykle bywa w przypadku klas, które nie są specjalnie zabezpieczone dla wątków ).
Guffa

8
Myślę, że warto byłoby dodać zastrzeżenie, że nie jest to kryptograficznie bezpieczne, ponieważ jest to popularne pytanie, na wypadek, gdyby ktoś ślepo próbował wykonać kryptografię z Random...
Daniel García Rubio

1
Doskonała odpowiedź. Istnieje kilka dobrych „ulepszeń” Random, dzięki którym twoja losowość jest bardziej niezawodna: ericlippert.com/2019/02/04/fixing-random-part-2 i codeblog.jonskeet.uk/2009/11/04/revisiting losowość .
Jesse C. Slicer,

280

Pytanie wygląda na bardzo proste, ale odpowiedź jest nieco skomplikowana. Jeśli widzisz, prawie wszyscy sugerowali użycie klasy Random, a niektórzy sugerowali użycie klasy kryptograficznej RNG. Ale kiedy wybrać, co.

W tym celu musimy najpierw zrozumieć termin RANDOMNESS i leżącą u jego podstaw filozofię.

Zachęcam do obejrzenia tego filmu, który wnika głęboko w filozofię RANDOMNESS przy użyciu C # https://www.youtube.com/watch?v=tCYxc-2-3fY

Po pierwsze, zrozummy filozofię RANDOMNESS. Gdy mówimy osobie, aby wybierała między CZERWONYM, ZIELONYM i ŻÓŁTYM, co dzieje się wewnętrznie. Co sprawia, że ​​dana osoba wybiera CZERWONY, ŻÓŁTY lub ZIELONY?

c # Losowo

Pewna wstępna myśl przychodzi do głowy osoby, która decyduje o jego wyborze, może to być ulubiony kolor, szczęśliwy kolor i tak dalej. Innymi słowy, jakiś początkowy wyzwalacz, który określamy w LOSOWO jako SEED. To SEED jest punktem początkowym, wyzwalaczem, który skłania go do wybrania wartości LOSOWANEJ.

Teraz, jeśli SEED jest łatwy do odgadnięcia, wówczas tego rodzaju liczby losowe są określane jako PSEUDO, a gdy nasiona są trudne do odgadnięcia, te liczby losowe są określane jako BEZPIECZNE liczby losowe.

Na przykład osoba wybiera kolor w zależności od pogody i kombinacji dźwięków, wtedy trudno odgadnąć początkowe ziarno.

c # Losowo

A teraz pozwólcie, że złożę ważne oświadczenie:

* Klasa „Random” generuje tylko losową liczbę PSEUDO i aby wygenerować BEZPIECZNĄ liczbę losową, musimy użyć klasy „RNGCryptoServiceProvider”.

c # Losowo

Klasa losowa pobiera wartości początkowe z zegara procesora, co jest bardzo przewidywalne. Innymi słowy, klasa RANDOM języka C # generuje pseudolosowe liczby, poniżej znajduje się kod tego samego.

** Uwaga: ** .NET Core 2.0.0+używa innego ziarna w konstruktorze bez parametrów: używa zegara procesora Guid.NewGuid().GetHashCode().

var random = new Random();
int randomnumber = random.Next()

Podczas gdy RNGCryptoServiceProviderklasa używa entropii systemu operacyjnego do generowania nasion. Entropia systemu operacyjnego jest wartością losową, która jest generowana przy użyciu dźwięku, kliknięcia myszą i ustawień klawiatury, temperatury termicznej itp. Poniżej podano kod dla tego samego.

using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider()) 
{ 
    byte[] rno = new byte[5];    
    rg.GetBytes(rno);    
    int randomvalue = BitConverter.ToInt32(rno, 0); 
}

Aby zrozumieć entropię systemu operacyjnego, zobacz ten film od 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY, gdzie wyjaśniono logikę entropii systemu operacyjnego. Tak więc, mówiąc prosto, RNG Crypto generuje BEZPIECZNE losowe liczby.


9
nie powinien być twoim bajtem [5] tylko [4], ponieważ ToInt32 analizuje tylko 4 bajty?
Bernhard

6
Zawsze dobrze jest wiedzieć, gdzie mieszkają te klasy. System.Security.Cryptography
Elton

1
Zalecane jest użycie RandomNumberGenerator.Create()zamiast wywoływania konstruktora, RNGCryptoServiceProviderponieważ nie jest on dostępny na wszystkich platformach.
dzitkowskik

Chcę tylko sprecyzować, że pseudolosowe generowanie SecureRandom IS.
Nùménor

Z powodu zwiększonej losowości zarodka, czy jest możliwe tworzenie nowych obiektów RNGCryptoServiceProvider za każdym razem, gdy potrzebuję wygenerować liczbę losową, czy też lepiej jest utworzyć jeden obiekt RNGCryptoServiceProvider i użyć go ponownie, gdy będę potrzebować wygenerować liczbę losową, ponieważ należy zrobić z klasą Random?
user2150989

231

Za każdym razem, gdy robisz nowy Random (), jest on inicjowany. Oznacza to, że w ciasnej pętli dostajesz tę samą wartość wiele razy. Powinieneś zachować pojedyncze Losowe wystąpienie i dalej używać Dalej w tym samym wystąpieniu.

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

3
Czy nie to powiedział @Guffa w swojej odpowiedzi 6 miesięcy temu? „Jeśli utworzysz nowe wystąpienia zbyt blisko siebie, wyprodukują one tę samą serię liczb losowych”
Chris,

3
@ Chris - Właśnie tak powiedziałeś. W tym przedstawiłem wdrożenie tego. Myślę, że to dobry sposób na zrobienie tego. Działa lepiej.
Pankaj Mishra

22
Jest to implementacja, która synchronizuje kod do użycia z wątków Seval. Jest to dobre dla aplikacji wielowątkowej, ale strata czasu dla aplikacji wielowątkowej.
Guffa

@SeanWorle: Najpierw spróbowałem z podejściem od Guffa. Potem próbowałem zapisać ten sam Randomobiekt. W obu przypadkach mam ten sam losowy numer. Przy podejściu Pankaja tak się nie stało. Być może jest to przypadkowe , ale teraz wątpię. Pytam o liczbę losową w tej samej sekundzie z różnych wątków.
testowanie

1
@testing: Zgadzam się, że metoda Pankaja jest poprawna. Mówię o tym, że można to uprościć: // Funkcja uzyskania prywatnej liczby prywatnej statycznie tylko do odczytu Random getrandom = new Random (); public static int GetRandomNumber (int min, int max) {lock (getrandom) {// synchronize return getrandom.Next (min, max); }}
Sean Worle,

92

Uważaj, który new Random()jest rozsiewany według bieżącego znacznika czasu.

Jeśli chcesz wygenerować tylko jeden numer , możesz użyć:

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

Aby uzyskać więcej informacji, spójrz na klasę Random , ale pamiętaj:

Ponieważ jednak zegar ma skończoną rozdzielczość, użycie konstruktora bez parametrów do tworzenia różnych obiektów losowych w krótkim odstępie czasu tworzy generatory liczb losowych, które wytwarzają identyczne sekwencje liczb losowych

Dlatego nie używaj tego kodu do generowania serii liczb losowych.


41
-1: Domyślne ziarno zależy od czasu; zrób to w pętli, a otrzymasz bardzo nieprzypadkowe wyniki. Powinieneś stworzyć jeden generator i używać go dla wszystkich swoich liczb, a nie osobnego generatora za każdym razem.
Bevan

21
Hej, to niesprawiedliwe. Pytanie brzmiało, jak wygenerować losową liczbę całkowitą. Nie wspomniano o żadnych pętlach ani seriach.
Fiodor Soikin,

26
Ok, słuszna uwaga. Odwołany. Chociaż nadal uważam, że nie używanie new Random()w pętli jest ważnym punktem.
Bevan,

Dla tych, którzy napotkają to w przyszłości, powinno to być teraz oczywiste, ale po prostu to zaznaczę; odpowiedź została zaktualizowana o ten punkt, aby nie używać tego w pętli dla wielu wartości.
vapcguy


30

Chciałem dodać bezpieczną kryptograficznie wersję:

Klasa RNGCryptoServiceProvider ( MSDN lub dotnetperls )

Implementuje IDisposable.

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

15

Możesz użyć metody StaticRandom Jona Skeeta w bibliotece klas MiscUtil, którą zbudował dla pseudolosowej liczby.

using MiscUtil;
...

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

31
Właśnie spojrzałem na kod źródłowy i ta funkcja używa dokładnie tego samego silnika liczb losowych, tego „uwzględnionego” w C #, ale upewnia się, że do wszystkich wywołań używany jest ten sam obiekt „seed” / „mother”. (Przykro mi, że nie znam terminologii C #. Mam jednak na
myśli,

5
Niemożliwe jest, aby cokolwiek było „naprawdę przypadkowe”, ponieważ zawsze zawiera się jakiś czynnik ograniczający lub uprzedzenia, które są nieodłączne od samego jego istnienia. Nie słuchałeś nauczyciela na lekcjach przedmiotów ścisłych? ;-)
Phill Healey

Powiedzmy, że według niego jest to tak „losowe”, jak to możliwe
The Mitra Boy

Zepsuty link teraz. Dlatego podajesz informacje, które znajdziesz w swojej odpowiedzi.
vapcguy

13

Wypróbowałem wszystkie te rozwiązania z wyjątkiem odpowiedzi COBOL ... lol

Żadne z tych rozwiązań nie było wystarczająco dobre. Potrzebowałem liczb losowych w szybkiej pętli int i dostawałem mnóstwo zduplikowanych wartości nawet w bardzo szerokich zakresach. Po zbyt długim zadowoleniu z losowych wyników postanowiłem ostatecznie rozwiązać ten problem raz na zawsze.

Chodzi o ziarno.

Tworzę losową liczbę całkowitą, parsując nie-cyfry z Guida, a następnie używam jej do utworzenia mojej losowej klasy.

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

Aktualizacja : Seeding nie jest konieczny, jeśli raz utworzysz klasę Random. Dlatego najlepiej byłoby stworzyć klasę statyczną i wywołać z niej metodę.

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

Następnie możesz użyć klasy statycznej w taki sposób ...

for(var i = 0; i < 1000; i++)
{
   int randomNumber = IntUtil.Random(1,100);
   Console.WriteLine(randomNumber); 
}

Przyznaję, że podoba mi się to podejście.


6
Guid nie jest przypadkowy, nie jest dobrym ziarnem. GUID nie daje gwarancji losowości, daje gwarancję wyjątkowości. stackoverflow.com/questions/2621563/…
Magu

2
Guid jest dobrym nasieniem. Używam tylko liczb z Guid. Wypróbuj metodę dla siebie. Włóż to w długą pętlę i spójrz na wyniki dla siebie.
Proximo,

1
Hmm, według drugiej myśli ... nasiona wcale nie są potrzebne. Aktualizacja odpowiedzi
Proximo,

1
Świetny punkt aktualizacji. Nawet nie pomyślałem, żeby zrobić to pole statyczne, w ten sposób działa znacznie lepiej i jest czystsze.
JCisar,

1
Z tą odpowiedzią są pewne problemy. Przede wszystkim GUID nie jest świetnym źródłem nasion - tylko dlatego, że wygląda losowo, nie znaczy, że jest. To może być wystarczająco dobre dla własnych potrzeb. Po drugie, klasa Random nie jest bezpieczna dla wątków. Musisz utworzyć go raz na wątek.
Hector,

11

Liczby generowane przez wbudowaną Randomklasę (System.Random) generują pseudolosowe liczby.

Jeśli chcesz prawdziwych liczb losowych, najbliższym rozwiązaniem jest „bezpieczny Pseudo losowy generator”, który można wygenerować za pomocą klas kryptograficznych w języku C #, takich jak RNGCryptoServiceProvider.

Mimo to, jeśli nadal potrzebujesz prawdziwych liczb losowych, będziesz musiał użyć zewnętrznego źródła, takiego jak urządzenia odpowiedzialne za rozpad radioaktywny, jako zalążek generatora liczb losowych. Ponieważ z definicji dowolna liczba wygenerowana za pomocą metod czysto algorytmicznych nie może być prawdziwie losowa.


11

utwórz obiekt losowy

Random rand = new Random();

i użyj go

int randomNumber = rand.Next(min, max);

nie musisz inicjować za new Random()każdym razem, gdy potrzebujesz losowej liczby, zainicjuj jedną Losowo, a następnie użyj jej tyle razy, ile potrzebujesz w pętli lub cokolwiek innego


5
new Random()używa bieżących kleszczy jako nasion. Kiedy utworzysz wiele instancji w ciągu tej samej milisekundy (w przeciwieństwie do tyknięcia), otrzymasz taką samą wartość.
Hans Ke ING ing

10
To jest aktywnie złe. DateTime.Now.Millisecond (w przeciwieństwie do DateTime.Now.Ticks) to liczba od 0 do 999. Jeśli tworzysz nową z nich dla każdej liczby losowej, będziesz mieć tylko 1000 możliwości.
Oren Melzer

Co 24 osoby zastanawiały się nad głosowaniem nad odpowiedzią ...?
Enigmativity

10

Zmodyfikowana odpowiedź stąd .

Jeśli masz dostęp do procesora zgodnego z Intel Secure Key, możesz generować prawdziwe losowe liczby i ciągi znaków za pomocą tych bibliotek: https://github.com/JebteK/RdRand i https://www.rdrand.com/

Wystarczy pobrać najnowszą wersję stąd , dołącz Jebtek.RdRand i dodaj dla niej instrukcję using. Następnie wszystko, co musisz zrobić, to:

// 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();

Jeśli nie masz zgodnego procesora do wykonania kodu, skorzystaj z usług RESTful na stronie rdrand.com. Z biblioteką otoki RdRandom zawartą w projekcie, wystarczy to zrobić (otrzymasz 1000 darmowych połączeń podczas rejestracji):

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

7

Użyłem poniższego kodu, aby mieć losową liczbę (niezalecane):

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

4

Chociaż jest to w porządku:

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

Chcesz kontrolować limit (min. I maks. Mumbers) przez większość czasu. Musisz więc określić, gdzie zaczyna się i kończy losowa liczba.

Next()Sposób dwa parametry, wartości minimalne i maksymalne.

Więc jeśli chcę, aby mój losowy numer wynosił między 5 a 15, po prostu bym to zrobił

int randomNumber = random.Next(5, 16)

4

Z tej klasy korzystam. Działa jakRandomNumber.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);
    }
}

Twoja klasa GenerateRandom nigdy nie zwróci liczby 666, tylko 665. Jest to powszechne nieporozumienie (cecha) wartości Random.Next max.
Gordon Bell,

3

Chciałem pokazać, co się dzieje, gdy za każdym razem używany jest nowy generator losowy. Załóżmy, że masz dwie metody lub dwie klasy, z których każda wymaga losowej liczby. I naiwnie kodujesz je w następujący sposób:

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

Myślisz, że dostaniesz dwa różne identyfikatory? NIE

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

Rozwiązaniem jest zawsze stosowanie pojedynczego statycznego generatora losowego. Lubię to:

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

Jak zatem bezpiecznie wybrać ziarno?
ja72

Cóż, po pierwsze, jeśli obiekty są tworzone nawet w odstępie 10 ms, generowane liczby losowe są różne w domyślnym ziarnie. Po drugie, możesz zebrać dowolne losowe dane środowiskowe lub przetworzone, które masz w pobliżu, aby uzyskać ziarno. Potem jest kompromis między tym, czy potrzebujesz jednej długiej sekwencji liczb, która najprawdopodobniej zacznie się powtarzać, czy wielu strumieni, nawet jeśli dwa strumienie będą identyczne. A jeśli martwisz się bezpieczeństwem, RNGCryptoServiceProvideri tak lepiej zadzwonić.
Millie Smith,

Fajnie byłoby mieć układ losowy z małym źródłem promieniowania radioaktywnego z cząstkami alfa i detektorem (jak działa detektor dymu) w celu losowego przydzielania liczb na podstawie rozpadu radioaktywnego (co jest bardzo losowe).
ja72

3

W przypadku silnych losowych nasion zawsze używam CryptoRNG, a nie 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
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);

1
Chociaż ten kod może odpowiedzieć na pytanie, lepiej wyjaśnić, jak rozwiązać problem i podać kod jako przykład lub odniesienie. Odpowiedzi zawierające tylko kod mogą być mylące i pozbawione kontekstu.
Robert Columbia,

3

Tak jak notatka do wykorzystania w przyszłości.

Jeśli używasz platformy .NET Core, wiele przypadkowych wystąpień nie jest tak niebezpiecznych, jak wcześniej. Wiem, że to pytanie pochodzi z 2010 roku, ale ponieważ jest ono stare, ale ma pewną atrakcję, myślę, że dobrze jest udokumentować zmianę.

Możesz odnieść się do pytania, które zadałem:

Czy Microsoft zmienił domyślny domyślny seed?

Zasadniczo zmienili domyślny materiał siewny z Environment.TickCountna Guid.NewGuid().GetHashCode(), więc jeśli utworzysz 2 instancje Losowo, nie będą wyświetlać tych samych liczb.

Różnice między plikami z .NET Framework / .NET Core (2.0.0+) można zobaczyć tutaj: https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d

Nie jest tak bezpieczny jak RNGCryptoServiceProvider, ale przynajmniej nie da ci dziwnych rezultatów.


To jest już nieaktualne. Nastąpił znaczny sprzeciw wobec używania prowadnic. Kod jest teraz Interop.GetRandomBytes((byte*)&result, sizeof(int));.
Enigmativity

2

Liczby obliczone przez komputer w procesie deterministycznym nie mogą z definicji być losowe.

Jeśli chcesz prawdziwych liczb losowych, losowość pochodzi z hałasu atmosferycznego lub rozpadu radioaktywnego.

Możesz spróbować na przykład RANDOM.ORG (zmniejsza wydajność)


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

Umieść dowolne wartości w drugim nawiasie, upewnij się, że ustawiłeś nazwę, pisząc prop i podwójną tabulator, aby wygenerować kod


1
Podpora i podwójna zakładka?
DCShannon,

Dlaczego prop i podwójna zakładka ? Czy mówisz, że bez tego skrótu klawiaturowego, który jest skrótem od właściwości, twój kod nie będzie działał?
Sнаđошƒаӽ

2

Jeśli chcesz, aby CSRNG generował losowe liczby od min. Do maks., Jest to dla Ciebie. Zainicjuje Randomklasy za pomocą bezpiecznych losowych nasion.

    class SecureRandom : Random
    {
        public static byte[] GetBytes(ulong length)
        {
            RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider();
            byte[] bytes = new byte[length];
            RNG.GetBytes(bytes);
            RNG.Dispose();
            return bytes;
        }
        public SecureRandom() : base(BitConverter.ToInt32(GetBytes(4), 0))
        {

        }
        public int GetRandomInt(int min, int max)
        {
            int treashold = max - min;
            if(treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if (treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (Next() % treashold);
        }
        public static int GetRandomIntStatic(int min, int max)
        {
            int treashold = max - min;
            if (treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if(treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (BitConverter.ToInt32(GetBytes(4), 0) % treashold);
        }
    }

1

Niestety, OP rzeczywiście wymaga intwartości losowej , ale dla prostego celu dzielenia się wiedzą, jeśli chcesz mieć BigIntegerwartość losową , możesz użyć następującej instrukcji:

BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));

0

Zakładam, że chcesz równomiernie rozłożonego generatora liczb losowych, jak poniżej. Losowa liczba w większości języków programowania, w tym C # i C ++, nie jest poprawnie tasowana przed użyciem. Oznacza to, że będziesz otrzymywać tę samą liczbę w kółko, co nie jest tak naprawdę losowe. Aby uniknąć ciągłego rysowania tej samej liczby, potrzebujesz ziarna. Zazwyczaj kleszcze w czasie są odpowiednie do tego zadania. Pamiętaj, że będziesz otrzymywał ten sam numer w kółko, jeśli używasz tego samego ziarna za każdym razem. Staraj się więc zawsze używać różnych nasion. Czas jest dobrym źródłem dla nasion, ponieważ zawsze się odradzają.

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

jeśli szukasz generatora liczb losowych do rozkładu normalnego, możesz użyć transformacji Boxa-Mullera. Sprawdź odpowiedź yoyoyoyosef w Losowym pytaniu zmiennym gaussowskim. Ponieważ chcesz liczbę całkowitą, musisz rzucić podwójną wartość na liczbę całkowitą na końcu.

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)

Losowe zmienne gaussowskie


0

Najprostszym sposobem jest prawdopodobnie tylko Random.range(1, 3)To wygenerowałoby liczbę od 1 do 2.


-1

Możesz spróbować z losową wartością nasion, używając poniżej:

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

string randomDigits = rnd.Next();

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

Dzięki @ MikaelDúiBolinder za obejrzenie tego fragmentu
Rejwanul Reja

-2

Dlaczego nie użyć int randomNumber = Random.Range(start_range, end_range)?


Właściwie int randomNumber = Random.Range (zakres_początkowy, zakres_końcowy + 1)
Gordon Bell

3
Czy istnieje Random.Range ()? Nie mogłem tego znaleźć w dokumentacji MSDN.
Phillip Ngan,

Nie mogłem również znaleźć Random.Range () w dokumentacji MSDN
user2455111,

-2

Używaj wielokrotnie jednej instancji Losowo

// Somewhat better code...
Random rng = new Random();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(GenerateDigit(rng));
}
...
static int GenerateDigit(Random rng)
{
    // Assume there'd be more logic here really
    return rng.Next(10);
}

W tym artykule wyjaśniono, dlaczego losowość powoduje tak wiele problemów i jak je rozwiązać. http://csharpindepth.com/Articles/Chapter12/Random.aspx


Randomnie jest klasą bezpieczną dla wątków. Jeśli utworzysz pojedyncze wystąpienie, powinieneś ograniczyć do niego dostęp za mechanizmem blokującym.
Brad M

-2

Wypróbuj te proste kroki, aby utworzyć losowe liczby:

Utwórz funkcję:

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

Użyj powyższej funkcji w miejscu, w którym chcesz użyć liczb losowych. Załóżmy, że chcesz go użyć w polu tekstowym.

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

0 to min, a 999 to max. Możesz zmienić wartości na cokolwiek chcesz.



1
liczba losowa (0, 999) nigdy nie zwróci 999. Wartość maksymalna nie jest wliczona. Jest to powszechne nieporozumienie (funkcja) wartości losowej. Następna wartość maksymalna.
Gordon Bell,

-2

Zawsze mam metody generujące liczby losowe, które pomagają w różnych celach. Mam nadzieję, że to też może ci pomóc:

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

    public string RandomString(int size, bool lowerCase)  
    {  
        var builder = new StringBuilder();  
        var 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();  
    }  
}

-3

Szybkie i łatwe do wstawienia, użyj poniżej kodu:

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

// for example unique name
strName += "_" + new Random().Next(100, 999);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.