visual semilla repetir propiedad para numeros numero hacer generar digitos decimales como algoritmo aleatorios aleatorio c# random

c# - semilla - forma inteligente de generar un número aleatorio único



random en visual basic (20)

Quiero generar una secuencia de números aleatorios únicos en el rango de 00000001 a 99999999.

Entonces, el primero podría ser 00001010, el segundo 40002928, etc.

La manera más fácil es generar un número aleatorio y almacenarlo en la base de datos, y cada vez que lo haga, vuelva a verificar la base de datos si el número ya existe y, de ser así, genere uno nuevo, revíselo nuevamente, etc. Pero eso no se ve bien, podría regenerar un número tal vez 100 veces si la cantidad de elementos generados aumenta.

¿Hay una manera más inteligente?

EDITAR como siempre me olvidé de decir POR QUÉ quería esto, y probablemente hará las cosas más claras y tal vez tenga una alternativa, y es: queremos generar un número de orden para una reserva, así que podríamos simplemente usar 000001, 000002, etc. no queremos darles a los competidores una idea de la cantidad de pedidos que se crean (porque no es un mercado de alto volumen, y no queremos que sepan si estamos en el pedido 30 después de 2 meses o en el pedido 100. Entonces queremos tener un número de orden que sea aleatorio (pero único)


  1. crear y almacenar ind db dos versiones barajadas (SHUFFLE_1 y SHUFFLE_2) del intervalo [0..N), donde N = 10''000;

  2. cada vez que se crea un nuevo pedido, le asigna su id como este:

ORDER_FAKE_INDEX = N * SHUFFLE_1 [ORDER_REAL_INDEX / N] + SHUFFLE_2 [ORDER_REAL_INDEX% N]


¿Qué tal crear un conjunto de todos los números posibles y simplemente aleatorizar el orden? Podrías elegir el siguiente número de la cola.

Cada número aparece solo una vez en el conjunto, y cuando quiere uno nuevo, ya se ha generado, por lo que la sobrecarga es pequeña en el punto en el que quiere uno. Puede hacer esto en la memoria o la base de datos de su elección. Solo necesitará una estrategia de bloqueo sensata para obtener el siguiente número disponible.


Al seguir la línea podemos obtener, por ejemplo, 6 números aleatorios no repetitivos para el rango, por ejemplo, 1 a 100.

var randomNumbers = Enumerable.Range(1, 100) .OrderBy(n => Guid.NewGuid()) .Take(6) .OrderBy(n => n);


Ejecutar un generador congruente lineal una vez para generar cada número puede producir resultados bastante débiles. Ejecutarlo a través de una serie de iteraciones que es relativamente primordial para su base (100,000,000 en este caso) lo mejorará considerablemente. Si antes de informar cada salida del generador, lo ejecuta a través de una o más funciones de permutación adicionales, la salida final seguirá siendo una permutación libre de duplicados de tantos números como desee (hasta 100.000.000), pero si se eligen las funciones adecuadas el resultado puede ser criptográficamente fuerte.




Me gusta la solución de Lazarus, pero si quiere evitar preasignar el espacio para cada número posible, simplemente almacene los números usados ​​en la tabla, pero construya una lista de "números no utilizados" en la memoria agregando todos los números posibles a una colección, luego borrando todos los que están presentes en la base de datos. Luego seleccione uno de los números restantes y úselo, agregándolo a la lista en la base de datos, obviamente.

Pero, como digo, me gusta la solución de Lazaru: creo que es la mejor opción para la mayoría de los escenarios.


Para el tamaño extremadamente limitado de sus números, no puede esperar exclusividad para ningún tipo de generación aleatoria.

Está generando un entero de 32 bits, mientras que para alcanzar la unicidad necesita un número mucho mayor en términos de 128 bits, que es el tamaño que usa el GUID y que, como siempre, será globalmente único.



Podrías colocar tus números en un conjunto. Si el tamaño del conjunto tras generación de sus N números es demasiado pequeño, genere un poco más.

Haz algunas ejecuciones de prueba. ¿Cuántos números tienes que generar en promedio? Trate de encontrar una solución óptima para el intercambio "generar demasiados números" / "verificar con demasiada frecuencia los duplicados". Este óptimo es un número M, de modo que después de generar números M, su conjunto probablemente tendrá N números únicos.

Ah, y M también se puede calcular: si necesita un número adicional (su conjunto contiene N-1), entonces la posibilidad de que un número aleatorio ya esté en el conjunto es (N-1) / R, siendo R el rango . Me estoy volviendo loco aquí, así que tendrás que resolverlo tú mismo (pero este tipo de cosas es lo que hace que la programación sea divertida, ¿no?).


Podrías construir una tabla con todos los números posibles en ella, darle al registro un campo ''usado''.

  1. Seleccione todos los registros que no han sido ''usados''
  2. Elija un número aleatorio (r) entre 1 y el recuento de registros
  3. Tome el número de registro r
  4. Obtenga su ''valor aleatorio'' del registro
  5. Establezca el indicador ''usado'' y actualice el db.

Eso debería ser más eficiente que elegir números aleatorios, consultar la base de datos y repetir hasta que no se encuentre, ya que eso es solo una mendicidad para los últimos valores.


Puede poner una restricción única en la columna que contiene el número aleatorio, luego manejar cualquier voladura de restricción regenerando el número. Creo que esto normalmente indexa la columna también así que esto sería más rápido.

Has etiquetado la pregunta con C #, así que supongo que estás usando C # para generar el número aleatorio. Tal vez piense en hacer que la base de datos genere el número aleatorio en un proceso almacenado y devolverlo.


Puede tratar de dar nombres de usuario de escritura mediante el uso de un número inicial y un número incremental. Comienza en un número (digamos, 12000), luego, para cada cuenta creada, el número sube por el valor incremental.

id = startValue + (totalNumberOfAccounts * inctrementalNumber)

Si incrementalNumber es un valor principal, debería poder recorrer el valor máximo de la cuenta y no presionar otro valor. Esto crea la ilusión de una identificación aleatoria, pero también debe tener muy pocos conflictos. En el caso de un conflicto, puede agregar un número para aumentar cuando hay un conflicto, por lo que el código anterior se convierte. Queremos manejar este caso, ya que, si encontramos un valor de cuenta idéntico, cuando incrementamos, nos encontraremos con otro conflicto cuando incrementemos nuevamente.

id = startValue + (totalNumberOfAccounts * inctrementalNumber) + totalConflicts


Puede usar un Generador congruente lineal (LCG) o un Registro de desplazamiento de realimentación lineal (LFSR). Google o wikipedia para más información.

Ambos pueden, con los parámetros correctos, operar en una base de "ciclo completo" (o "período completo") de modo que generen un "número aleatorio de psuedo" solo una vez en un período único y generen todos los números dentro del rango . Ambos son generadores "débiles", por lo que no es bueno para la citografía, pero tal vez "lo suficientemente bueno" para la aparente aleatoriedad. Puede que tenga que restringir el período para trabajar dentro de su máximo ''decimal'' ya que es necesario tener períodos ''binarios''.

Actualización: Debo añadir que no es necesario precalcular o pre-almacenar valores previos de ninguna manera, solo necesita mantener el valor de inicialización (single int) y calcular ''a pedido'' el siguiente número en el secuencia. Por supuesto, puede guardar una cadena de números precalculados en su base de datos si así lo desea, pero no es necesario.


También vine con el mismo tipo de problema, pero en C #. Finalmente lo resolví. Espero que funcione para ti también.

Supongamos que necesito un número aleatorio entre 0 y algunos MaxValue y que un objeto de tipo aleatorio diga aleatorio.

int n=0; while(n<MaxValue) { int i=0; i=random.Next(n,MaxValue); n++; Write.Console(i.ToString()); }


Tuve que hacer algo como esto antes (crear un número de "apariencia aleatoria" como parte de una URL). Lo que hice fue crear una lista de claves generadas al azar. Cada vez que necesitaba un nuevo número, simplemente seleccionaba aleatoriamente un número de las claves.Count y XOR la ​​clave y el número de secuencia dado, y luego el valor XORed emitido (en la base 62) con el índice de claves (en la base 62). También verifico la salida para asegurarme de que no contenga ninguna palabra. Si simplemente toma la siguiente tecla y tiene un segundo avance. Descifrar el número es igualmente simple (el primer dígito es el índice de la clave a usar, un XOR simple y listo).

Me gusta la respuesta de andora si está generando nuevos números y podría haberlo usado si lo hubiera sabido. Sin embargo, si tuviera que hacer esto de nuevo, simplemente habría usado UUIDs . La mayoría (si no todas) de la plataforma tiene un método para generarlas y la longitud no es un problema para las URL.


Use generadores de números pseudoaleatorios.

Por ejemplo, Generador de números aleatorios congruente lineal

(Si increment yn son coprime, entonces el código generará todos los números de 0 a n-1):

int seed = 1, increment = 3; int n = 10; int x = seed; for(int i = 0; i < n; i++) { x = (x + increment) % n; Console.WriteLine(x); }

Salida: 4 7 0 3 6 9 2 5 8 1

Generadores básicos de números aleatorios

Mersenne Twister


de la manera estúpida: construya una tabla para grabar, almacene todos los números, y ellos, cada vez que los use, y márquelos como "usados"


System.Random rnd = new System.Random(); IEnumerable<int> numbers = Enumerable.Range(0, 99999999).OrderBy(r => rnd.Next());

Esto le da una colección aleatoriamente mezclada de entradas en su rango. A continuación, puede iterar a través de la colección en orden.

Lo mejor de esto es que en realidad no estás creando toda la colección en la memoria.

Consulte los comentarios a continuación: esto generará toda la colección en la memoria cuando itere al primer elemento.


function getShuffledNumbers(count) { var shuffledNumbers = new Array(); var choices = new Array(); for (var i = 0; i<count; i++) { // choose a number between 1 and amount of numbers remaining choices[i] = selectedNumber = Math.ceil(Math.random()*(99999999 - i)); // Now to figure out the number based on this selection, work backwards until // you figure out which choice this number WOULD have been on the first step for (var j = 0; j < i; j++) { if (choices[i - 1 - j] >= selectedNumber) { // This basically says "it was choice number (selectedNumber) on the last step, // but if it''s greater than or equal to this, it must have been choice number // (selectedNumber + 1) on THIS step." selectedNumber++; } } shuffledNumbers[i] = selectedNumber; } return shuffledNumbers; }

Esta es una forma tan rápida como podría pensar y solo utiliza la memoria como lo necesita, sin embargo, si la ejecuta durante todo el proceso utilizará el doble de memoria porque tiene dos matrices, choices y shuffledNumbers .