توليد قيم عشوائية في C#
-
21-08-2019 - |
سؤال
كيف يمكن توليد عشوائية Int64 و UInt64 القيم باستخدام Random
الدرجة في C# ؟
المحلول
هذا ينبغي أن تفعل خدعة.(انها امتداد طريقة حتى أن كنت يمكن أن نسميها كما يمكنك الاتصال العادي Next
أو NextDouble
طرق على Random
كائن).
public static Int64 NextInt64(this Random rnd)
{
var buffer = new byte[sizeof(Int64)];
rnd.NextBytes(buffer);
return BitConverter.ToInt64(buffer, 0);
}
مجرد استبدال Int64
مع UInt64
في كل مكان إذا كنت تريد غير صحيحة بدلا من ذلك يجب عليك أن تعمل بشكل جيد.
ملاحظة: لأنه لا السياق قدمت فيما يتعلق بالأمن أو المطلوب عشوائية من الأرقام التي تم إنشاؤها (في الواقع OP ذكر على وجه التحديد Random
الطبقة), بلدي على سبيل المثال ببساطة يتعامل مع Random
الدرجة التي هو الحل المفضل عند العشوائية (غالبا ما قدرت المعلومات الكون) ليست قضية.كمسألة من الفائدة راجع الأجوبة الأخرى التي تذكر RNGCryptoServiceProvider
(RNG المقدمة في System.Security
مساحة الاسم) ، والتي يمكن استخدامها مماثل تقريبا.
نصائح أخرى
استخدم Random.NextBytes()
و <لأ href = "http://msdn.microsoft.com/en-us/library/system.bitconverter.toint64.aspx" يختلط = "نوفولو noreferrer"> BitConverter.ToInt64
/ <لأ href = "http://msdn.microsoft كوم / EN-US / مكتبة / system.bitconverter.touint64.aspx "يختلط =" نوفولو noreferrer "> BitConverter.ToUInt64
.
// Assume rng refers to an instance of System.Random
byte[] bytes = new byte[8];
rng.NextBytes(bytes);
long int64 = BitConverter.ToInt64(bytes, 0);
ulong uint64 = BitConverter.ToUInt64(bytes, 0);
لاحظ أن استخدام Random.Next()
مرتين، وتحويل قيمة واحدة ثم أورينج / مضيفا لا يعمل. Random.Next()
تنتج سوى الأعداد الصحيحة غير السالبة، أي أنها تولد 31 بت، وليس 32، وذلك نتيجة لمكالمتين لا تنتج سوى 62 بت عشوائية بدلا من 64 بت لتغطية مجموعة كاملة من Int64
/ UInt64
. ( Guffa في الإجابة يظهر كيفية القيام بذلك مع ثلاثة م> يدعو إلى Random.Next()
بالرغم من ذلك.)
تفضل, هذا يستخدم crytpo الخدمات (لا الطبقة عشوائية), الذي هو (من الناحية النظرية) أفضل RNG ثم الطبقة عشوائية.يمكنك بسهولة جعل هذا امتداد عشوائي أو جعل الخاصة بك عشوائية الطبقة حيث RNGCryptoServiceProvider هي فئة مستوى الكائن.
using System.Security.Cryptography;
public static Int64 NextInt64()
{
var bytes = new byte[sizeof(Int64)];
RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
Gen.GetBytes(bytes);
return BitConverter.ToInt64(bytes , 0);
}
ويمكنك استخدام تحول قليلا لتشكيل رقم عشوائي 64 بت من أرقام عشوائية 31 بت، ولكن لديك لاستخدام ثلاثة أرقام 31 بت للحصول على ما يكفي من بت:
long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();
وأنا دائما استخدام هذا للحصول على البذور بلدي العشوائي (التدقيق إزالة الخطأ الإيجاز):
m_randomURL = "https://www.random.org/cgi-bin/randnum?num=1&min=1&max=1000000000";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_randomURL);
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
Random rand = new Random(Convert.ToInt32(stIn.ReadToEnd()));
وrandom.org يستخدم الضجيج في الغلاف الجوي لتوليد العشوائية، ويستخدم على ما يبدو لاليانصيب وكذا.
وأنت لا تقول كيف كنت تنوي استخدام هذه الأرقام العشوائية ... نضع في اعتبارنا أن القيم التي يتم إرجاعها بواسطة عشوائية م> ليست "آمنة التشفير" وأنها لا ينبغي أن تستخدم ل أشياء تتعلق بأسرار (كبيرة) أو (الكثير من) المال.
هل يمكن إنشاء byte
مجموعة، وملء مع عشوائي البيانات ومن ثم تحويله إلى long
(وInt64
) و <أ href ل = "http://msdn.microsoft.com/en-us/library/t98873t4.aspx" يختلط = "نوفولو noreferrer"> ULONG (وUInt64
).
byte[] buffer = new byte[sizeof(Int64)];
Random random = new Random();
random.NextBytes(buffer);
long signed = BitConverter.ToInt64(buffer, 0);
random.NextBytes(buffer);
long unsigned = BitConverter.ToUInt64(buffer, 0);
والجواب الآخر مع RNGCryptoServiceProvider
بدلا من Random
. هنا يمكنك ان ترى كيفية إزالة MSB وبالتالي فإن النتيجة هي دائما إيجابية.
public static Int64 NextInt64()
{
var buffer = new byte[8];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);