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_bytesphp 7 中可用,Laravel 慢慢转移到该函数并仅使用该函数而没有任何回退。

ramsey/uuid 是 Laravel 中默认的 UUID 库。通过查看代码,我们可以发现默认的随机生成器是RandomBytesGenerator,它使用random_bytesStr::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::randomUuid::uuid4(不修改UuidrandomGenerator)几乎相同。

【讨论】:

【参考方案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() 还是自定义函数?的主要内容,如果未能解决你的问题,请参考以下文章

laravel 测试错误,没有这样的文件或目录

laravel测试错误,没有这样的文件或目录

Laravel 5.7 - 上传到公共文件夹

Laravel 5.6 中的自定义助手

如何在 Laravel 5.3 中添加自定义通知通道

Laravel 加载并初始化自定义助手类