repetir repetidos rango para numeros numero letras generar decimales con cifras algoritmo aleatorios aleatorio aleatorias c# random

c# - repetidos - Generador de números aleatorios solo generando un número aleatorio



generar numeros aleatorios no repetidos c# (9)

Tengo la siguiente función:

//Function to get random number public static int RandomNumber(int min, int max) { Random random = new Random(); return random.Next(min, max); }

Como lo llamo

byte[] mac = new byte[6]; for (int x = 0; x < 6; ++x) mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

Si paso ese bucle con el depurador durante el tiempo de ejecución obtengo diferentes valores (que es lo que quiero). Sin embargo, si coloco un punto de interrupción dos líneas debajo de ese código, todos los miembros de la matriz "mac" tienen el mismo valor.

¿Por qué sucede eso?


1) Como dijo Marc Gravell, intente usar UN generador aleatorio. Siempre es bueno agregar esto al constructor: System.Environment.TickCount.

2) Un consejo. Digamos que desea crear 100 objetos y suponga que cada uno de ellos debería tener su propio generador aleatorio (útil si calcula las CARGAS de números aleatorios en un período de tiempo muy corto). Si hiciera esto en un bucle (generación de 100 objetos), podría hacerlo así (para garantizar la aleatoriedad total):

int inMyRandSeed; for(int i=0;i<100;i++) { inMyRandSeed = System.Environment.TickCount + i; . . . myNewObject = new MyNewObject(inMyRandSeed); . . . } // Usage: Random m_rndGen = new Random(inMyRandSeed);

Aclamaciones.


Cada vez que ejecutes

Random random = new Random (15);

No importa si lo ejecutas millones de veces, siempre usarás la misma semilla.

Si utiliza

Random random = new Random ();

Usted obtiene una secuencia de números aleatorios diferente, si un hacker adivina la semilla y su algoritmo está relacionado con la seguridad de su sistema, su algoritmo está roto. Yo te ejecuto mult. En este constructor, la semilla se especifica mediante el reloj del sistema y, si se crean varias instancias en un período de tiempo muy corto (milisegundos), es posible que tengan la misma semilla.

Si necesitas números aleatorios seguros debes usar la clase.

System.Security.Cryptography.RNGCryptoServiceProvider

public static int Next(int min, int max) { if(min >= max) { throw new ArgumentException("Min value is greater or equals than Max value."); } byte[] intBytes = new byte[4]; using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { rng.GetNonZeroBytes(intBytes); } return min + Math.Abs(BitConverter.ToInt32(intBytes, 0)) % (max - min + 1); }

Uso:

int randomNumber = Next(1,100);


Cada vez que haces un new Random() se inicializa usando el reloj. Esto significa que en un circuito cerrado obtienes el mismo valor muchas veces. Debe mantener una sola instancia Random y seguir usando Next en la misma instancia.

//Function to get a random number private static readonly Random random = new Random(); private static readonly object syncLock = new object(); public static int RandomNumber(int min, int max) { lock(syncLock) { // synchronize return random.Next(min, max); } }

Editar (ver comentarios): ¿por qué necesitamos un lock aquí?

Básicamente, Next va a cambiar el estado interno de la instancia Random . Si lo hacemos al mismo tiempo desde varios subprocesos, podría argumentar que "acabamos de hacer que el resultado sea aún más aleatorio", pero lo que realmente estamos haciendo es potencialmente romper la implementación interna, y también podríamos comenzar a obtener los mismos números. de diferentes hilos, lo que podría ser un problema y podría no serlo. Sin embargo, la garantía de lo que sucede internamente es el problema más grande; Random no garantiza la seguridad de los hilos. Por lo tanto, hay dos enfoques válidos:

  • sincronizar para que no accedamos al mismo tiempo desde diferentes hilos
  • usar diferentes instancias Random por hilo

Cualquiera puede estar bien; pero excluir una sola instancia de varias personas que llaman al mismo tiempo es solo pedir problemas.

La lock logra el primero (y más simple) de estos enfoques; Sin embargo, otro enfoque podría ser:

private static readonly ThreadLocal<Random> appRandom = new ThreadLocal<Random>(() => new Random());

esto es por hilo, por lo que no es necesario sincronizar.


Hay muchas soluciones, aquí una: si solo quiere un número, borre las letras y el método recibe un resultado aleatorio y la longitud.

public String GenerateRandom(Random oRandom, int iLongitudPin) { String sCharacters = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"; int iLength = sCharacters.Length; char cCharacter; int iLongitudNuevaCadena = iLongitudPin; String sRandomResult = ""; for (int i = 0; i < iLongitudNuevaCadena; i++) { cCharacter = sCharacters[oRandom.Next(iLength)]; sRandomResult += cCharacter.ToString(); } return (sRandomResult); }


La solución de Mark puede ser bastante costosa ya que necesita sincronizarse cada vez.

Podemos evitar la necesidad de sincronización utilizando el patrón de almacenamiento específico de subproceso:

public class RandomNumber : IRandomNumber { private static readonly Random Global = new Random(); [ThreadStatic] private static Random _local; public int Next(int max) { var localBuffer = _local; if (localBuffer == null) { int seed; lock(Global) seed = Global.Next(); localBuffer = new Random(seed); _local = localBuffer; } return localBuffer.Next(max); } }

Mida las dos implementaciones y verá una diferencia significativa.


Mi respuesta desde here :

Solo reiterando la solución correcta :

namespace mySpace { public static class Util { private static rnd = new Random(); public static int GetRandom() { return rnd.Next(); } } }

Así que puedes llamar:

var i = Util.GetRandom();

todo a través de.

Si necesita estrictamente un verdadero método estático sin estado para generar números aleatorios, puede confiar en un Guid .

public static class Util { public static int GetRandom() { return Guid.NewGuid().GetHashCode(); } }

Va a ser un poquito más lento, pero puede ser mucho más aleatorio que Random.Next , al menos desde mi experiencia.

Pero no

new Random(Guid.NewGuid().GetHashCode()).Next();

La creación innecesaria de objetos lo hará más lento, especialmente en un bucle.

Y nunca

new Random().Next();

No solo es más lento (dentro de un bucle), su aleatoriedad es ... bueno, no es realmente bueno para mí ...


Para facilitar la reutilización a lo largo de su aplicación, una clase estática puede ayudar.

public static class StaticRandom { private static int seed; private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random> (() => new Random(Interlocked.Increment(ref seed))); static StaticRandom() { seed = Environment.TickCount; } public static Random Instance { get { return threadLocal.Value; } } }

Puede usar y luego usar instancia aleatoria estática con código como

StaticRandom.Instance.Next(1, 100);


Preferiría usar la siguiente clase para generar números aleatorios:

byte[] random; System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider(); prov.GetBytes(random);


acaba de declarar la variable de clase aleatoria de esta manera:

Random r = new Random(); // ... Get three random numbers. // Here you''ll get numbers from 5 to 9 Console.WriteLine(r.Next(5, 10));

Si desea obtener un número aleatorio diferente cada vez de su lista, use

r.Next(StartPoint,EndPoint) //Here end point will not be included

Cada vez declarando Random r = new Random() una vez.