tags:

views:

55

answers:

4

I have two input fields for example's sake called A and B.

What i want, is to somehow derive a hash or total of these inputs, and pass that to a php function which will give me one of a set of results, but consistently.

Heres what i think it should look like

pseudo code

$a = $_POST[a];
$b = $_POST[b];

$pre = "$a$b";
// Put both inputs together as a single string

$hash = mashup($pre);
// Do something that creates a "hash" of the inputs given.

$output = magicfunction($hash);
// Takes the "hash" and uses some magic method to match it to a particular output

Now no matter what is put in the inputs, the output is one of say 20 things. If the user inputs something different, the out put will be different, but if they input the same thing, it will consistently return the same thing. Its possible for another input to output the same information, but the method which it picks what to output needs to be solid so that the same input will result in the same output.

An example of what im talking about(but not what im trying to make), is those sites where you enter your name and it gives you some novelty name, like pron star name, or rock star name, or whatever. Its not just random, if you enter the same name you get the same result, but different names can also give you that result.

+1  A: 

First off, are you sure you want a single hash from multiple inputs (as opposed to a single hash)?

Irrespective, you could use something like array_count_values (works on strings and ints) to create a trivial 'hash' and then use an array of ranges to select the output for each hash. For example:

$charHash = array_count_values(str_split($_POST['a'].$_POST['b']));

This might be too simplistic for what you're trying to achieve (hard to tell without more information), but it seems a reasonable approach.

middaparka
+2  A: 

It sounds like what you need is something like the md5() function in PHP. It generates a unique 32 character hash-string based on any length string input.

Collisions where different inputs give the same hash are very rare, but can happen if you have very varying input. If you would like to increase the number of collisons you could simply use substr() to e.g. only take the first 3 characters of the hash-string.

allanmc
You can convert the substring of this hash to a number using the hexdec() function.
mkluwe
+2  A: 

I think the easiest way is to resolve the string to say a value in the range of 0-19, which can then be looked up in an array. One way this could be done, loop through the $pre and keep adding the ascii values and then in the end do "mod 20" on it. See below.

function hashup($str,$totalSetSize = 20)
{
    $sum = 0;
    for ($i = 0; $i = strlen($str); $i++)
    {
        $sum += ord($str[$i]);
    }
    return ($sum % $totalSetSize);
}

hashup would return a value in the range 0-19, which magicfunction() can just look up in an array.

function magicfunction($idx)
{
    return $ROCK_STAR_NAMES[$idx];
}

Though in reality you do not need magicfunction, I just put it here to keep it consistent with your example.

With the above hash generation, the names 'a' and 'b' would give you the next name in ROCK_STAR_NAME. If you don't want this to be in sequence, you should do $pre=md5("$a$b"), and then pass it to hashsup.

aip.cd.aish
nice. I like that even better than mine
Gordon
+1  A: 

Revised code to use Dependency Injection and the hash method of aip.cd.aish above:

class Mapper
{
    protected $map = array();

    // Having to pass the map on instantiation allows us to
    // reuse the Mapper class for any map you want.
    public function __construct(array $map)
    {
        $this->map = $map;
    }

    // ** EDIT ** replaced my original hash method 
    // with the one from aip.cd.aish - so kudos to him.
    public function hash($str)
    {
        $sum = 0;
        for ($i = 0; $i = strlen($str); $i++) {
            $sum += ord($str[$i]);
        }
        return $sum;
    }

    public function mapInput($input)
    {   
        $output = $input;
        $items  = count($this->map);
        if($items > 0) {
            $hash   = $this->hash($input);
            $key    = $hash % $items;
            $output = $this->map[$key];
         }
         return $output;
    }        
}

// create new Mapper and pass the map to it.    
$mapper = new Mapper(array('cheese', 'onions', 'pepper', 'garlic', 
                           'tomatoe','sausage', 'ham', 'squid', 
                           'eggs', 'beef'));

echo $mapper->mapInput('Patrick');
Gordon