生成随机数字和字母

13

我可以请求一段生成包含随机字母和数字的单词的代码吗?我知道有一个PHP函数rand(),但我不知道它是否适用于字母。还有一个名为mt_rand()的函数,但我不知道它是如何工作的。我打算生成像这样的一个单词:

$randomcode = re784dfg7ert7;

你们有没有关于这个问题的简单代码?提前谢谢!


你可能想使用Random::alphanumericLowercaseString($length),甚至可以放弃“小写字母”的要求。 - caw
14个回答

19
<?php
echo substr(sha1(mt_rand()),17,6); //To Generate Random Numbers with Letters.
?>

12

这是我经常使用的更为广泛的方法,用于生成随机数字、字母或混合:

function assign_rand_value($num) {

    // accepts 1 - 36
    switch($num) {
        case "1"  : $rand_value = "a"; break;
        case "2"  : $rand_value = "b"; break;
        case "3"  : $rand_value = "c"; break;
        case "4"  : $rand_value = "d"; break;
        case "5"  : $rand_value = "e"; break;
        case "6"  : $rand_value = "f"; break;
        case "7"  : $rand_value = "g"; break;
        case "8"  : $rand_value = "h"; break;
        case "9"  : $rand_value = "i"; break;
        case "10" : $rand_value = "j"; break;
        case "11" : $rand_value = "k"; break;
        case "12" : $rand_value = "l"; break;
        case "13" : $rand_value = "m"; break;
        case "14" : $rand_value = "n"; break;
        case "15" : $rand_value = "o"; break;
        case "16" : $rand_value = "p"; break;
        case "17" : $rand_value = "q"; break;
        case "18" : $rand_value = "r"; break;
        case "19" : $rand_value = "s"; break;
        case "20" : $rand_value = "t"; break;
        case "21" : $rand_value = "u"; break;
        case "22" : $rand_value = "v"; break;
        case "23" : $rand_value = "w"; break;
        case "24" : $rand_value = "x"; break;
        case "25" : $rand_value = "y"; break;
        case "26" : $rand_value = "z"; break;
        case "27" : $rand_value = "0"; break;
        case "28" : $rand_value = "1"; break;
        case "29" : $rand_value = "2"; break;
        case "30" : $rand_value = "3"; break;
        case "31" : $rand_value = "4"; break;
        case "32" : $rand_value = "5"; break;
        case "33" : $rand_value = "6"; break;
        case "34" : $rand_value = "7"; break;
        case "35" : $rand_value = "8"; break;
        case "36" : $rand_value = "9"; break;
    }
    return $rand_value;
}

function get_rand_alphanumeric($length) {
    if ($length>0) {
        $rand_id="";
        for ($i=1; $i<=$length; $i++) {
            mt_srand((double)microtime() * 1000000);
            $num = mt_rand(1,36);
            $rand_id .= assign_rand_value($num);
        }
    }
    return $rand_id;
}

function get_rand_numbers($length) {
    if ($length>0) {
        $rand_id="";
        for($i=1; $i<=$length; $i++) {
            mt_srand((double)microtime() * 1000000);
            $num = mt_rand(27,36);
            $rand_id .= assign_rand_value($num);
        }
    }
    return $rand_id;
}

function get_rand_letters($length) {
    if ($length>0) {
        $rand_id="";
        for($i=1; $i<=$length; $i++) {
            mt_srand((double)microtime() * 1000000);
            $num = mt_rand(1,26);
            $rand_id .= assign_rand_value($num);
        }
    }
    return $rand_id;
}

用法:

基本上,我有一个带有数组的主函数,然后我调用次要函数根据长度参数构建我的字符串:

字母:

$str = get_rand_letters(8); // Only Letters

数字:

$str = get_rand_numbers(8); // Only Numbers

字母数字混合码:

$str = get_rand_alphanumeric(8); // Numbers and Letters

这个问题已被Kerrek SB回答,但这可能有助于寻找更广泛、更灵活的方法的人。


2
这并不是“广泛的”。它只是冗长而已。你可以将所有这些字母和数字塞进数组中,并通过数字键引用它们。assign_rand_values() 看起来有点多余。此外,使用可预测的数字(如 microtime())进行种子处理并不总是最好的选择。(如果我听起来像个混蛋,我只是想帮忙 :) ) - Bailey Parker
@PhpMyCoder:我不是个混蛋,而是一个关心自己表现的人 :) 实际上,我很久以前就设置了这个,基于一些例子...它能用,所以我再也没有看过它!但是,我会进行性能优化的!谢谢 :) - Zuul
你应该在程序中仅对 RNG 进行一次种子初始化,而不是在循环中每次都进行,否则你将无法获得可预测的统计特性。 - Kerrek SB
这个答案让我想起了为什么我尽可能避免使用switch块——它们非常冗长。我会将其转换为一个干净简单的查找数组。if ($length>0) {要么是一个不必要的检查,要么会阻止声明预期的变量。 - mickmackusa

6

步骤1:创建一个字母表,$alph = "0123456789abcde..."

步骤2:创建一个随机数,$n = rand(0, ALPHSIZE-1),或使用mt_rand()

步骤3:获取字母表中的适当索引:$alph[n]

重复步骤2和步骤3,直到你需要的字符数量出现为止。

如果你想要强大的统计特性(如均匀性),那么你应该更加努力工作来获得随机数,但这个方法可以帮助你入门。(我认为这个的统计特性已经足够了。)


好的,也许可以详细说明一下:

$alph = "012...";
function make_random_string($N)
{
  $s = "";
  for ($i = 0; $i != $N; ++$i)
    s .= $alph[mt_rand(0, ALPHSIZE - 1)];
  return $s;
}

下面是使用自定义字母表的版本:

function make_random_custom_string($N, $alphabet)
{
  $s = "";
  for ($i = 0; $i != $N; ++$i)
    s .= $alphabet[mt_rand(0, strlen($alphabet) - 1)];
  return $s;
}

例如:10个随机的奇数位数字:make_random_custom_string(10, "13579");

这段代码将使用给定的数字集合生成一个长度为10的随机字符串,其中只包含奇数位数字。

rand() % N 会更倾向于选择靠近字母表开头的字符,除非最大随机值加一能够被字母表大小整除。使用 rand(0, strlen($alph) - 1) 会更好。 - cdhowie
@cdhowie:是的,我知道...就像我说的,如果一致性很重要,你必须多花点功夫。不过mt_rand()函数似乎可以得到正确的分布。---哦,我明白了,你实际上也可以为rand()指定一个范围。我会进行编辑! - Kerrek SB
抱歉,我不理解第三步。你能否更清楚地表达或者像教一个新手程序员一样说明一下?谢谢。 - glove
@Glove:你需要在0..SIZE-1范围内获取一个数字,所以我只是取模运算后得到了余数(%是“模运算符”)。但不要紧,有一种更好的方法,可以直接在rand调用中指定范围,建议使用这种方法。这将逐个字符地给你,因此循环次数应与所需字符数相同。 - Kerrek SB
1
我知道这可能只是微不足道的微观优化,但我会将 strlen($alphabet) - 1 存储在一个变量中。在 for 循环期间,它永远不会改变,因此调用它多次似乎是不必要的。 - Bailey Parker
显示剩余3条评论

5
使用uniqid
$desired_length = 10; //or whatever length you want
$unique = uniqid();

$your_random_word = substr($unique, 0, $desired_length);

more_entropy(第二个参数,第一个参数为空字符串作为前缀)设置为 true,以输出 23 个字符而不是 13 个字符。 - Bailey Parker
这也可以包含 . - rybo111

3
这对我来说很容易 - 这将生成一个15个字符的字符串 -
        $alph = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $code='';

        for($i=0;$i<15;$i++){
           $code .= $alph[rand(0, 35)];
        }

为什么不使用 for() 循环语法?为什么不使用 .= 进行连接?为什么不通过偏移量访问随机字符($code .= $alph[rand(0, 35)];),而要使用那些迭代函数调用?如果我要实现你的逻辑,只有前两行代码会保持不变。 - mickmackusa
感谢您的建议,代码示例已更新。 - Don F

2
这可以这样完成:
function RandomCode($length = 10)
{
    $code = '';
    $total = 0;

    do
    {
        if (rand(0, 1) == 0)
        {
            $code.= chr(rand(97, 122)); // ASCII code from **a(97)** to **z(122)**
        }
        else
        {
            $code.= rand(0, 9); // Numbers!!
        }
        $total++;
    } while ($total < $length);

    return $code;
}

看一下 mt_rand()。另外,通过创建一个在 97 到 132 之间的随机数来限制使用它(或 rand())可能是个好主意。然后,如果这个数字小于等于 122,就使用 char;如果大于 122,则减去 122 并将其解释为一个数字。 - Bailey Parker
谢谢你的提示。我一直使用rand函数,但我发现mt_rand更快。但是如果我使用mt_rand并给出最小和最大参数,而不是验证数字是否大于或小于122呢? - user898741
我明白了,所以你只有一个 mt_rand,而不是像我的代码中一样有两个。非常好! - user898741
它还可以扩展以包括大写字母和特殊字符。 - Bailey Parker

1
function randText($len=4){
    $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    for($i=0;$i<$len;$i++){
        $txt.=substr($str, rand(0, strlen($str)), 1);   
    }
return $txt;
}

使用方法很简单,只需输入:

$yourVar = randText(10);  // to get 10char long text

1
请编辑您的答案,添加代码的解释以及它是如何解决问题的。许多 Stack Overflow 的用户都是新手,可能无法理解您发布的代码。 - i alarmed alien
当意图访问单个单字节字符时,使用 substr() 是不必要的调用。最简单的方法是使用方括号语法按偏移量定位字符。 - mickmackusa

1
尝试一下,这对我有效。
$numLenth = 35;

function make_seed_Token() {
  list($usec, $sec) = explode(' ', microtime());
  return (float) $sec + ((float) $usec * 100000);
}

srand(make_seed_Token());

$numSeed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$getNumber = "";
for($i = 0; $i < $numLenth; $i ++) {
 $getNumber .= $numSeed[rand(0, strlen($numSeed))];

}

echo $getNumber;

在Stackoverflow上,仅有代码的答案价值较低,因为它们对于数千名未来的研究人员几乎没有教育/授权作用。 - mickmackusa
$numSeed 在你的代码片段中长度不会改变,所以 PHP 反复计算它的长度是不必要的努力。 - mickmackusa

1
这是一个简单的代码示例。它会生成10个字符,您可以通过修改限制(0,10)来限制字符数量。
$str = substr(md5(time()), 0, 10);
echo $str; //7aca159655

1
echo bin2hex(openssl_random_pseudo_bytes(12));

在Stackoverflow上,仅有代码的答案价值较低,因为它们对于数千名未来的研究人员几乎没有教育/赋能作用。 - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接