Respostas:
A Random
classe é usada para criar números aleatórios. (Pseudo-aleatório, é claro.).
Exemplo:
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
Se você deseja criar mais de um número aleatório, mantenha a Random
instância e reutilize-a. Se você criar novas instâncias muito próximas no tempo, elas produzirão a mesma série de números aleatórios que o gerador aleatório é semeado no relógio do sistema.
rnd
como static
e / ou defini-lo apenas uma vez ao inicializar o código.
Random
...
Random
por aí para tornar sua aleatoriedade mais robusta: ericlippert.com/2019/02/04/fixing-random-part-2 e codeblog.jonskeet.uk/2009/11/04/revisiting aleatoriedade .
A pergunta parece muito simples, mas a resposta é um pouco complicada. Se você vir quase todo mundo sugeriu o uso da classe Random e alguns sugeriram o uso da classe de criptografia RNG. Mas então quando escolher o que.
Para isso, precisamos primeiro entender o termo ALEATÓRIA e a filosofia por trás dele.
Recomendamos que você assista a este vídeo, que é aprofundado na filosofia da ALEATÓRIA usando C # https://www.youtube.com/watch?v=tCYxc-2-3fY
Primeira coisa, vamos entender a filosofia da ALEATÓRIA. Quando dizemos a uma pessoa para escolher entre VERMELHO, VERDE e AMARELO, o que acontece internamente. O que faz uma pessoa escolher VERMELHO, AMARELO ou VERDE?
Algum pensamento inicial entra na mente das pessoas que decide sua escolha; pode ser a cor favorita, a cor da sorte e assim por diante. Em outras palavras, algum gatilho inicial que denominamos RANDOM como SEED. Esse SEED é o ponto de partida, o gatilho que o instiga a selecionar o valor RANDOM.
Agora, se um SEED é fácil de adivinhar, esse tipo de número aleatório é denominado PSEUDO e quando é difícil adivinhar que esses números aleatórios são denominados números aleatórios SECURED .
Por exemplo, uma pessoa escolhe a cor, dependendo da combinação de clima e som, seria difícil adivinhar a semente inicial.
Agora deixe-me fazer uma declaração importante: -
* A classe "Random" gera apenas o número aleatório PSEUDO e, para gerar o número aleatório SECURE, precisamos usar a classe "RNGCryptoServiceProvider".
A classe aleatória obtém valores iniciais do relógio da CPU, o que é muito previsível. Portanto, em outras palavras, a classe RANDOM de C # gera números pseudo-aleatórios, abaixo está o código para o mesmo.
** Nota: ** .NET Core 2.0.0+
usa uma semente diferente no construtor sem parâmetros: em vez do relógio da CPU que ele usa Guid.NewGuid().GetHashCode()
.
var random = new Random();
int randomnumber = random.Next()
Enquanto a RNGCryptoServiceProvider
classe usa entropia do SO para gerar sementes. A entropia do SO é um valor aleatório que é gerado usando som, clique do mouse e tempo do teclado, temperatura térmica etc. Abaixo segue o código para o mesmo.
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[5];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
}
Para entender a entropia do SO, assista a este vídeo das 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY, onde é explicada a lógica da entropia do SO. Então, colocando em palavras simples, o RNG Crypto gera números aleatórios SEGUROS.
RandomNumberGenerator.Create()
vez de chamar o construtor, RNGCryptoServiceProvider
pois ele não está disponível em todas as plataformas.
Toda vez que você cria um novo Random (), ele é inicializado. Isso significa que, em um circuito fechado, você obtém o mesmo valor várias vezes. Você deve manter uma única instância aleatória e continuar usando Next na mesma instância.
//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);
}
}
Random
objeto. Nos dois casos, obtive o mesmo número aleatório. Com a abordagem de Pankaj, isso não aconteceu. Talvez isso seja aleatório , mas duvido agora. Estou consultando o número aleatório no mesmo segundo de diferentes threads.
Cuidado que new Random()
é semeado no carimbo de data / hora atual.
Se você deseja gerar apenas um número, pode usar:
new Random().Next( int.MinValue, int.MaxValue )
Para obter mais informações, consulte a classe Random , embora observe:
No entanto, como o relógio possui resolução finita, o uso do construtor sem parâmetros para criar diferentes objetos Random em sucessão próxima cria geradores de números aleatórios que produzem sequências idênticas de números aleatórios
Portanto, não use esse código para gerar uma série de números aleatórios.
new Random()
um loop é um ponto importante.
Eu queria adicionar uma versão criptograficamente segura:
Classe RNGCryptoServiceProvider ( MSDN ou dotnetperls )
Implementa IDisposable.
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] randomNumber = new byte[4];//4 for int32
rng.GetBytes(randomNumber);
int value = BitConverter.ToInt32(randomNumber, 0);
}
Você poderia usar o método StaticRandom de Jon Skeet dentro da biblioteca de classes MiscUtil que ele criou para um número pseudo-aleatório.
using MiscUtil;
...
for (int i = 0; i < 100;
Console.WriteLine(StaticRandom.Next());
Eu tentei todas essas soluções, excluindo a resposta COBOL ... lol
Nenhuma dessas soluções foi boa o suficiente. Eu precisava de randoms em um loop rápido para int e estava obtendo toneladas de valores duplicados, mesmo em intervalos muito amplos. Depois de me contentar com resultados aleatórios por tempo demais, decidi finalmente resolver esse problema de uma vez por todas.
É tudo sobre a semente.
Eu crio um número inteiro aleatório analisando os não dígitos de Guid, então eu uso isso para instanciar minha classe Random.
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);
}
Atualização : A propagação não é necessária se você instanciar a classe Random uma vez. Portanto, seria melhor criar uma classe estática e chamar um método disso.
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);
}
}
Então você pode usar a classe estática assim ..
for(var i = 0; i < 1000; i++)
{
int randomNumber = IntUtil.Random(1,100);
Console.WriteLine(randomNumber);
}
Admito que gosto mais dessa abordagem.
Os números gerados pelo embutido Random
classe (System.Random) gera números pseudo-aleatórios.
Se você deseja números aleatórios verdadeiros, o mais próximo que podemos chegar é de "Gerador pseudo-aleatório seguro", que pode ser gerado usando as classes criptográficas em C #, como RNGCryptoServiceProvider
.
Mesmo assim, se você ainda precisar de números aleatórios verdadeiros , precisará usar uma fonte externa, como dispositivos que representam a deterioração radioativa como uma semente para um gerador de números aleatórios. Como, por definição, qualquer número gerado por meios puramente algorítmicos não pode ser verdadeiramente aleatório.
criar um objeto aleatório
Random rand = new Random();
e use
int randomNumber = rand.Next(min, max);
você não precisa inicializar new Random()
toda vez que precisar de um número aleatório, iniciar um aleatório e usá-lo quantas vezes for necessário dentro de um loop ou qualquer outra coisa
new Random()
usa os ticks atuais como semente. Ao instanciar várias instâncias no mesmo milissegundo (em vez de marcar), você receberá o mesmo valor.
Resposta modificada a partir daqui .
Se você tiver acesso a uma CPU compatível com Intel Secure Key, poderá gerar números e sequências aleatórias reais usando estas bibliotecas: https://github.com/JebteK/RdRand e https://www.rdrand.com/
Basta baixar a versão mais recente a partir daqui , incluir Jebtek.RdRand e adicionar uma declaração de uso. Então, tudo que você precisa fazer é o seguinte:
// 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();
Se você não possui uma CPU compatível para executar o código, use os serviços RESTful em rdrand.com. Com a biblioteca de wrapper RdRandom incluída no seu projeto, você precisaria fazer isso (você recebe 1000 chamadas gratuitas ao se inscrever):
string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
Enquanto isso estiver correto:
Random random = new Random();
int randomNumber = random.Next()
Você deseja controlar o limite (números mínimo e máximo) na maioria das vezes. Então, você precisa especificar onde o número aleatório começa e termina.
O Next()
método aceita dois parâmetros, min e max.
Então, se eu quiser que meu número aleatório esteja entre digamos 5 e 15, eu faria
int randomNumber = random.Next(5, 16)
Esta é a classe que eu uso. Funciona comoRandomNumber.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);
}
}
Eu queria demonstrar o que acontece quando um novo gerador aleatório é usado todas as vezes. Suponha que você tenha dois métodos ou duas classes, cada um exigindo um número aleatório. E ingenuamente você os codifica como:
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; }
}
Você acha que receberá dois IDs diferentes? NÃO
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
}
}
A solução é sempre usar um único gerador aleatório estático. Como isso:
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; }
}
RNGCryptoServiceProvider
é melhor ligar de qualquer maneira.
Para sementes aleatórias fortes, eu sempre uso CryptoRNG e não 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);
}
}
}
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
Apenas como uma nota para referência futura.
Se você estiver usando o .NET Core, várias instâncias aleatórias não serão tão perigosas quanto antes. Estou ciente de que essa pergunta é de 2010, mas como essa pergunta é antiga, mas tem alguma atração, acho bom documentar a mudança.
Você pode se referir a esta pergunta que fiz há algum tempo:
A Microsoft alterou a semente padrão aleatória?
Basicamente, eles mudaram a semente padrão de Environment.TickCount
paraGuid.NewGuid().GetHashCode()
, portanto, se você criar 2 instâncias do Random, ele não exibirá os mesmos números.
Você pode ver as diferenças de arquivo do .NET Framework / .NET Core (2.0.0+) aqui: https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d
Não é tão seguro quanto RNGCryptoServiceProvider, mas pelo menos não oferece resultados estranhos.
Interop.GetRandomBytes((byte*)&result, sizeof(int));
.
Os números calculados por um computador através de um processo determinístico não podem, por definição, ser aleatórios.
Se você deseja números aleatórios genuínos, a aleatoriedade provém do ruído atmosférico ou da deterioração radioativa.
Você pode tentar, por exemplo, RANDOM.ORG (reduz o desempenho)
Random rand = new Random();
int name = rand.Next()
Coloque os valores desejados nos segundos parênteses, verifique se você definiu um nome escrevendo prop e tab dupla para gerar o código
Se você deseja que um CSRNG gere números aleatórios entre um mínimo e um máximo, isso é para você. Inicializará as Random
classes com sementes aleatórias seguras.
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);
}
}
Desculpe, o OP realmente requer um int
valor aleatório , mas com o simples propósito de compartilhar conhecimento, se você deseja um BigInteger
valor aleatório, pode usar a seguinte instrução:
BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));
Assumirei que você deseja um gerador de números aleatórios uniformemente distribuído, como abaixo. O número aleatório na maioria das linguagens de programação, incluindo C # e C ++, não é embaralhado adequadamente antes de ser utilizado. Isso significa que você obterá o mesmo número repetidamente, o que não é realmente aleatório. Para evitar desenhar o mesmo número repetidamente, você precisa de uma semente. Normalmente, os tiques no tempo são aceitáveis para esta tarefa. Lembre-se de que você obterá o mesmo número repetidamente se estiver sempre usando a mesma semente. Portanto, tente usar sempre sementes variadas. O tempo é uma boa fonte de sementes, porque elas sempre mudam.
int GetRandomNumber(int min, int max)
{
Random rand = new Random((int)DateTime.Now.Ticks);
return rand.Next(min, max);
}
se você estiver procurando por gerador de números aleatórios para distribuição normal, poderá usar uma transformação Box-Muller. Verifique a resposta por yoyoyoyosef na pergunta variável aleatória gaussiana. Como você deseja inteiro, você deve converter o valor duplo para inteiro no final.
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)
A maneira mais fácil é provavelmente apenas Random.range(1, 3)
Isso geraria um número entre 1 e 2.
Você pode tentar com o valor aleatório da semente usando abaixo:
var rnd = new Random(11111111); //note: seed value is 11111111
string randomDigits = rnd.Next();
var requestNumber = $"SD-{randomDigits}";
Por que não usar int randomNumber = Random.Range(start_range, end_range)
?
Use uma instância do Random repetidamente
// 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);
}
Este artigo analisa por que a aleatoriedade causa tantos problemas e como resolvê-los. http://csharpindepth.com/Articles/Chapter12/Random.aspx
Random
não é uma classe segura para threads. Se você criar uma única instância, deverá restringir o acesso a ela por trás de um mecanismo de bloqueio.
Tente estas etapas simples para criar números aleatórios:
Criar função:
private int randomnumber(int min, int max)
{
Random rnum = new Random();
return rnum.Next(min, max);
}
Use a função acima em um local onde você deseja usar números aleatórios. Suponha que você queira usá-lo em uma caixa de texto.
textBox1.Text = randomnumber(0, 999).ToString();
0 é mínimo e 999 é máx. Você pode alterar os valores para o que quiser.
Eu sempre tenho métodos que geram números aleatórios que ajudam para vários propósitos. Espero que isso possa ajudá-lo também:
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();
}
}
Rápido e fácil para embutir, use o código a seguir:
new Random().Next(min, max);
// for example unique name
strName += "_" + new Random().Next(100, 999);