【问题标题】:How can I create a unique random string in laravel 5 [duplicate]如何在 laravel 5 中创建一个唯一的随机字符串 [重复]
【发布时间】:2015-10-23 14:32:22
【问题描述】:

我是 laravel 5 的新手。我正在做一个项目,我想为每个应用程序分配一些随机可读的 unique 字符串。我知道可以用作种子的每个应用程序 ID。由于该应用程序将在公司内部使用,因此我不太担心安全性。我希望表大小会增长,所以我的目标是尽可能地实现唯一性,因为 DB 中的字段是唯一的。类似(EN1A20、EN12ZOV 等)的代码。如果该函数可以让我传递我想要返回的字符串的长度,那就太棒了。

编辑 下面显示的是我对这个问题的尝试

private function generate_app_code($application_id) { 
        $token = $this->getToken(6, $application_id);
        $code = 'EN'. $token . substr(strftime("%Y", time()),2);

        return $code;
    }

    private function getToken($length, $seed){    
        $token = "";
        $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $codeAlphabet.= "0123456789";

        mt_srand($seed);      // Call once. Good since $application_id is unique.

        for($i=0;$i<$length;$i++){
            $token .= $codeAlphabet[mt_rand(0,strlen($codeAlphabet)-1)];
        }
        return $token;
    }

上面的代码可以解决问题吗?

编辑

实际上,我从这篇帖子PHP: How to generate a random, unique, alphanumeric string? 中借鉴了上面的方法,但这篇帖子并没有完全解决我的问题。我的目标是生成一个长度为 6 到 8 的字符串(字母数字且可读)。我的管理员将使用此字符串进行查询。在我的函数中,我有 mt_srand($seed) 为随机数生成器播种,其中种子是我的 application_id。有可能得到重复的$token。

感谢帮助。

【问题讨论】:

  • Str::random(6);仅在 laravel 中...
  • 对于未来的 Google 员工,他们正在寻找仅适用于 laravel 的解决方案。我创建了这个模型方法,它利用 Laravel 助手并检查数据库是否存在。在这种情况下,它用于 API 密钥生成 - public function generateApiKey() { do { // generate our new API key $key = 'key_' . str_random(32); } while (static::where('api_key', $key)-&gt;exists()); // return our newly generated API key return $key; }

标签: php random laravel-5


【解决方案1】:

你可以使用:

sha1(time())

解释:sha1是哈希函数,哈希函数最重要的特点是它们不会产生不同字符串的相同哈希,所以理论上time()总是唯一的,sha1(time())总是会给你唯一的固定宽度的字符串。

已编辑:

您可以使用您的功能,但在给出令牌之前,您可以连接到数据库并检查令牌是否存在,如果存在则生成新令牌,如果不存在则给出这个令牌。这种机制会给你独特的令牌。

【讨论】:

  • 我不想使用 sha1。目标是管理员将能够按此编号搜索应用程序以进行查询。我认为 sha1 字符串很长。
  • 我认为 mt_srand() 用种子为随机数生成器播种,所以我想知道令牌如何在某些时候变得重复。
  • 你可以使用内置的辅助函数:例如:$token = 'rand(111,555);回声 $token;
  • 当代码每秒运行多次时,这将导致重复的字符串。对于您的用例而言,这可能不够随机
  • 你总是可以将睡眠时间设置为 1 秒,或者如果这比使用毫秒数和睡眠时间 1 毫秒多
【解决方案2】:

通过您尝试解决问题,您可以应用以下方法来确保唯一的代码:

do
{
    $token = $this->getToken(6, $application_id);
    $code = 'EN'. $token . substr(strftime("%Y", time()),2);
    $user_code = User::where('user_code', $code)->get();
}
while(!empty($user_code));

编辑

要避免 laravel 中的无限循环,请使用

do
    {
        $token = $this->getToken(6, $application_id);
        $code = 'EN'. $token . substr(strftime("%Y", time()),2);
        $user_code = User::where('user_code', $code)->get();
    }
    while(!$user_code->isEmpty());

http://laravel.com/api/5.0/Illuminate/Support/Collection.html#method_isEmpty

或者一起去

  do
        {
            $token = $this->getToken(6, $application_id);
            $code = 'EN'. $token . substr(strftime("%Y", time()),2);
            $user_code = User::where('user_code', $code)->first();
        }
        while(!empty($user_code));

使用 first() 代替 get()。 $user_code 可能是唯一的,因此我们可以方便地提取第一个结果。

【讨论】:

    【解决方案3】:

    你可以使用内置的辅助函数:

    str_random(int);
    

    可以找到文档:Laravel 5.1 Docs

    为确保它是唯一的,您始终可以检查该名称是否不存在,如果确实存在,则重新运行该函数以生成新字符串。

    希望对您有所帮助。

    【讨论】:

    • 我认为我们正在寻找一个随机字符串,而不是在一个表中,这可能会生成一个现有的字符串,因为没有进行检查。
    • 这似乎比其他答案更清晰,但我看到 str_random() 在较新的 Laravel 版本中已被弃用,是否可以使用替代函数?
    • 看起来 'str_random' 是一个全局助手,现在已经不复存在,但您仍然可以使用 \Illuminate\Support\Str::random()。
    • str_random 存在于 Laravel 5.8
    • 对于最新的 Laravel 版本 7,您可以像 \Str::random(10); 一样使用它注意第一个“\”只是因为我没有包含 Str 特征。
    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 2010-11-19
    相关资源
    最近更新 更多