0

Given a N-bit hash (e.g. output of md5()), I have 2 situations I need solutions for:

  1. Based on the hash, return an integer value in a given range.
  2. Based on the hash, return an array value from a given array.

Same hash, should always return same number or array key within that range or from that same input array. If the input array changes but hash remains the same, then i would get a different selection.

So for example i would have code like this:

    echo intFromHash(1, 100, 'abcd'); // 15
    echo intFromHash(1, 100, 'defg'); // 90
    echo arrayValueFromHash(['moe', 'joe', 'pike'], 'abcd'); // 'joe'
    echo arrayValueFromHash(['pike', 'dolly']); // pike
4
  • 1
    can you provide any code from your current "intFromHash" and "arrayValueFromHash" functions? Commented Oct 17, 2018 at 10:49
  • @FalcoB there's no code, those are actually the functions I need. Commented Oct 17, 2018 at 10:53
  • Welcome to Stack Overflow. Please take a tour of the site, read How to Ask and how to create a minimal reproducible example. Then come back to your question and reformulate it (preferably with code samples, provided input and the expected output) in order to get a (useful) answer. Before posting a question, search the site and make sure a similar question wasn't already answered. Please also note that Stack Overflow is not a coding service. Show what you have tried and where you got stuck to maximize the chances to get help. Commented Oct 17, 2018 at 11:14
  • You can write intFromHash() in 1 line of code using the crc32() PHP function. Then you can use it to implement arrayValueFromHash() (in another line of code). Commented Oct 17, 2018 at 11:18

2 Answers 2

1

You can write intFromHash() in 1 line of code using the crc32() PHP function:

function intFromHash($min, $max, $hash {
    return $min + crc32($hash) % ($max - $min + 1);
}

Use abs(crc32($hash)) if you are running it on a 32-bit system (read the documentation for details).

Then you can use it to implement arrayValueFromHash() (in another line of code):

function arrayValueFromHash(array $array, $hash) {
    return $array[intFromHash(0, count($array) - 1, $hash)];
}

Use return $array[array_keys($array)[intFromHash(...)]]; if $array is an associative array (the expression presented in the code works only for numerically indexed arrays, as those listed in the question.)

Sign up to request clarification or add additional context in comments.

Comments

0

Figured it out I think. Here's the code for whoever needs it:

    /**
     * Return a key from an array based on a given 4-bit hash.
     *
     * @param array $array Array to return a key from.
     * @param string $hash 4-bit hash. If hash is longer than 4-bit only first 4 bits will be used.
     * @return mixed
     */
    function getArrayValueByHash($array, $hash)
    {
        $arrayKeys = array_keys($array);
        $index = getIntFromHash(0, sizeof($arrayKeys)-1, $hash);
        return $array[$arrayKeys[$index]];
    }

    /**
     * Return an integer in range, based on a hash.
     *
     * @param int $start
     * @param int $end
     * @param string $hash 4-bit hash. If hash is longer than 4-bit only first 4 bits will be used.
     * @return int
     */
    function getIntFromHash($start, $end, $hash)
    {
        $size = $end-$start;
        $hash = str_split($hash);
        $intHash = ord($hash[0]) * 16777216 + ord($hash[1]) * 65536 + ord($hash[2]) * 256 + ord($hash[3]);
        $fits = $intHash / $size;
        $decimals = $fits - floor($fits);
        $index = floor($decimals * $size);
        return $start+$index;
    }

1 Comment

I believe you meant "4-byte" not "4-bit".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.