Oauth需要一个随机的64位无符号数字,以十进制格式编码为ASCII字符串。你能帮我用PHP实现这个吗? 谢谢。
Oauth需要一个随机的64位无符号数字,以十进制格式编码为ASCII字符串。你能帮我用PHP实现这个吗? 谢谢。
这是一个非常有趣的问题(如何在PHP中创建任意长度随机数的十进制表示,且不能使用可选扩展)。以下是解决方案:
// 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位的随机比特作为十六进制编码字符串,没有问题。
数学很难,所以这里是代码:
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);
/**
* Generate nonce
*
* @return string
*/
public function generateNonce()
{
return md5(uniqid(rand(), true));
}
count_bits
无法处理大于PHP_INT_MAX的数字。 - Charlescount_bits
确实有限,但由于我们只需要用它来测量mt_getrandmax
的返回值,因此它足以胜任这项工作。 - Jonmt_getrandmax
通常似乎也是2^31-1。 - Charlesnab = convert(n, a, b)
,可能存在n !== convert(nab, b, a)
的情况。要小心注意。 - ksimkabase_convert_arbitrary
。但是为什么要用所有的字母呢?$value = $value * $fromBase + $nibbles[$i];
不是保证操作只对 2 到 16 进制有效吗? - Chibueze Opatastrpos
而不是substr
。然而,我仍然对($value >= $toBase) { $nibbles[$newlen++] = (int)($value / $toBase); $value %= $toBase; }
感到困惑,这里到底发生了什么?评论将不胜感激。 - Chibueze Opata