tags:

views:

62

answers:

4

How can I get random number from text?

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);

So that "text1" always return 476 (for example) in mt_rand(1, 1000), and "text2" - always 241.
Is it possible?

A: 

It sounds like you want to return a random number between 1 and 1000 when given a string key but you want to return the same "random number" every time you get the same string key.

My intuitive solution was hash your input and return an int based on that. However, a much better solution is to cache your generations:

$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

Edit: Updated, you want to cache per min/max too.

Graphain
`assertEqual($rand1, text_to_number($text1, 1, 1000)); //PSEUDOCODE assert` - what is this? where can I read about this?
Qiao
It was pseudocode (i.e. not real code) that just demonstrates that repeated calls should be the same. Just ignore it.
Graphain
This "cache" would only live for the time this script is running. This may of may not be of any use, depending on the purpose. (Also, I think your use of globals makes this broken)
Brenton Alker
@Brenton Yeah you're right about caching for time of script. I wasn't sure on the use case. Yeah I'm sure it does, I assumed they would translate it into a member variable in their own class.
Graphain
+4  A: 

What you want to do is to seed random generator with value based on your string. See, the code

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

will always assign the same value to $value, no matter how many times you call it. Even better, all other calls to mt_rand will return the same values (different from each other) consistently from one run to another but you shouldn't care about that.

So, you have to write

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);
}

How do you calculate seed based on text is another problem. You can convert each char to integer and sum them up. You can calculate CRC32. You can make MD5 and get part of that. Lots of choices here.

But really, why don't you just use some sort of CRC or MD5 directly?

vava
new to that king of problems, now i will. But like randomness more.
Qiao
MD5 looks random :) So does CRC32. Use SHA512 and no one will be able to guess your string from the number you got. That is exactly what those hash algorithms are for.
vava
+4  A: 

I'd say forget about the "random", it sounds like what you really want is some form of hash. Here is a simple implementation that uses the md5 hash of the string and uses modulus to scale it into your required range.

function text_to_number($text, $min = 0, $max = 1000)
{
  return fmod(hexdec(md5($text)), ($max - $min)) + $min;
}
Brenton Alker
This was my first thought too but you executed it better. This would be nicer than caching.
Graphain
+1 for hash. Yup, that sounds like what he needsd
LeonixSolutions
+1  A: 

You seem to be asking for a CRC. This type of function computes a short hash in the form of a number (usually 32 bits) for a string designed to be a quick, fairly reliable way to determine if two strings are different.

crc32($string)

This will return a value between -2147483648 and 2147483647.

To make sure it falls within 0 to 999, try using something like

abs(crc32($string)) % 1000

Of course this reduces the "randomness" of the value somewhat.

thomasrutter
Very simple solution.
Graphain