2010-11-23 13 views
21

De lo que he entendido arc4random() genera mucho mejores que al azar los números de rand(), sin embargo no he visto una forma de sembrar, y me gustaría igual usando srand(). ¿Hay alguna manera?arc4random siembra() en el SDK iPhone

+1

¿Encontraste una manera de sembrar al final? – Ali

Respuesta

22

No es para lo que arc4random está diseñado. A medida que la documentación indica:

La función arc4random() proporciona una alta calidad de 32 bits pseudo-aleatorio número muy rápidamente. arc4random() se siembra regularmente desde el subsistema de números aleatorios fuertes del núcleo descrito en random(4).

Dado que se vuelve a sembrar a sí mismo desde una fuente de entropía de todos modos, no gana nada sembrándolo manualmente, y de hecho, dicho método no existe.

+1

Aceptaré esta respuesta por ahora. Parece que no hay una manera fácil de sembrar manualmente arc4random. Hay una mención aleatoria (4) de sembrar manualmente el dispositivo aleatorio, pero no tengo claro cómo podría hacerlo. – andrewz

+4

@andrews: lo único que * puedes * hacer es insertar cosas manualmente en el grupo de entropía, desde el cual 'arc4random' se resembrará. Sin embargo, eso está en desuso y todavía no tiene control sobre la siembra.Esto básicamente significa que no se puede tratar 'arc4random' como un PRNG que, cuando se siembra con el mismo vector de inicialización, produce la misma secuencia exacta. 'java.security.SecureRandom' tiene el mismo" problema "y es similarmente por diseño. Si necesita un control detallado de su PRNG, implemente MT-19937, no es largo y el código fuente de C está disponible. – Joey

+4

En realidad, hay algo que ganar al sembrar manualmente un generador de números aleatorios. Cuando se utiliza junto con recursos generados por procedimientos, proporciona un medio para reproducir el mismo recurso varias veces con solo su número de identificación de identificación. Esto permite que las construcciones aleatorias, por lo demás complejas, se compartan con otros usuarios, pero sin la necesidad de grandes transferencias de archivos de datos. Por supuesto, esto supone que tu generador pseudoaleatorio siempre produce la misma secuencia para la misma semilla. – Ash

1

En realidad, no necesita sembrar ... se siembra solo en la primera llamada. Consulte la documentación llamando al

man arc4random 

en su carcasa. La línea relevante, en DESCRIPTION, es:

There is no need to call arc4random_stir() before using arc4random(), 
since arc4random() automatically initializes itself. 
+30

QUIERO sembrarlo. ¿Hay alguna manera? – andrewz

+0

@andrewz ¡Tiene el mismo problema aquí! : D Gran cosa ... –

+0

@sam tendrás que cambiar tu respuesta de "En realidad no necesitas sembrar ..." a "No puedes sembrarla". Debe saber mejor y comprender el requisito o la necesidad de crear SRG. –

6

En realidad se puede hacer esto en iOS 9.

import GameKit 

let source = GKARC4RandomSource(seed: "hello world".data(using: .utf8)!) 
source.dropValues(1024) 
source.nextInt() // <-- your number 

De acuerdo con los documentos:

Las fuentes aleatorias basadas en Arc4 tienen secuencias iniciales repetibles. Si se utiliza para ofuscación, debe eliminar N valores desde el inicio, donde N debe ser cualquier número mayor que 768 para garantizar que la secuencia inicial se vacíe.

Así que, mientras utiliza los mismos datos de semillas (obviamente sin utilizar ! en el código de producción) y el mismo número de valores perdidos, obtendrá los mismos resultados.

3

En Swift 3 Estoy usando srand48() y drand48() cuando necesito un valor sembrado. Hice esta función que parece funcionar lo suficientemente bien para mis necesidades:

func seeded_rand(seed:Int, min:Double, max:Double) -> Int 
{ 
    srand48(seed) 
    return Int(round(drand48() * (max-min)) + min) 
} 
+0

Perfecto, ¡gracias! Esto debería ser aceptado como respuesta. – Zapko