Bagaimana cara menghasilkan integer acak dalam C #?
1922
The Random
kelas 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 Random
instance 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.
rnd
sebagaistatic
dan / atau mengaturnya sekali saja saat menginisialisasi kode.Random
...Random
luar 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 .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?
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.
Sekarang izinkan saya membuat pernyataan penting: -
* "Random" kelas menghasilkan hanya nomor acak PSEUDO dan untuk menghasilkan nomor acak SECURE kita perlu menggunakan kelas "RNGCryptoServiceProvider".
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 digunakanGuid.NewGuid().GetHashCode()
.Sementara
RNGCryptoServiceProvider
kelas 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.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.
sumber
RandomNumberGenerator.Create()
alih-alih memanggil konstruktorRNGCryptoServiceProvider
karena tidak tersedia di semua platform.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.
sumber
Random
objek 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.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:
Jadi jangan gunakan kode ini untuk menghasilkan serangkaian angka acak.
sumber
new Random()
dalam satu lingkaran adalah poin penting.sumber
Saya ingin menambahkan versi yang aman secara kriptografis:
Kelas RNGCryptoServiceProvider ( MSDN atau dotnetperls )
Ini mengimplementasikan IDisposable.
sumber
Anda bisa menggunakan metode StaticRandom Jon Skeet di dalam perpustakaan kelas MiscUtil yang ia buat untuk nomor pseudo-acak.
sumber
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.
Pembaruan : Pembibitan tidak diperlukan jika Anda membuat instance kelas Acak satu kali. Jadi akan lebih baik untuk membuat kelas statis dan memanggil metode itu.
Maka Anda dapat menggunakan kelas statis seperti itu ..
Saya akui saya lebih suka pendekatan ini.
sumber
Angka-angka yang dihasilkan oleh
Random
kelas 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.
sumber
buat objek acak
dan gunakan itu
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 punsumber
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.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:
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):
sumber
Saya menggunakan kode di bawah ini untuk memiliki nomor acak (tidak disarankan):
sumber
Meskipun tidak apa-apa:
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
sumber
Ini kelas yang saya gunakan. Bekerja seperti
RandomNumber.GenerateRandom(1, 666)
sumber
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:
Apakah Anda pikir Anda akan mendapatkan dua ID yang berbeda? NGGAK
Solusinya adalah selalu menggunakan generator acak statis tunggal. Seperti ini:
sumber
RNGCryptoServiceProvider
adalah panggilan yang lebih baik.Untuk seed acak yang kuat, saya selalu menggunakan CryptoRNG dan bukan Time.
sumber
sumber
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.TickCount
menjadiGuid.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.
sumber
Interop.GetRandomBytes((byte*)&result, sizeof(int));
.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)
sumber
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
sumber
Jika Anda ingin CSRNG menghasilkan angka acak antara min dan maks, ini untuk Anda. Ini akan menginisialisasi
Random
kelas dengan benih acak aman.sumber
Maaf, OP memang membutuhkan
int
nilai acak , tetapi untuk tujuan sederhana berbagi pengetahuan jika Anda menginginkanBigInteger
nilai acak, Anda dapat menggunakan pernyataan berikut:sumber
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.
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.
Variabel Gaussian Acak
sumber
Cara termudah mungkin hanya
Random.range(1, 3)
Ini akan menghasilkan angka antara 1 dan 2.sumber
Anda dapat mencoba dengan nilai seed acak menggunakan di bawah ini:
sumber
Kenapa tidak digunakan
int randomNumber = Random.Range(start_range, end_range)
?sumber
Gunakan satu contoh Acak berulang kali
Artikel ini membahas mengapa keacakan menyebabkan begitu banyak masalah, dan bagaimana cara mengatasinya. http://csharpindepth.com/Articles/Chapter12/Random.aspx
sumber
Random
bukan kelas thread aman. Jika Anda membuat satu instance, Anda harus membatasi aksesnya di belakang mekanisme penguncian.Coba langkah-langkah sederhana ini untuk membuat angka acak:
Buat fungsi:
Gunakan fungsi di atas di lokasi di mana Anda ingin menggunakan angka acak. Misalkan Anda ingin menggunakannya dalam kotak teks.
0 minimum dan 999 maks. Anda dapat mengubah nilai menjadi apa pun yang Anda inginkan.
sumber
Saya selalu memiliki metode yang menghasilkan angka acak yang membantu untuk berbagai keperluan. Saya harap ini dapat membantu Anda juga:
sumber
Cepat dan mudah untuk inline, gunakan kode di bawah ini:
sumber