【问题标题】:Generate random structured data with PHP使用 PHP 生成随机结构化数据
【发布时间】:2013-06-16 11:19:32
【问题描述】:

我想知道如何继续创建一个与 IPv6 结构相似的随机 PHP 值

示例:2001:0db8:85a3:0042:1000:8a2e:0370:7334:nc21

我可以使用mt_rand(0000,9999).":"....... and so on 但这只会创建数值,而且是多余的。有没有一种更简单的方法可以在说一个函数中以数字方式完成它?

感谢大家的反馈和信息,最后我选择了以下代码位

$randomString = sha1(dechex(mt_rand(0, 2147483647)));
$token = implode(':', str_split($randomString, 4));

结果:

9ec0:4709:926e:4cbf:fa87:2ac3:03da:f547:485b:6464

【问题讨论】:

  • 然后使用dechex(),以及4个半字节十六进制值的实际数字范围。
  • 你实际上用这个做什么?如果只是为了生成唯一的ID,还有uniqid函数。
  • 生成一个完全随机的Token
  • 您可以随机创建一个整数(正如您已经展示过的那样)或创建一个像stackoverflow.com/questions/5438760/… 这样的字符。将这两个方法都放入一个函数中,然后随机选择调用哪一个。然后你会随机得到一个数字或一个字母。
  • @user1477388 感谢您的信息,但这个$randomString = sha1(dechex(mt_rand(0, 2147483647))); $token = implode(':', str_split($randomString, 4)); 工作正常

标签: php


【解决方案1】:

避免使用rand 参见str_shuffle and randomness 尝试:

echo myRand(36);

输出

023c:631e:f770:ec5b:f06b:917a:b839:4aea:45b7

使用的功能

function myRand($length, $sep = ":", $space = 4) {
    if (function_exists("mcrypt_create_iv")) {
        $r = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
    } else if (function_exists("openssl_random_pseudo_bytes")) {
        $r = openssl_random_pseudo_bytes($length);
    } else if (is_readable('/dev/urandom')) {
        $r = file_get_contents('/dev/urandom', false, null, 0, $length);
    } else {
        $i = 0;
        $r = "";
        while($i ++ < $length) {
            $r .= chr(mt_rand(0, 255));
        }
    }
    return wordwrap(substr(bin2hex($r), 0, $length), $space, $sep, true);
}

【讨论】:

  • 我可以建议/dev/random 作为另一个后备方案吗?虽然 +1。
  • MCRYPT_RAND = /dev/random while MCRYPT_DEV_URANDOM is /dev/urandom ...我使用`/dev/urandom`因为/dev/random会在熵池耗尽后阻塞
  • 是的,我知道,但如果 mcrypt 和 openssl 都不可用,is_readable('/dev/urandom') &amp;&amp; file_get_contents('/dev/urandom', false, null, 0, $length) 是一个简单的后备方案,可能比mt_rand 更可取。
  • @deceze .. 我明白你的意思了 .. .. 谢谢会马上更新代码
  • @Baba 我参考了你的答案,以防有人需要安全的随机数据而不是简单快速的方法。
【解决方案2】:

使用密码哈希函数。他们默认输出十六进制:

md5(rand()) // eg: ccc4fd993dd07dac621455c7c924d38f

其他implodestr_split(md5(rand()), 4) 的返回值用冒号创建如下:

implode(':', str_split('ccc4fd993dd07dac621455c7c924d38f', 4));
// ccc4:fd99:3dd0:7dac:6214:55c7:c924:d38f

根据您希望随机使用的块数,使用substr 截断哈希。


注意此方法不会产生真正的随机性。如果需要真正随机的数据,请查看 Baba 的答案。

【讨论】:

  • 几乎完全符合我的建议,除了使用uniqid() 而不是rand(),因为它增加了一层额外的冲突避免层。
  • 很棒的作品就像一个魅力,这就是我所做的$randomString = sha1(dechex(mt_rand(0, 2147483647))); $token = implode(':', str_split($randomString, 4));
  • @user2293381 请注意,sha1 的输出大小为 160 位(= 40 个十六进制字符)。 IPv6 的大小只有 128 位(= 32 个字符)。 md5 可能更适合!
  • @TimWolla 我只是在寻找 IPv6 结构,因此是“:”。我只是不知道怎么称呼它,所以我只是把它称为 IPv6 结构
  • 请注意,rand() 最多返回 2,147,483,647 个不同的数字,而md5 的空格为 16^32。使用这种方法根本不会有效地填充 MD5 空间。如果 2,147,483,647 个不同的值就足够了,没问题;但对于 IPv6 等 unique 值的目的来说还不够好(我知道,这只是一个例子)。
【解决方案3】:

您可以生成一个介于 0 和 65 535 (0xffff) 之间的随机数,然后使用 dechex 将其转换为十六进制。

请注意,字符串的结尾 nc21 不是有效的十六进制数字,因此不是有效的 IPv6 地址。

【讨论】:

  • 我知道,我只是作为参考。对此感到抱歉
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 2015-07-26
  • 2015-02-26
相关资源
最近更新 更多