具有 7 个字符的随机字母数字(基数 36 = 0..9 + a..z)值必须在 2176782336 和 78364164095 之间具有基数 10 表示,以下 sn-p 证明了这一点:
var_dump(base_convert('1000000', 36, 10)); // 2176782336
var_dump(base_convert('zzzzzzz', 36, 10)); // 78364164095
为了使其独一无二,我们必须依赖非重复因素,显而易见的选择是time():
var_dump(time()); // 1273508728
var_dump(microtime(true)); // 1273508728.2883
如果我们只想确保每秒 1 个唯一代码的最小唯一性因子,我们可以这样做:
var_dump(base_convert(time() * 2, 10, 36)); // 164ff8w
var_dump(base_convert(time() * 2 + 1, 10, 36)); // 164ff8x
var_dump(base_convert(time() * 2 + 2, 10, 36)); // 164ff8y
var_dump(base_convert(time() * 2 + 3, 10, 36)); // 164ff8z
您会注意到这些代码不是随机的,您还会注意到 time() (1273508728) 小于 2176782336(7 个字符代码的最小基数 10 表示),这就是为什么我做time() * 2。
现在让我们做一些日期数学,以增加随机性并增加唯一性因子,同时遵守旧版本 PHP (< 5.0?) 的整数限制:
var_dump(1 * 60 * 60); // 3600
var_dump(1 * 60 * 60 * 24); // 86400
var_dump(1 * 60 * 60 * 24 * 366); // 31622400
var_dump(1 * 60 * 60 * 24 * 366 * 10); // 316224000
var_dump(1 * 60 * 60 * 24 * 366 * 20); // 632448000
var_dump(1 * 60 * 60 * 24 * 366 * 30); // 948672000
var_dump(1 * 60 * 60 * 24 * 366 * 31); // 980294400
var_dump(PHP_INT_MAX); // 2147483647
关于PHP_INT_MAX 我不确定最近版本的 PHP 到底发生了什么变化,因为以下内容显然适用于 PHP 5.3.1,也许有人可以对此有所了解:
var_dump(base_convert(PHP_INT_MAX, 10, 36)); // zik0zj
var_dump(base_convert(PHP_INT_MAX + 1, 10, 36)); // zik0zk
var_dump(base_convert(PHP_INT_MAX + 2, 10, 36)); // zik0zl
var_dump(base_convert(PHP_INT_MAX * 2, 10, 36)); // 1z141z2
var_dump(base_convert(PHP_INT_MAX * 2 + 1, 10, 36)); // 1z141z3
var_dump(base_convert(PHP_INT_MAX * 2 + 2, 10, 36)); // 1z141z4
我在这里的合理化有点迷失了,我很无聊,所以我会很快完成。我们几乎可以使用整个 36 个基本字符集并安全地生成顺序代码,保证唯一性因子为每秒 1 个唯一代码for 3.16887646 years,使用以下代码:
base_convert(mt_rand(22, 782) . substr(time(), 2), 10, 36);
我刚刚意识到,由于mt_rand() 的第一个参数,上述内容有时会返回重复值,为了产生独特的结果,我们需要稍微限制我们的基本 36 字符集:
base_convert(mt_rand(122, 782) . substr(time(), 2), 10, 36);
请记住,上面的值仍然是连续的,为了使它们看起来随机,我们可以使用microtime(),但我们只能确保每秒10个代码for 3.8 months的唯一性因子:
base_convert(mt_rand(122, 782) . substr(number_format(microtime(true), 1, '', ''), 3), 10, 36);
事实证明这比我最初预期的要困难,因为有很多限制:
- 使用整个 base 36 字符集
- 生成外观随机的代码
- 每秒唯一性因子与唯一性持久性之间的权衡
- PHP 整数限制
如果我们可以忽略以上任何一项,它会容易得多,我相信这可以进一步优化,但就像我说的:这让我很无聊。也许有人想在我离开的地方捡起这个。 =) 我饿了! =S