Laravel str_random() 还是自定义函数?
Posted
技术标签:
【中文标题】Laravel str_random() 还是自定义函数?【英文标题】:Laravel str_random() or custom function? 【发布时间】:2014-05-25 19:16:05 【问题描述】:Laravel str_random() 函数是否足够随机,以便我可以将其用于 ID?
例如:
str_random(32);
这会生成一个长度为 32 的随机字符串,由字母数字字符 [a-zA-z0-9](总共 62 个字符)组成。
这相当于 2272657884496751345355241563627544170162852933518655225856 种可能性。
但是,我的问题是,这是否足够好?或者我应该考虑使用 UUID 或其他自定义函数。
【问题讨论】:
您可以在保存之前检查以确保它不是重复的,例如在生成独特的 slug 时。当然,这不太可能发生。 【参考方案1】:str_random
(Str::random()
) 尝试使用openssl_random_pseudo_bytes
,这是一个针对密码学优化的伪随机数生成器,而不是唯一性。如果openssl_random_pseudo_bytes
不可用,则回退到quickRandom()
:
public static function quickRandom($length = 16)
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
在我看来,quickRandom
代码不唯一性和密码学都不可靠。
是的,拥有openssl_random_pseudo_bytes
并使用 32 字节几乎不可能看到冲突,但仍有可能。如果你想确保你的字符串/数字是唯一的(99.99%),你最好使用 UUID 函数。这是我通常使用的:
/**
*
* Generate v4 UUID
*
* Version 4 UUIDs are pseudo-random.
*/
public static function v4()
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
// 16 bits for "time_mid"
mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
它会生成一个有效的 RFC 4211 COMPLIANT 版本 4 UUID。
检查这个:https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions
【讨论】:
你在哪里声明'如果它可用'关于openssl,为什么不呢?另外,什么是唯一性的最佳方法,因为我将使用字符串作为 ID。 在这一行:github.com/laravel/framework/blob/master/src/Illuminate/Support/…,泰勒检查它是否可用,所以我不得不假设它可能并不总是可用。 在您看来,quickRandom 就足够了吗?如果我要在保存之前检查它是否是唯一的。连续发生两次碰撞的可能性很小......? 不是。它可能有利于临时文件的创建/删除,或者在页面上提供 html 唯一 id,给出一些示例,但不能用作 id。编辑使其更清晰。 对于您的 UUID,您所做的只是根据mt_rand()
生成一个非常长的随机数。这与mt_rand($largeNumber, $largerNumber)
没有什么不同...您只是添加一些破折号以使其看起来不像一个很长的数字。【参考方案2】:
你可以用这个
use Illuminate\Support\Str;
$random = Str::random(40);
【讨论】:
这是在 laravel 8 上工作的。不客气【参考方案3】:接受的答案在 2014 年 4 月是正确的。它不再准确。 2014 年 11 月 there was a commit 删除了 quickRandom
的使用。随着 random_bytes
在 php 7 中可用,Laravel 慢慢转移到该函数并仅使用该函数而没有任何回退。
ramsey/uuid
是 Laravel 中默认的 UUID 库。通过查看代码,我们可以发现默认的随机生成器是RandomBytesGenerator
,它使用random_bytes
。 Str::random
使用的方法相同。
关于 UUID 的 Wikipedia 页面对 UUID v4 做了以下说明:
[...] 版本 4 UUID 将有 6 个预先确定的变体和版本位,剩下 122 位用于随机生成的部分,[...]
https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
128 位 = 122 个随机位 + 6 个版本位。 128 位正好是 16 个字节。大多数 UUID 实现读取 16 个字节的随机字节,然后替换指定位置的版本(在 v4 的情况下)。
总而言之,到目前为止,如果您使用长度等于 16 的Str::random
或Uuid::uuid4
(不修改Uuid
的randomGenerator
)几乎相同。
【讨论】:
【参考方案4】:您可以使用this 包。
例如:
Uuid::generate()
【讨论】:
【参考方案5】:为了让它更独特,使用 TIMESTAMP 和 concat row id 简单且重复数字的可能性为零
【讨论】:
【参考方案6】:我使用的是 Laravel 6 版本,在 Illuminate\Support\Str::random 上运行良好,但是 str_random 和 Illuminate\Support\Str::str_random 都不适用于我使用 Laravel 6。
下面你可以看到函数的文档
/**
* Generate a more truly "random" alpha-numeric string.
*
* @param int $length
* @return string
*/
public static function random($length = 16)
【讨论】:
以上是关于Laravel str_random() 还是自定义函数?的主要内容,如果未能解决你的问题,请参考以下文章