2010-12-10 40 views

Répondre

16

Vous pouvez utiliser mon GpRandomGen. Il implémente l'algorithme de Marsaglia/Zaman/James, est extrêmement rapide et supposément très aléatoire. Publié en tant que freeware.

+0

Cela ressemble à un générateur de nombres aléatoires complet bien que je préférerais une solution utilisant des fonctions Delphi natives. L'instruction "ceci est le générateur de nombres aléatoires le plus connu" en haut du fichier semble un peu trop sûre d'elle :-) – blerontin

+0

Peut-être était-ce le meilleur en 2002. Je n'ai aucune idée de l'état de l'art en génération aléatoire aujourd'hui. – gabr

+3

GpRandomGen 'is' natif Delphi. Il ne s'appuie pas sur COM, .NET, ASM, etc. Il contient des références aux articles de recherche publiés originaux, l'attribution à l'implémentation C originale, etc. Que voulez-vous de plus? –

4

Vous pouvez générer 64 bits aléatoires et interpréter le résultat sous forme d'entier. (63 bits si vous travaillez avec des entiers signés et souhaitez que le résultat soit non négatif.) Vous pouvez également prendre deux entiers aléatoires dans la plage 0..2^31-1, plus deux bits aléatoires supplémentaires, et les concaténer pour obtenir un nombre entier de 64 bits aléatoire.

EDIT: J'étais curieux de connaître les propriétés statistiques des nombres pseudo-aléatoires générés par concaténer composants pseudo-aléatoires et a constaté que (apparemment), cette approche pourrait selon ne pas fonctionner correctement sur votre générateur pseudo-aléatoire (bien sûr pour génération de nombres aléatoires réels, à partir du bruit atmosphérique, la concaténation de bits aléatoires n'est pas un problème). Pour une utilisation récréative, la perte de diverses propriétés statistiques peut être acceptable, mais pour une utilisation plus sérieuse, vous pourriez avoir besoin d'un générateur pseudo-aléatoire personnalisé comme suggéré par @gabr. Voici une question connexe: Best method of generating a number with 256 random bits?

4

Pour répondre à ma propre question, je suis venu avec le code suivant:

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; 

Je ne sais pas si cela est une solution valable ou crée toujours le même numéro de suivi X + 1 après un nombre de résultat donné X.

+0

Cela dépend de l'utilisation que vous en faites. Cela peut être suffisant pour une simple source de hasard dans un jeu ou une simulation.Si cela concerne tout ce qui concerne le chiffrement, évitez les solutions personnalisées et ad hoc. Chaque programmeur a finalement l'idée de combiner des sources aléatoires pour créer de grands nombres aléatoires. C'est une très mauvaise idée en général. – Ferruccio

+0

Il s'agit de créer des noms de fichiers uniques. Ne doit pas être crypté. – blerontin

+0

@Ferruccio: Par intérêt, quel est le problème avec la suggestion blerontins? Comment peut-il être exploité? Si j'avais besoin d'un nombre aléatoire de 64 bits et que j'avais seulement un générateur 32 bits, je ne ferais que concaténer et je crois que c'était sûr. Pourquoi n'est-ce pas? –

10

Génère deux randoms de 32 bits et les joint ensemble.

EDIT

similaires à @ réponse de Andreas J'aime la mise en œuvre suivante (équivalent):

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. Pourquoi le rendre plus compliqué que nécessaire? (Blerotin a dit "C'est pour créer des noms de fichiers uniques.") –

+4

Vous pouvez utiliser Int64Rec déclaré dans SysUtils casting Résultat, pas besoin de déclarer une autre structure: Int64Rec (Résultat) .Hi: = Random32; Int64Rec (résultat) .Lo: = Random32; –

+0

@Idsandon, oui ce serait probablement encore mieux! –

3

simple:

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

Random32 est votre 32 bits préféré non signé nombre entier fonction aléatoire.

+0

Pourquoi la manipulation de pointeur laide quand il ya une façon plus propre de travailler sur les octets constituant une valeur de 64 bits? Laissez le compilateur calculer les décalages! :) –

+0

@Idsandon: Le code ci-dessus capture le plus exactement la façon dont je * pense * sur le problème. –

+0

Et le vote bas obligatoire, il est venu ... –

3

Créez un GUID (par exemple, CoCreateGuid) et copiez-le dans Int64.

+0

Ou utilisez une fonction de hachage crypto sur un GUID. :-) –