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.
Answer from fico7489 on Stack OverflowYou 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.
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.
Create a function that generates the 10 digit random key then passes it through a validator with a unique rule set. If the validator gives you an error re-run the same function to generate a new one
public function randomId(){
$id = \Str::random(10);
$validator = \Validator::make(['id'=>$id],['id'=>'unique:table,col']);
if($validator->fails()){
return $this->randomId();
}
return $id;
}
From what I understand of your question, you could achieve this using a created event on the model. This will allow you to add anything to the model before it is persisted in the database without any further interaction required.
In a service provider, or your App\Providers\AppServiceProvider add the event to the boot method.
public function boot()
{
User::creating(function ($user) {
// When ever a User model is created
// this event callback will be fired.
$user->setAttribute('randomString', str_random(10));
// Returning 'false' here will stop the
// creation of the model.
});
}
Full documentation for eloquent model events.
PHP 7 standard library provides the random_bytes($length) function that generate cryptographically secure pseudo-random bytes.
Example:
$bytes = random_bytes(20);
var_dump(bin2hex($bytes));
The above example will output something similar to:
string(40) "5fe69c95ed70a9869d9f9af7d8400a6673bb9ce9"
More info: http://php.net/manual/en/function.random-bytes.php
PHP 5 (outdated)
I was just looking into how to solve this same problem, but I also want my function to create a token that can be used for password retrieval as well. This means that I need to limit the ability of the token to be guessed. Because uniqid is based on the time, and according to php.net "the return value is little different from microtime()", uniqid does not meet the criteria. PHP recommends using openssl_random_pseudo_bytes() instead to generate cryptographically secure tokens.
A quick, short and to the point answer is:
bin2hex(openssl_random_pseudo_bytes($bytes))
which will generate a random string of alphanumeric characters of length = $bytes * 2. Unfortunately this only has an alphabet of [a-f][0-9], but it works.
Below is the strongest function I could make that satisfies the criteria (This is an implemented version of Erik's answer).
function crypto_rand_secure(
max)
{
$range =
min;
if ($range < 1) return $min; // not so random...
$log = ceil(log($range, 2));
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
rnd & $filter; // discard irrelevant bits
} while (
range);
return
rnd;
}
function getToken($length)
{
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet); // edited
for (
i < $length; $i++) {
$token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
}
return $token;
}
crypto_rand_secure( works as a drop in replacement for max)
rand() or mt_rand. It uses openssl_random_pseudo_bytes to help create a random number between max.
getToken($length) creates an alphabet to use within the token and then creates a string of length $length.
Source: https://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
Security Notice: This solution should not be used in situations where the quality of your randomness can affect the security of an application. In particular,
rand()anduniqid()are not cryptographically secure random number generators. See Scott's answer for a secure alternative.
If you do not need it to be absolutely unique over time:
md5(uniqid(rand(), true))
Otherwise (given you have already determined a unique login for your user):
md5(uniqid($your_user_login, true))
str_random (Str::random()) tries to use openssl_random_pseudo_bytes which is a pseudo random number generator optimized for cryptography, not uniqueness. If openssl_random_pseudo_bytes is not available, it falls back to quickRandom():
public static function quickRandom($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}
In my opinion quickRandom code is not reliable for uniqueness nor cryptography.
Yes, having openssl_random_pseudo_bytes and using 32 bytes is almost impossible to see a collision, but it's still possible. If you want to make sure your strings/numbers will be unique (99.99%), you better use a UUID function. This is what I normally use:
/**
*
* 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)
);
}
It generates a VALID RFC 4211 COMPLIANT version 4 UUID.
Check this: https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions
you can use this
use Illuminate\Support\Str;
$random = Str::random(40);