2010-06-21 7 views
1

Comment puis-je obtenir un nombre aléatoire à partir du texte?texte au nombre aléatoire

function text_to_number($text, $min, $max) 
{ 
    .... 
    mt_rand($min, $max); 
    .... 
    return $random_number; 
} 

$rand1 = text_to_number("text1", 1, 1000); 
$rand2 = text_to_number("text2", 1, 1000); 

Alors que "text1" toujours revenir 476 (par exemple) mt_rand(1, 1000) et "text2" - toujours 241.
Est-il possible?

+3

Si le résultat est déterministe, comment est-ce un nombre aléatoire? –

+0

'mt_rand (1, 1001)' devrait renvoyer un nombre différent pour "text1" que 'mt_rand (1, 1000)' – Qiao

+1

@Qiao Donc votre vraie question semble être comment pouvez-vous graver le RNG en utilisant du texte? –

Répondre

5

Ce que vous voulez faire est d'ensemencer un générateur aléatoire avec une valeur basée sur votre chaîne. Voir, le code

mt_srand(5); 
$value = mt_rand(1, 10); 

sera toujours attribuer la même valeur à $value, peu importe combien de fois vous l'appelez. Mieux encore, tous les autres appels à mt_rand retourneront les mêmes valeurs (différentes les unes des autres) d'une course à l'autre, mais cela ne devrait pas vous intéresser.

Donc, vous devez écrire

function make_seed($text) { 
    //do seed calc 
    return $seed; 
} 

function text_to_number($text, $min, $max) { 
    mt_srand(make_seed($text)); 
    return mt_rand($min, $max); 
} 

Comment calculez-vous des semences à partir du texte est un autre problème. Vous pouvez convertir chaque caractère en nombre entier et les additionner. Vous pouvez calculer CRC32. Vous pouvez faire MD5 et en faire partie. Beaucoup de choix ici. Mais vraiment, pourquoi n'utilisez-vous pas simplement une sorte de CRC ou MD5 directement?

+0

nouveau à ce roi des problèmes, maintenant je le ferai. Mais comme le hasard plus. – Qiao

+1

MD5 semble aléatoire :) Tout comme CRC32. Utilisez SHA512 et personne ne sera en mesure de deviner votre chaîne à partir du nombre que vous avez obtenu. C'est exactement ce que sont les algorithmes de hachage. – vava

+0

"Comment calculez-vous les graines en fonction du texte est un autre problème." Non, c'est la question exacte que l'OP a posée. –

0

Il semble que vous souhaitiez renvoyer un nombre aléatoire compris entre 1 et 1000 avec une clé de chaîne, mais vous souhaitez renvoyer le même "nombre aléatoire" chaque fois que vous obtenez la même clé de chaîne.

Ma solution intuitive était de hacher votre entrée et retourner un int basé sur cela. Cependant, une bien meilleure solution consiste à mettre en cache vos générations:

$cache = array(); 
function text_to_number($text, $min, $max) 
{ 
    if (!isset($cache[$text])) 
     $cache[$text] = array(); 

    if (!isset($cache[$text][$min]) 
     $cache[$text][$min] = array(); 

    if (!isset($cache[$text][$min][$max]) 
     $cache[$text][$min][$max] = mt_rand($min, $max); 

    return $cache[$text][$min][$max]; 
} 

$text1 = "text1"; 
$text2 = "text2"; 

$rand1 = text_to_number($text1, 1, 1000); 
$rand2 = text_to_number($text2, 1, 1000); 
assertEqual($rand1, text_to_number($text1, 1, 1000)); //PSEUDOCODE assert 

Modifier: Mise à jour, vous souhaitez mettre en cache par min/max aussi.

+0

'assertEqual ($ rand1, text_to_number ($ text1, 1, 1000)); // PSEUDOCODE assert' - qu'est-ce que c'est? Où puis-je lire à ce sujet? – Qiao

+0

C'était un pseudo-code (c'est-à-dire pas un code réel) qui démontre simplement que les appels répétés doivent être identiques. N'y faites pas attention. –

+1

Ce "cache" ne resterait actif que pendant l'exécution de ce script. Cela peut ne pas être utile, selon le but. (Aussi, je pense que votre utilisation de globals rend ceci cassé) –

6

Je dirais d'oublier le "aléatoire", il semble que ce que vous voulez vraiment est une forme de hachage. Voici une implémentation simple qui utilise le hachage md5 de la chaîne et utilise le module pour le mettre à l'échelle dans la plage requise.

function text_to_number($text, $min = 0, $max = 1000) 
{ 
    return fmod(hexdec(md5($text)), ($max - $min)) + $min; 
} 
+0

C'était aussi ma première pensée mais vous l'avez mieux exécutée. Ce serait plus agréable que la mise en cache. –

+0

+1 pour le hachage. Yup, cela ressemble à ce qu'il a besoin – Mawg

1

Vous semblez être demander un CRC. Ce type de fonction calcule un hachage court sous la forme d'un nombre (généralement 32 bits) pour une chaîne conçue pour être un moyen rapide et assez fiable de déterminer si deux chaînes sont différentes.

crc32($string) 

Ceci renvoie une valeur entre -2147483648 et 2147483647.

Pour vous assurer qu'il tombe dans 0 à 999, essayez d'utiliser quelque chose comme

abs(crc32($string)) % 1000 

Bien sûr, cela réduit le « caractère aléatoire "de la valeur un peu.

+0

Solution très simple. –