Bagaimana cara menghasilkan nomor int acak?

1922

Bagaimana cara menghasilkan integer acak dalam C #?

Rella
sumber

Jawaban:

2503

The Randomkelas digunakan untuk membuat nomor acak. (Tentu saja semu-acak.).

Contoh:

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

Jika Anda ingin membuat lebih dari satu angka acak, Anda harus menyimpan Randominstance dan menggunakannya kembali. Jika Anda membuat instance baru terlalu dekat dalam waktu, mereka akan menghasilkan seri angka acak yang sama dengan generator acak diunggulkan dari jam sistem.

Guffa
sumber
184
Hanya catatan untuk pengguna Unity C #, Anda harus menentukan "System.Random ()" karena Unity memiliki "UnityEngine.Random ()" yang bentrok (perhatikan bahwa "UnityEngine.Random ()" tidak memiliki kemampuan untuk menghasilkan acak angka). Karena kesatuan tidak selalu mengimpor Sistem secara default, ini dapat menyebabkan kebingungan.
Joehot200
2
Untuk menggunakannya kembali, Anda dapat mendeklarasikan rndsebagai staticdan / atau mengaturnya sekali saja saat menginisialisasi kode.
Junior Mayhé
4
@ YuniorM: Ya, Anda dapat membuat statis untuk menggunakannya kembali, tetapi Anda harus berhati-hati agar Anda tidak mengaksesnya dari beberapa utas karena tidak aman untuk ulir (seperti biasanya untuk kelas mana pun yang tidak secara khusus membuat ulir aman ).
Guffa
9
Saya pikir akan bermanfaat untuk menambahkan penafian bahwa ini tidak aman secara kriptografi, karena ini adalah pertanyaan yang populer, kalau-kalau ada orang yang secara buta mencoba melakukan kriptografi dengan Random...
Daniel García Rubio
1
Jawaban yang sangat bagus. Ada beberapa "peningkatan" yang bagus di Randomluar sana untuk membuat keacakan Anda lebih kuat: ericlippert.com/2019/02/04/fixing-random-part-2 dan codeblog.jonskeet.uk/2009/11/04/revisiting -Randomness .
Jesse C. Slicer
280

Pertanyaannya terlihat sangat sederhana tetapi jawabannya agak rumit. Jika Anda melihat hampir semua orang menyarankan untuk menggunakan kelas Acak dan beberapa menyarankan untuk menggunakan kelas kripto RNG. Tetapi kemudian kapan harus memilih apa.

Untuk itu kita perlu terlebih dahulu memahami istilah KEANDALAN dan filosofi di baliknya.

Saya mendorong Anda untuk menonton video ini yang mendalami filosofi RANDOMNESS menggunakan C # https://www.youtube.com/watch?v=tCYxc-2-3fY

Hal pertama marilah kita memahami filosofi KEANDALAN. Ketika kami memberi tahu seseorang untuk memilih antara MERAH, HIJAU dan KUNING apa yang terjadi secara internal. Apa yang membuat seseorang memilih MERAH atau KUNING atau HIJAU?

c # Acak

Beberapa pemikiran awal masuk ke pikiran orang yang memutuskan pilihannya, itu bisa menjadi warna favorit, warna keberuntungan dan sebagainya. Dengan kata lain beberapa pemicu awal yang kita sebut dalam RANDOM sebagai SEED. SEED ini adalah titik awal, pemicu yang menghasutnya untuk memilih nilai RANDOM.

Sekarang jika SEED mudah ditebak maka angka-angka acak semacam itu disebut sebagai PSEUDO dan ketika sebuah seed sulit ditebak, angka-angka acak itu disebut angka acak SECURED .

Misalnya seseorang memilih warna tergantung pada kombinasi cuaca dan suara maka akan sulit untuk menebak benih awal.

c # Acak

Sekarang izinkan saya membuat pernyataan penting: -

* "Random" kelas menghasilkan hanya nomor acak PSEUDO dan untuk menghasilkan nomor acak SECURE kita perlu menggunakan kelas "RNGCryptoServiceProvider".

c # Acak

Kelas acak mengambil nilai seed dari jam CPU Anda yang sangat mudah diprediksi. Jadi dengan kata lain kelas ACAK dari C # menghasilkan angka acak semu, di bawah ini adalah kode yang sama.

** Catatan: ** .NET Core 2.0.0+menggunakan seed berbeda pada konstruktor tanpa parameter: alih-alih jam CPU yang digunakan Guid.NewGuid().GetHashCode().

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

Sementara RNGCryptoServiceProviderkelas menggunakan entropi OS untuk menghasilkan benih. Entropi OS adalah nilai acak yang dihasilkan menggunakan suara, klik mouse, dan pengaturan waktu keyboard, suhu termal, dll. Di bawah ini adalah kode yang sama.

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

Untuk memahami entropi OS, lihat video ini dari pukul 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY di mana logika entropi OS dijelaskan. Jadi dengan kata-kata sederhana RNG Crypto menghasilkan angka acak AMAN.

Shivprasad Koirala
sumber
9
bukankah seharusnya byte Anda [5] hanya [4] karena ToInt32 hanya mem-parsing 4 byte?
Bernhard
6
Selalu membantu untuk mengetahui di mana kelas-kelas ini tinggal. System.Security.Cryptography
Elton
1
Disarankan untuk menggunakan RandomNumberGenerator.Create()alih-alih memanggil konstruktor RNGCryptoServiceProviderkarena tidak tersedia di semua platform.
dzitkowskik
Saya hanya ingin memastikan bahwa generasi acak semu SecureRandom IS.
Nùménor
Karena meningkatnya keacakan benih, apakah boleh membuat objek RNGCryptoServiceProvider yang baru setiap kali saya perlu membuat nomor acak, atau apakah masih lebih baik untuk membuat satu objek RNGCryptoServiceProvider dan menggunakannya kembali setiap kali saya perlu membuat nomor acak, seperti harus dilakukan dengan kelas acak?
user2150989
231

Setiap kali Anda melakukan Acak baru () diinisialisasi. Ini berarti bahwa dalam loop ketat Anda mendapatkan nilai yang sama banyak kali. Anda harus menyimpan satu instance Acak dan terus menggunakan Next pada instance yang sama.

//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);
    }
}
Pankaj Mishra
sumber
3
Bukankah ini yang dikatakan @Guffa dalam jawabannya 6 bulan lalu? "Jika Anda membuat instance baru terlalu dekat dalam waktu, mereka akan menghasilkan seri angka acak yang sama"
Chris
3
@ Chris- Itu benar apa yang kamu katakan. Dalam hal ini saya telah menyediakan implementasi itu. Saya pikir ini cara yang baik untuk melakukannya. Itu bekerja lebih baik.
Pankaj Mishra
22
Ini adalah implementasi yang menyinkronkan kode untuk digunakan dari utas seval. Itu bagus untuk aplikasi multi-utas, tetapi buang-buang waktu untuk satu aplikasi utas tunggal.
Guffa
@SeanWorle: Pertama, saya mencobanya dengan pendekatan dari Guffa. Kemudian saya mencoba menyimpan Randomobjek yang sama . Pada kedua kasus saya mendapat nomor acak yang sama. Dengan pendekatan dari Pankaj itu tidak terjadi. Mungkin ini acak , tapi saya ragu sekarang. Saya meminta nomor acak di detik yang sama dari utas berbeda.
menguji
1
@ pengujian: Saya setuju bahwa metode Pankaj adalah yang benar untuk digunakan. Apa yang saya katakan adalah dapat disederhanakan menjadi ini: // Berfungsi untuk mendapatkan angka acak private static readonly Random getrandom = new Random (); public static int GetRandomNumber (int min, int max) {lock (getrandom) {// menyinkronkan return getrandom.Next (min, maks); }}
Sean Worle
92

Waspadalah yang new Random()diunggulkan di cap waktu saat ini.

Jika Anda ingin menghasilkan hanya satu nomor, Anda dapat menggunakan:

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

Untuk informasi lebih lanjut, lihat kelas Acak , namun harap dicatat:

Namun, karena jam memiliki resolusi hingga, menggunakan konstruktor tanpa parameter untuk membuat objek Acak yang berbeda secara berurutan membuat generator angka acak yang menghasilkan urutan identik dari nomor acak

Jadi jangan gunakan kode ini untuk menghasilkan serangkaian angka acak.

Fyodor Soikin
sumber
41
-1: Benih default didasarkan pada waktu; lakukan ini dalam satu lingkaran dan Anda akan mendapatkan hasil yang sangat tidak acak. Anda harus membuat satu generator dan menggunakannya untuk semua nomor Anda, bukan generator yang terpisah setiap kali.
Bevan
21
Hei, itu tidak adil. Pertanyaannya adalah bagaimana menghasilkan nomor int acak. Tidak ada loop atau seri yang disebutkan.
Fyodor Soikin
26
Ok, poin yang adil. Dicabut. Padahal, saya masih berpikir bahwa tidak menggunakan new Random()dalam satu lingkaran adalah poin penting.
Bevan
Bagi mereka yang menemukan ini di masa depan, itu seharusnya sudah jelas sekarang, tapi saya hanya akan menunjukkannya; jawabannya diperbarui dengan titik ini, untuk tidak menggunakan ini dalam satu lingkaran untuk beberapa nilai.
vapcguy
49
Random r = new Random();
int n = r.Next();
Joren
sumber
30

Saya ingin menambahkan versi yang aman secara kriptografis:

Kelas RNGCryptoServiceProvider ( MSDN atau dotnetperls )

Ini mengimplementasikan IDisposable.

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

Anda bisa menggunakan metode StaticRandom Jon Skeet di dalam perpustakaan kelas MiscUtil yang ia buat untuk nomor pseudo-acak.

using MiscUtil;
...

for (int i = 0; i < 100; 
    Console.WriteLine(StaticRandom.Next());
mbcrump
sumber
31
Saya baru saja melihat kode sumber, dan fungsi ini menggunakan mesin nomor acak yang sama persis, yang "disertakan" dalam C #, tetapi memastikan bahwa "seed" / "objek ibu" yang sama digunakan untuk semua panggilan. (Saya minta maaf karena saya tidak tahu terminologi C #. Tetapi poin saya adalah bahwa fungsi ini tidak membuat angka acak yang lebih baik daripada fungsi standar.)
Andreas Rejbrand
5
Tidak mungkin sesuatu menjadi 'benar-benar acak' karena selalu ada beberapa faktor pembatas atau prasangka termasuk yang melekat oleh keberadaannya. Apakah Anda tidak mendengarkan guru di kelas sains? ;-)
Phill Healey
Katakanlah, menurutnya ini 'benar-benar acak'
The Mitra Boy
Tautan rusak sekarang. Inilah sebabnya mengapa Anda memasukkan informasi yang Anda temukan dalam jawaban Anda.
vapcguy
13

Saya sudah mencoba semua solusi ini kecuali jawaban COBOL ... lol

Tidak ada solusi yang cukup baik. Saya membutuhkan tebasan dalam loop cepat untuk int dan saya mendapatkan banyak nilai duplikat bahkan dalam rentang yang sangat luas. Setelah puas dengan hasil acak yang terlalu lama, saya memutuskan untuk akhirnya mengatasi masalah ini untuk selamanya.

Ini semua tentang benih.

Saya membuat bilangan bulat acak dengan mem-parsing non-digit dari Guid, lalu saya menggunakannya untuk membuat instance kelas acak saya.

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

Pembaruan : Pembibitan tidak diperlukan jika Anda membuat instance kelas Acak satu kali. Jadi akan lebih baik untuk membuat kelas statis dan memanggil metode itu.

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

Maka Anda dapat menggunakan kelas statis seperti itu ..

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

Saya akui saya lebih suka pendekatan ini.

Pd bulan depan
sumber
6
Panduan tidak acak, ini bukan benih yang baik. GUID tidak membuat jaminan tentang keacakan, itu membuat jaminan seputar keunikan. stackoverflow.com/questions/2621563/…
Magu
2
Guid adalah benih yang baik. Saya hanya menggunakan nomor dalam Panduan. Cobalah metodenya sendiri. Taruh dalam long for loop dan lihat hasilnya sendiri.
Pd bulan depan
1
Hmm, setelah dipikir-pikir .. benih tidak diperlukan sama sekali. Memperbarui jawaban
Proximo
1
Poin bagus pada pembaruan. Saya bahkan tidak berpikir untuk menjadikannya bidang statis, cara ini bekerja lebih baik dan lebih bersih.
JCisar
1
Ada beberapa masalah dengan jawaban ini. Pertama-tama, GUID bukan sumber benih yang bagus - hanya karena terlihat acak, bukan berarti itu benar. Ini mungkin cukup baik untuk kebutuhan pribadi Anda. Kedua, kelas Random tidak aman utas. Anda harus instantiate sekali per utas.
Hector
11

Angka-angka yang dihasilkan oleh Randomkelas inbuilt (System.Random) menghasilkan angka acak semu.

Jika Anda menginginkan angka acak yang benar, yang terdekat yang bisa kami dapatkan adalah "secure Pseudo Random Generator" yang dapat dihasilkan dengan menggunakan kelas-kelas Kriptografi dalam C # seperti RNGCryptoServiceProvider.

Meski begitu, jika Anda masih membutuhkan bilangan acak sejati, Anda harus menggunakan sumber eksternal seperti perangkat yang menghitung peluruhan radioaktif sebagai seed untuk generator bilangan acak. Karena, menurut definisi, angka apa pun yang dihasilkan dengan cara algoritmik murni tidak dapat benar-benar acak.

Anshita Arya
sumber
11

buat objek acak

Random rand = new Random();

dan gunakan itu

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

Anda tidak perlu menginisialisasi new Random()setiap kali Anda membutuhkan nomor acak, mulai satu acak lalu gunakan sebanyak yang Anda butuhkan dalam satu lingkaran atau apa pun

Mohamed Selim
sumber
5
new Random()menggunakan kutu saat ini sebagai benih. Ketika Anda instantiate beberapa instance dalam milidetik yang sama (sebagai lawan dari centang), maka Anda akan mendapatkan nilai yang sama dikembalikan.
Hans Ke
10
Ini sangat buruk. DateTime.Now.Millisecond (tidak seperti DateTime.Now.Ticks) adalah angka antara 0 dan 999. Jika Anda membuat yang baru untuk setiap nomor acak, Anda hanya akan memiliki 1000 kemungkinan.
Oren Melzer
Apa yang 24 orang pikirkan dalam memilih suara ini ...?
Enigmativity
10

Jawaban yang dimodifikasi dari sini .

Jika Anda memiliki akses ke CPU yang kompatibel dengan Intel Secure Key, Anda dapat menghasilkan bilangan dan string acak nyata menggunakan perpustakaan ini: https://github.com/JebteK/RdRand dan https://www.rdrand.com/

Cukup unduh versi terbaru dari sini , termasuk Jebtek.RdRand dan tambahkan pernyataan menggunakan untuk itu. Kemudian, yang perlu Anda lakukan adalah ini:

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

Jika Anda tidak memiliki CPU yang kompatibel untuk menjalankan kode, gunakan saja layanan RESTful di rdrand.com. Dengan perpustakaan pembungkus RdRandom termasuk dalam proyek Anda, Anda hanya perlu melakukan ini (Anda mendapatkan 1000 panggilan gratis saat mendaftar):

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

Saya menggunakan kode di bawah ini untuk memiliki nomor acak (tidak disarankan):

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

Meskipun tidak apa-apa:

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

Anda ingin mengontrol batas (min dan max mumbers) sebagian besar waktu. Jadi, Anda perlu menentukan di mana angka acak dimulai dan berakhir.

The Next()Metode menerima dua parameter, min dan max.

Jadi jika saya ingin nomor acak saya antara katakan 5 dan 15, saya akan melakukannya

int randomNumber = random.Next(5, 16)
Ojonugwa Jude Ochalifu
sumber
4

Ini kelas yang saya gunakan. Bekerja sepertiRandomNumber.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);
    }
}
AskethZ
sumber
Kelas GenerateRandom Anda tidak akan pernah mengembalikan angka 666, hanya 665. Ini adalah kesalahpahaman umum (fitur) dari nilai Random.Next maks.
Gordon Bell
3

Saya ingin menunjukkan apa yang terjadi ketika generator acak baru digunakan setiap saat. Misalkan Anda memiliki dua metode atau dua kelas yang masing-masing membutuhkan nomor acak. Dan secara naif Anda mengkodekannya seperti:

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

Apakah Anda pikir Anda akan mendapatkan dua ID yang berbeda? NGGAK

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

Solusinya adalah selalu menggunakan generator acak statis tunggal. Seperti ini:

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; }
}
Ja72
sumber
Bagaimana Anda memilih benih dengan aman?
ja72
Nah, pertama, jika objek Anda dibuat terpisah 10 ms, angka acak yang dihasilkan berbeda dengan seed default. Kedua, Anda dapat menumbuk data lingkungan atau proses acak apa pun yang Anda miliki untuk mendapatkan seed. Lalu ada kompromi apakah Anda ingin satu urutan angka yang kemungkinan besar akan mulai berulang sendiri, atau beberapa aliran bahkan jika dua aliran akhirnya identik. Dan jika Anda khawatir tentang keamanan, itu RNGCryptoServiceProvideradalah panggilan yang lebih baik.
Millie Smith
Akan lebih baik untuk memiliki chip pengacak dengan sumber radioaktif partikel alfa kecil dan detektor (cara detektor asap bekerja) untuk mengacak angka berdasarkan peluruhan radioaktif (yang sangat acak).
ja72
3

Untuk seed acak yang kuat, saya selalu menggunakan CryptoRNG dan bukan 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);
        }
    }
}
Davit Tvildiani
sumber
3
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
Mengubah rute
sumber
1
Meskipun kode ini dapat menjawab pertanyaan, lebih baik untuk menjelaskan bagaimana menyelesaikan masalah dan memberikan kode sebagai contoh atau referensi. Jawaban khusus kode bisa membingungkan dan kurang konteks.
Robert Columbia
3

Sama seperti catatan untuk referensi di masa mendatang.

Jika Anda menggunakan .NET Core, beberapa instance Acak tidak berbahaya seperti sebelumnya. Saya menyadari bahwa pertanyaan ini berasal dari 2010, tetapi karena pertanyaan ini sudah lama tetapi memiliki beberapa daya tarik, saya pikir itu hal yang baik untuk mendokumentasikan perubahan.

Anda dapat merujuk ke pertanyaan yang saya buat beberapa waktu lalu:

Apakah Microsoft mengubah seed default Acak?

Pada dasarnya, mereka telah mengubah seed default dari Environment.TickCountmenjadi Guid.NewGuid().GetHashCode(), jadi jika Anda membuat 2 instance Random, ia tidak akan menampilkan angka yang sama.

Anda dapat melihat perbedaan file dari .NET Framework / .NET Core (2.0.0+) di sini: https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d

Ini tidak seaman RNGCryptoServiceProvider, tapi setidaknya itu tidak akan memberi Anda hasil yang aneh.

Lucca Ferri
sumber
Ini sudah ketinggalan zaman. Ada reaksi yang cukup besar terhadap penggunaan Panduan. Kode sekarang Interop.GetRandomBytes((byte*)&result, sizeof(int));.
Enigmativity
2

Angka yang dihitung oleh komputer melalui proses deterministik, tidak dapat, menurut definisi, menjadi acak.

Jika Anda menginginkan angka acak asli, keacakan berasal dari kebisingan atmosfer atau peluruhan radioaktif.

Anda dapat mencoba misalnya RANDOM.ORG (ini mengurangi kinerja)

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

Masukkan nilai apa pun yang Anda inginkan dalam tanda kurung kedua pastikan Anda telah menetapkan nama dengan menulis prop dan double tab untuk menghasilkan kode

pengguna3773367
sumber
1
Prop dan double tab?
DCShannon
Mengapa mengganjal dan menggandakan tab ? Apakah Anda mengatakan tanpa pintasan keyboard itu, yang merupakan kependekan dari properti, kode Anda tidak akan berfungsi?
Sнаđошƒаӽ
2

Jika Anda ingin CSRNG menghasilkan angka acak antara min dan maks, ini untuk Anda. Ini akan menginisialisasi Randomkelas dengan benih acak aman.

    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);
        }
    }
Jessie Lesbian
sumber
1

Maaf, OP memang membutuhkan intnilai acak , tetapi untuk tujuan sederhana berbagi pengetahuan jika Anda menginginkan BigIntegernilai acak, Anda dapat menggunakan pernyataan berikut:

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

Saya akan berasumsi bahwa Anda ingin generator nomor acak terdistribusi secara merata seperti di bawah ini. Nomor acak di sebagian besar bahasa pemrograman termasuk C # dan C ++ tidak dikocok dengan benar sebelum menggunakannya. Ini berarti Anda akan mendapatkan nomor yang sama berulang-ulang, yang sebenarnya tidak acak. Untuk menghindari menggambar nomor yang sama berulang-ulang, Anda perlu seed. Biasanya, ticks in time tidak masalah untuk tugas ini. Ingatlah bahwa Anda akan mendapatkan nomor yang sama berulang kali jika Anda menggunakan benih yang sama setiap waktu. Jadi cobalah selalu menggunakan benih yang bervariasi. Waktu adalah sumber yang baik untuk benih karena mereka selalu mengejar.

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

jika Anda mencari generator angka acak untuk distribusi normal, Anda mungkin menggunakan transformasi Box-Muller. Periksa jawabannya oleh yoyoyoyosef di Random Gaussian Variable Question. Karena Anda ingin integer, Anda harus memberikan nilai ganda ke integer pada akhirnya.

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)

Variabel Gaussian Acak

auto9817
sumber
0

Cara termudah mungkin hanya Random.range(1, 3)Ini akan menghasilkan angka antara 1 dan 2.


sumber
-1

Anda dapat mencoba dengan nilai seed acak menggunakan di bawah ini:

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

string randomDigits = rnd.Next();

var requestNumber = $"SD-{randomDigits}";
Rejwanul Reja
sumber
Terima kasih @ MikaelDúiBolinder untuk melihat snipet ini
Rejwanul Reja
-2

Kenapa tidak digunakan int randomNumber = Random.Range(start_range, end_range)?

Recomer
sumber
Sebenarnya int randomNumber = Random.Range (start_range, end_range + 1)
Gordon Bell
3
Apakah Random.Range () ada? Saya tidak dapat menemukannya di dokumentasi MSDN.
Phillip Ngan
Saya tidak dapat menemukan Random.Range () dalam dokumentasi MSDN juga
user2455111
-2

Gunakan satu contoh Acak berulang kali

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

Artikel ini membahas mengapa keacakan menyebabkan begitu banyak masalah, dan bagaimana cara mengatasinya. http://csharpindepth.com/Articles/Chapter12/Random.aspx

Ankit Agarwal
sumber
Randombukan kelas thread aman. Jika Anda membuat satu instance, Anda harus membatasi aksesnya di belakang mekanisme penguncian.
Brad M
-2

Coba langkah-langkah sederhana ini untuk membuat angka acak:

Buat fungsi:

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

Gunakan fungsi di atas di lokasi di mana Anda ingin menggunakan angka acak. Misalkan Anda ingin menggunakannya dalam kotak teks.

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

0 minimum dan 999 maks. Anda dapat mengubah nilai menjadi apa pun yang Anda inginkan.

Hani Mehdi
sumber
Ini akan mengembalikan nomor yang sama ketika dipanggil beberapa kali bersama-sama karena menggunakan waktu Sistem sebagai seed ...
MOnsDaR
1
randomnumber (0, 999) tidak akan pernah mengembalikan 999. Nilai Max tidak termasuk. Ini adalah kesalahpahaman umum (fitur) dari nilai maks Random.Next.
Gordon Bell
-2

Saya selalu memiliki metode yang menghasilkan angka acak yang membantu untuk berbagai keperluan. Saya harap ini dapat membantu Anda juga:

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();  
    }  
}
PatsonLeaner
sumber
-3

Cepat dan mudah untuk inline, gunakan kode di bawah ini:

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

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