Вопрос

Как я могу сгенерировать случайные значения 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 (ГСЧ, предусмотренный в System.Security пространство имен), которое может использоваться почти идентично.

Другие советы

Использование Random.NextBytes() и BitConverter.ToInt64 / 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. (Ответ Гуффы показывает, как это сделать с три призывает к Random.Next() хотя.)

Вот, пожалуйста, здесь используется услуги crytpo (не Случайный класс), который (теоретически) является лучшим RNG, чем Случайный класс.Вы могли бы легко сделать это расширением Random или создать свой собственный класс Random, где 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) и улонг (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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top