Есть несколько хороших ответов, но для меня подходы кажутся глупыми.
Сначала они заставляют php создать шестнадцатеричное число, затем конвертируют его обратно (hexdec
) в BigInteger и затем сокращают его до количества букв ... это большая работа!
Вместо этого, почему бы не
Считать хеш в двоичном виде:
$binhash = md5('[input value]', true);
затем используя
$numhash = unpack('N2', $binhash); //- or 'V2' for little endian
для приведения этого к двум INT
с ($numhash
- это массив из двух элементов). Теперь вы можете уменьшить количество бит в числе, просто используя операцию AND
. например:
$result = $numhash[1] & 0x000FFFFF; //- to get numbers between 0 and 1048575
Но предупреждаем о столкновениях! Уменьшение числа означает увеличение вероятности двух разных [входных значений] с одинаковым выходом.
Я думаю, что гораздо лучшим способом было бы использование "ID-Crypting" с функцией Bijectiv. Так что никаких столкновений не может произойти! Для простейшего вида просто используйте Affine_cipher
Пример с максимальным диапазоном входных значений от 0 до 25:
function numcrypt($a)
{
return ($a * 15) % 26;
}
function unnumcrypt($a)
{
return ($a * 7) % 26;
}
Выход:
numcrypt(1) : 15
numcrypt(2) : 4
numcrypt(3) : 19
unnumcrypt(15) : 1
unnumcrypt(4) : 2
unnumcrypt(19) : 3
* * +1032 например,
$id = unnumcrypt($_GET('userid'));
... do something with the ID ...
echo '<a href="do.php?userid='. numcrypt($id) . '"> go </a>';
конечно, это небезопасно, но если никто не знает метод, используемый для вашего шифрования, то нет никаких причин безопасности, тогда этот путь быстрее и безопаснее при столкновении.