Как генерировать случайное 64-битное значение как десятичную строку в PHP
Oauth требует случайного 64-битного беззнакового числа, закодированного как строка ASCII в десятичном формате. Можете ли вы, ребята, помочь мне достичь этого с помощью php?
Благодаря
Ответы
Ответ 1
Вы можете использовать два 32-разрядных номера, четыре 16-битных номера и т.д.
PHP rand() и mt_rand() но сколько случайных бит, которые они поставляют, не указано стандартом (хотя они могут быть запрошены с помощью getrandmax() и mt_getrandmax(), соответственно.)
Таким образом, ваша самая простая ставка safest будет генерировать 64 случайных бита и устанавливать их один за другим.
Что касается работы с 64-битными целыми числами, я бы рекомендовал использовать библиотеку GMP, поскольку у нее есть хороший набор функций для помогите вам.
Вы можете создать номер, вызвать 64 gmp_setbit() на нем с последующими позициями, а затем преобразовать его в строку с помощью gmp_strval().
Ответ 2
Это была действительно интересная проблема (как создать десятичное представление произвольного числа случайных чисел в PHP без использования дополнительных расширений). Здесь решение:
Шаг 1: случайное число произвольной длины
// Counts how many bits are needed to represent $value
function count_bits($value) {
for($count = 0; $value != 0; $value >>= 1) {
++$count;
}
return $count;
}
// Returns a base16 random string of at least $bits bits
// Actual bits returned will be a multiple of 4 (1 hex digit)
function random_bits($bits) {
$result = '';
$accumulated_bits = 0;
$total_bits = count_bits(mt_getrandmax());
$usable_bits = intval($total_bits / 8) * 8;
while ($accumulated_bits < $bits) {
$bits_to_add = min($total_bits - $usable_bits, $bits - $accumulated_bits);
if ($bits_to_add % 4 != 0) {
// add bits in whole increments of 4
$bits_to_add += 4 - $bits_to_add % 4;
}
// isolate leftmost $bits_to_add from mt_rand() result
$more_bits = mt_rand() & ((1 << $bits_to_add) - 1);
// format as hex (this will be safe)
$format_string = '%0'.($bits_to_add / 4).'x';
$result .= sprintf($format_string, $more_bits);
$accumulated_bits += $bits_to_add;
}
return $result;
}
На этом этапе вызов random_bits(2048)
даст вам 2048 случайных битов в виде строки с шестнадцатеричным кодированием, без проблем.
Шаг 2: преобразование базы данных с произвольной точностью
Математика сложная, поэтому здесь код:
function base_convert_arbitrary($number, $fromBase, $toBase) {
$digits = '0123456789abcdefghijklmnopqrstuvwxyz';
$length = strlen($number);
$result = '';
$nibbles = array();
for ($i = 0; $i < $length; ++$i) {
$nibbles[$i] = strpos($digits, $number[$i]);
}
do {
$value = 0;
$newlen = 0;
for ($i = 0; $i < $length; ++$i) {
$value = $value * $fromBase + $nibbles[$i];
if ($value >= $toBase) {
$nibbles[$newlen++] = (int)($value / $toBase);
$value %= $toBase;
}
else if ($newlen > 0) {
$nibbles[$newlen++] = 0;
}
}
$length = $newlen;
$result = $digits[$value].$result;
}
while ($newlen != 0);
return $result;
}
Эта функция будет работать как рекламируемая, например, попробуйте base_convert_arbitrary('ffffffffffffffff', 16, 10) == '18446744073709551615'
и base_convert_arbitrary('10000000000000000', 16, 10) == '18446744073709551616'
.
Объединение вместе
echo base_convert_arbitrary(random_bits(64), 16, 10);
Ответ 3
Вы сами строите адаптер OAuth? Если это так, вы можете пересмотреть. Там есть много хороших библиотек OAuth, в том числе один из PECL, один в PEAR, другой из Zend Framework и этот другой один из которых размещен в Google Code. Я работал с первыми тремя, и все они довольно приличные.
Если вы действительно хотите сделать это самостоятельно, вы можете столкнуться с проблемой. PHP не может мыслить в 64-разрядных номерах, если он не скомпилирован на 64-битной платформе или у вас есть расширенное расширение математики. Это будет очень сложно представить 64-битное число как десятичное. Похоже, что многие из библиотек, которые я связал выше, полностью игнорируют требования к формату и просто работают с хешем исходного MD5. Здесь код из адаптера ZF:
/**
* Generate nonce
*
* @return string
*/
public function generateNonce()
{
return md5(uniqid(rand(), true));
}
Они выглядят так, как будто им не хватает проблем без взаимодействия.