1

下面的函数会始终生成一个唯一的字符串吗?以下函数生成的字符串的长度范围是多少?是否可以改进以产生更多独特性?

base_convert(mt_rand(10, 99) . intval(microtime(true) * 100), 8, 36);

谢谢

4

3 回答 3

4

请记住,编写自己的随机/唯一函数通常不是一个好主意。就像 KingCrunch 提到的那样,PHP 有一个内置函数uniqid可以完全满足您的需求。

要回答您的问题:

该函数不会总是生成唯一的字符串,这是不可能的。然而,良好的功能使其极不可能(比中彩票小几倍),因此在实践中足够独特。

长度:

  • mt_rand(10,99) : 生成 [10,99] 范围内的数字(2 位数字)
  • intval(microtime(true)*100) 将获取当前的 unix 时间戳加上 2 位毫秒。时间戳(目前)为 10 位长(并将保持大约一个世纪),因此总位数为 12 位(十进制)

然后它将数字视为 base_8 数字,这将经常失败,因为 base_8 不知道数字 8 或 9。在这种情况下,我不知道确切的 PHP 行为,但它仍然无效。如果您将数字视为以 10 为底,那么您有以下场景问题:需要多少位(以 36 为底)来表示 10^13(如果 mt_rand 生成 10)和 10^14(如果 mt_rand 生成 99)之间的数字)。

base_36 需要 9 位数字的最小数字是 2,821,109,907,457,它低于您的数字的下限。然而,它可以用 9 位数字表示的最大数字是 101,559,956,668,416 (~10^14)。因此它将生成一个 9 位的 base_36 数字。

[编辑] 我看到你特别需要一个 6 字符的唯一字符串。请记住,6 个字符相对较短,因此很难保证唯一性。你最好的选择仍然是

substr(uniqid(), 0, 6);

它比你自己想出的任何功能都要好。[/编辑]

于 2011-06-28T06:40:00.410 回答
1

简单使用 uniqid() 良好的内置函数。这也会从时间戳生成唯一 ID。所以 No. 将永远是唯一的。

于 2011-06-28T08:13:38.710 回答
0

您的问题的答案取决于您的要求。我将此功能用于一般不太安全的要求。只返回字母和数字,清除“相似”字符:-

function fGetRandomString($vLength = 4) {
    $sRandomString = "";    $sChr = "";
    for ($i = 0 ; $i < $vLength ; $i++) {
        $vState = rand(1, 3);
            switch ($vState)    {
            case 1: $sChr = chr(rand(65, 90));  break;  // CAPS (A-Z)
            case 2: $sChr = chr(rand(97, 122)); break;  // small (a-z)
            case 3: $sChr = chr(rand(48, 57));  break;  // Numbers (0-9)
        }
        if (!in_array($sChr, array('O', 'o', '0', '1', 'l')))   $sRandomString .= $sChr;
        else    $i--;
    }
    return $sRandomString;
}

祝你好运!

于 2011-06-28T07:47:12.373 回答