PHP номер между интервалами в зависимости от входной строки
В PHP я могу сделать это:
echo rand(5, 15);
Это даст мне число от 5 до 15, отличающееся каждый раз.
Статический номер в зависимости от входной строки
echo my_static_number(5, 15, 'some/custom_string');
Я все еще хочу число от 5 до 15. Разница в том, что я хочу, чтобы оно вычислялось в зависимости от третьего аргумента, строки.
- Допускается вывод чисел 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
- Один и тот же номер каждый раз, пока вызов функции остается неизменным.
Пример из реальной жизни
Изображения в папке:
1.jpg
2.jpg
3.jpg
etc.
Вызов Php:
<img src="<?php echo get_image(1, 15, $url); ?>">
<img src="<?php echo get_image(1, 15, $url); ?>">
Выведите что-то вроде этого:
<img src="7.jpg">
<img src="7.jpg">
Один и тот же номер каждый раз, пока вызов функции одинаков.
2 ответа
Я ожидаю, что вы строите балансировщик нагрузки.
Здесь вам нужно вычислить хеш из строки и преобразовать его в число. Хорошей псевдослучайной хэш-функции будет достаточно, чтобы получить случайное распределение. Одно из решений может быть таким:
function my_static_number($a, $b, $str) {
$hash = hash('crc32', $str); // crc32 is probably the fastest here
$dec = hexdec($hash); // convert hash to a decimal value
$base = $b + 1 - $a; // +1 is needed to include $b as possible value
return $a + fmod($dec, $base); // get remainder from $dec / $base
}
Некоторые тесты на детской площадке:
Обновление: может быть небольшое улучшение в скорости, если вы возьмете первые 2 символа $hash
вместо этого, а затем использовать $dec % $base
вместо fmod:
function my_static_number($a, $b, $str) {
$hash = substr(hash('crc32', $str), 0, 2); // effectively produces a number between 0 and 255
$dec = hexdec($hash);
$base = $b + 1 - $a;
return $a + $dec % $base;
}
Я сделал тест на случайное распределение, и обе функции работают достаточно хорошо.
Вот о чем я подумал, когда прочитал ваш вопрос:
function my_static_number($min,$max,$seedStr)
{
$hash = md5($seedStr);
$length = strlen($hash);
$seed = 1234;
for ($i=0; $i<$length; $i++) $seed += ord($hash[$i]);
srand($seed);
return rand($min,$max);
}
echo my_static_number(5, 15, 'some/custom_strings');
rand()
можно посеять, и с тем же начальным числом он сгенерирует одинаковую случайную последовательность. Поэтому я хэширую полную строку, складываю значения ascii этого хэша и использую это как начальное число.
Таким образом, вы получите случайные числа, но они будут одинаковыми для одинаковых начальных строк.
Эта функция имеет некоторые ограничения:
- скорость: это не самая быстрая Если это необходимо, вам нужен совершенно другой алгоритм.
- случайность: наблюдается небольшое снижение случайности выходных данных из-за ограниченного числа начальных значений. Это можно улучшить.
Подумайте об этом: здесь нет никакой реальной необходимости использовать какую-либо случайную функцию: вы можете использовать хеш для вычисления полуслучайного числа. Вот так:
function my_static_number($min,$max,$seedStr)
{
$hash = md5($seedStr);
$length = strlen($hash);
$number = 1234;
for ($i = 0;$i < $length;$i++) $number += ord($hash[$i]);
return $min + ($number % ($max-$min));
}
echo my_static_number(5, 15, 'some/custom_string');