How can I create a unique random string in laravel

2020-06-01 09:23发布

问题:

I am new to laravel 5. I am working on a project where I want to assign some random-readable unique string to each application. I have knowledge of the each application id which may be use as a seed. Since the app is going to be use within the company I don't worry much about security. I expect the table size to grow so my goal is to achieve uniqueness as much as possible because the field in DB is unique. A code like (EN1A20, EN12ZOV etc). If the function can allow me to pass the length of the string I want to return, that would be really awesome.

Edit Shown below is my attempt to the problem

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;
    }

Can the code above do the trick?

Edit

Actually I borrowed ideas from this post PHP: How to generate a random, unique, alphanumeric string? to come out with the methods above but the post does not entirely address my issues. My goal is to generate a string of length say 6 to 8 (Alphanumeric and readable). This string would be use by my admin for query purposes. In my function I have mt_srand($seed) to seed the random number generator where seed is my application_id. It is possible to get duplicate $token.

Appreciate help.

回答1:

With your attempt to the problem you could apply the following to ensure a unique code:

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));

Edit

To avoid an infinite loop in laravel, use

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

or go with

  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));

Instead of get(), use first(). $user_code is probably unique so we can conveniently pull out the first result.



回答2:

You can use :

sha1(time())

Explanation: sha1 is hash function, and most important characteristic of hash function is that they never produce the same hash of different string, so as time() is always unique in theory sha1(time()) will always give you unique string with fixed width.

EDITED:

You can use you function but before giving token you can connect to database and check if token exists, if exists generate new token, if not exists give hin this token. This mechanism will give you unique tokens.



回答3:

You could use the built in helper function:

str_random(int);

The documentation can be found: Laravel 5.1 Docs

To ensure it is unique you could always check that the name doesn't already exist and if it does rerun the function to generate a new string.

Hope that helps.