PHP:这个函数总是生成一个唯一的字符串吗?

时间:2011-06-28 06:25:04

标签: php base-conversion

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

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

由于

3 个答案:

答案 0 :(得分: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);

这比你设法独立完成的任何功能都要好。[/ edit]

答案 1 :(得分:1)

简单使用uniqid()良好的内置功能。这也会从时间戳生成唯一的ID。所以号码永远是唯一的。

答案 2 :(得分: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;
}

祝你好运!