2011-10-27 28 views
8

Estoy buscando una forma de generar números aleatorios grandes del orden de 2^64 en C ... (100000000 - 999999999), para usar en un algoritmo de cifrado de clave pública (como p yq).Cómo generar números aleatorios grandes C

No deseo generar un número más pequeño que 2^64 (es decir, más pequeño que 100000000).

¿Hay algo que pueda ayudarme a hacer esto?

+7

2^64 es mucho mayor que 999999999. –

Respuesta

11

random() devuelve una longitud que en un sistema de 64 bits debería ser de 64 bits. Si usted está en un sistema de 32 bits que podría hacer lo siguiente:

#include <inttypes.h> 

uint64_t num; 

/* add code to seed random number generator */ 

num = rand(); 
num = (num << 32) | rand(); 

// enforce limits of value between 100000000 and 999999999 
num = (num % (999999999 - 100000000)) + 100000000; 

alternativa en un sistema NIX se podía leer/dev/random en su memoria intermedia:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <inttypes.h> 

int fd; 
uint64_t num; 
if ((fd = open("/dev/random", O_RDONLY) == -1) 
{ 
    /* handle error */ 
}; 
read(fd, &num, 8); 
close(fd); 

// enforce limits of value between 100000000 and 999999999 
num = (num % (999999999 - 100000000)) + 100000000; 

Un

+5

'rand()' está limitado por 'RAND_MAX' que no es necesario' 2^32'. Y, todavía necesitas algo para pasar a 'srand()'. La funcionalidad '/ dev/random' también está disponible en [otras plataformas] (http://en.wikipedia.org/wiki//dev/random). –

+0

Esto no garantiza que se cumpla el requisito "No deseo generar un número inferior a ... 100000000". –

+0

Agregue la línea 'num = (num% (999999999 - 100000000)) + 100000000;' para generar un número aleatorio del límite inferior de 100000000 y el límite superior de 999999999. –

7

usted está buscando un PRNG criptográfica resistencia, como openssl/rand: http://www.openssl.org/docs/crypto/rand.html

+1

O [BCryptGenRandom] (http://msdn.microsoft.com/en-us/library/aa375458%28v=VS.85%29.aspx) en Windows Vista y versiones posteriores. –

+1

+1: usando 'rand()' para esto es un agujero de seguridad (prediciendo que la salida de 'rand()' no es terriblemente desafiante) –

3

se puede hacer una gran cantidad L de números más pequeños (por ejemplo A & B). Por ejemplo, con algo como L = (2^ n)*A + B donde^indica exponenciación y n es un entero constante (por ejemplo, 32). A continuación, codifica 1<<n (desplazamiento a la izquierda en modo bit) para la operación power-of 2.

Para que pueda crear un gran número aleatorio de números aleatorios más pequeños.

+0

¿qué significan las letras 'L, n, A, y b'? podrías explicar por favor? – Ameen

+0

Suponiendo que los números más pequeños 'u32' están uniformemente distribuidos, es un número combinado' u64 = (u32 << 32) | u32' también? – this

+0

@this. Supongo que sí, pero deberías preguntarle a un matemático. –

9

Se puede combinar dos enteros aleatorios de 4 bytes para producir un 8 bytes uno:

#include <stdint.h> 
... 
uint64_t random = 
    (((uint64_t) rand() << 0) & 0x00000000FFFFFFFFull) | 
    (((uint64_t) rand() << 32) & 0xFFFFFFFF00000000ull); 

Desde rand vuelve int, y sizeof(int) >= 4 en casi cualquier plataforma moderna, este código debería funcionar. Agregué el << 0 para hacer el intento más explícito.

El enmascaramiento con 0x00000000FFFFFFFF y 0xFFFFFFFF00000000 es para evitar la superposición de los bits en los dos números en el caso sizeof(int) > 4.

EDITAR

Desde @Banthar comentó que RAND_MAX no es necesariamente 2^32, y creo que se garantiza que sea al menos 2^16, puede combinar cuatro números de 2 bytes sólo para estar seguro:

uint64_t random = 
    (((uint64_t) rand() << 0) & 0x000000000000FFFFull) | 
    (((uint64_t) rand() << 16) & 0x00000000FFFF0000ull) | 
    (((uint64_t) rand() << 32) & 0x0000FFFF00000000ull) | 
    (((uint64_t) rand() << 48) & 0xFFFF000000000000ull); 
+3

Si usa '^' para combinar los números en lugar de '|', no necesita preocuparse por el enmascaramiento. – caf

3

Sé que probablemente obtenga b____slapped por OliCharlesworth, pero use rand() con una escala y desplazamiento. Está en stdlib.h Para cubrir todo el rango, debe agregarlo a otro rand más pequeño() para completar los espacios en el mapeo.

-1

O, puede usar dos generadores de números aleatorios con semillas INDEPENDIENTES y juntar los números de salida como se sugiere. Eso depende de si desea un número de 64 bits de un RNG con un período en el rango de 2^64. Simplemente no use la llamada predeterminada que depende de la hora, ya que obtendrá semillas idénticas para cada generador. De la manera correcta, simplemente no sé ...

Cuestiones relacionadas