2010-12-10 28 views

Respuesta

16

Puedes usar mi GpRandomGen. Implementa el algoritmo Marsaglia/Zaman/James, es extremadamente rápido y supuestamente muy aleatorio. Lanzado como un programa gratuito.

+0

Parece un generador de números aleatorios con todas las funciones, aunque yo preferiría una solución con funciones nativas de Delphi. La frase "este es el generador de números aleatorios más conocido" en la parte superior del archivo parece demasiado seguro de sí mismo :-) – blerontin

+0

Tal vez fue el mejor en 2002. No tengo idea de cuál es el estado del arte en la generación aleatoria hoy en día. – gabr

+3

GpRandomGen 'is' nativo Delphi. No depende de COM, .NET, ASM, etc. Contiene referencias a los artículos de investigación originales publicados, atribución a la implementación original de C, etc. ¿Qué más quieres? –

4

Puede generar 64 bits aleatorios e interpretar el resultado como un entero. (63 bits si está trabajando con enteros con signo y quiere que el resultado no sea negativo.) Equivalentemente, puede tomar dos enteros aleatorios en el rango 0..2^31-1, más dos bits aleatorios adicionales, y concatenarlos para obtener un entero aleatorio de 64 bits.

EDIT: Tenía curiosidad acerca de las propiedades estadísticas de números pseudo-aleatorios generados mediante la concatenación de componentes pseudo-aleatorios y se encontró que (aparentemente) este enfoque podría no funcionar bien en función de su generador pseudo-aleatorio (por supuesto para la verdadera generación de números aleatorios, a partir del ruido atmosférico, la concatenación de bits aleatorios no es un problema). Para uso recreativo, la pérdida de varias propiedades estadísticas podría ser aceptable, pero para un uso más serio podría terminar necesitando un generador pseudoaleatorio personalizado como sugirió @gabr. Aquí hay una pregunta relacionada: Best method of generating a number with 256 random bits?

4

para responder a mi propia pregunta me ocurrió con el siguiente código:

function GetRandomInt64() : int64; 
begin 
    Int64Rec(result).Words[0] := Random(High(Word)); 
    Int64Rec(result).Words[1] := Random(High(Word)); 
    Int64Rec(result).Words[2] := Random(High(Word)); 
    Int64Rec(result).Words[3] := Random(High(Word)); 
end; 

No estoy seguro si esto es una solución válida o que siempre va a crear el mismo número de seguimiento X + 1 después de un número de resultado determinado X.

+0

Depende de para qué lo use. Esto puede ser adecuado para una fuente simple de aleatoriedad en un juego o simulación.Si se trata de algo relacionado con el cifrado, evite las soluciones personalizadas y ad-hoc. A cada programador finalmente se le ocurre la idea de combinar fuentes aleatorias para crear números aleatorios grandes. Es una muy mala idea en general. – Ferruccio

+0

Es para crear nombres de archivo únicos. No necesita ser seguro de cifrado. – blerontin

+0

@Ferruccio: Fuera de interés, ¿qué pasa con la sugerencia de blerontins? ¿Cómo puede ser explotado? Si necesitaba un número aleatorio de 64 bits y solo tenía un generador de 32 bits, probablemente solo concatenaría y creería que era seguro. ¿Por qué no? –

10

Genera dos randoms de 32 bits y los empalma.

EDITAR

similares a @ respuesta de Andreas me gusta lo siguiente (equivalente) aplicación:

function Random64: UInt64; 
var 
    Overlay: packed record 
    a, b: UInt32; 
    end absolute Result; 
begin 
    Assert(SizeOf(Overlay)=SizeOf(Result)); 
    Overlay.a := Random32; 
    Overlay.b := Random32; 
end; 
+0

+1. ¿Por qué hacerlo más complicado de lo necesario? (Blerotin dijo "Es para crear nombres de archivos únicos"). –

+4

Puede usar Int64Rec declarado en SysUtils casting Result, no es necesario declarar otra estructura: Int64Rec (Result) .Hi: = Random32; Int64Rec (Resultado) .Lo: = Random32; –

+0

@Indsandon, sí, ¡eso probablemente sería aún mejor! –

3

simple:

function Random64: UInt64; 
begin 
    PCardinal(@result)^ := Random32; 
    PCardinal(cardinal(@result) + 4)^ := Random32; 
end; 

donde Random32 es su favorito de 32 bits sin signo función de número aleatorio entero.

+0

¿Por qué la manipulación del puntero feo cuando hay una manera más limpia de trabajar en los bytes que componen un valor de 64 bits? ¡Deja que el compilador calcule las compensaciones! :) –

+0

@Indsandon: El código anterior captura de forma más precisa la forma en que * pienso * sobre el problema. –

+0

Y el voto abajo obligatorio, llegó ... –

3

Cree un GUID (por ejemplo, CoCreateGuid) y vuélvalo a Int64.

+0

O usemos alguna función hash crypto en un GUID. :-) –

Cuestiones relacionadas