say if I wanted to give every user that registered on my site a unique id. It seems to me that if I wanted to do this I would have to: Create a random number for the id, check to see if that id already exists in the database, if it does exist then create another random number and send yet another query to see if that exists, and so on...
This could go on for ages. Apart from having an incrementing id, is there any decent way to do this?
The best way to do this is via the auto increment function, if you really don't want to use a function like so you could use uniqid();
Basically you it generates an unique id based on milliseconds, if you put in a kinda unique prefix in the function it will generate a very unique id.
echo uniqid('prefix');
This way you won't have to check after generating an id, if it already exists or not. You can be sure it is unique.
For more information check this url http://php.net/uniqid!
First of all, I agree with the comments. It's all overhead code, and if you're using it to make it look interesting you should really reconsider your priorities.
But, if you still need it; here's a little something:
function uid() {
mt_srand((double)microtime()*1000000);
$token = mt_rand(1, mt_getrandmax());
$uid = uniqid(md5($token), true);
if($uid != false && $uid != '' && $uid != NULL) {
$out = sha1($uid);
return $out;
} else {
return false;
}
}
Basically, it does a lot of random number generating to create a token for uniqueid, and then is sha's that. Probably overhead, but you can be sure that you never generate a double uid.
Fabian.
You can use the rand() function. It will generate a random number between two.
rand(0000,9999)
It will generate a number between 0 and 9999.
To check if it already exist:
$id = rand(0000,9999);
/* CREATE YOUR MYSQL CONNECTION */
$user_list = mysql_query("SELECT * FROM users");
while ($user = mysql_fetch_array($user_list))
{
if ($id == $user['id'])
{
echo('Already exist.');
}
else
{
/* YOUR CODE */
}
}
It's the way I did it...
If you have a string of 15 numbers you are looking at up to 999 trillion, I doubt it will run for "ages" considering there's almost 7 billion people on the planet.
Does the ID need to be numeric? By switching to alphabetic characters you will get a lot more entropy. A 6 digit number is 1,000,000 posibilities, a 6 character alphanumeric string is 2,176,782,336 possibilities. Make it mixed case alphanumeric and that jumps to 15,625,000,000.
Here's how I usually generate unique strings that are as short as possible:
$chars = 'abcdefghijklmnopqrstuvwrxyzABCDEFGHIJKLMNOPQRSTUVWRXYZ0123456789';
mt_srand((double)microtime()*1000000);
$id = '';
do {
$id .= $chars[mt_rand(0, strlen($chars) - 1)];
} while (isIdTaken($id));
var_dump($id);
You have to create a lot of items with this style of id, before you'll get to more than 3 or 4 characters.
I know it's late for this answer but the easiest solution is to generate random number and sure it will be unique 100% is
$uid = uniqid().date("Ymdhhis");
Related
I am using random number function in php. If browser loads or refresh, rand() generates new random number. But I need, if rand() generates a random number first time, after that, if browser loads then random number should not replace old one. Means I want first random number in session.
My code is:
$globalvari = rand();
$_SESSION['globalvari'] = $globalvari;
if ($_SESSION['globalvari'] != '') {
$globalvari1 = $_SESSION['globalvari'];
echo $globalvari1;
}
But it replace old one.
Try this
if(!empty($_SESSION['globalvari']) || (isset($_SESSION['globalvari']) && $_SESSION['globalvari'] === 0)){
$globalvari1=$_SESSION['globalvari'];
echo $globalvari1;
}else{
$globalvari=rand();
$_SESSION['globalvari']=$globalvari;
}
You're setting it every reload. So it has to be in the else condition. Also, use empty because it doesn't care if the index is set in the array or not.
Last empty will trip up on int(0), so you can bypass that with a simple OR and strict comparison.
Rand() A random integer between min (or 0) and max (or getrandmax() inclusive)
Or you can set a range that does not include 0
You should code like this :
if(!isset($_SESSION['globalvari'])){// Checks that `$_SESSION['globalvari']` exist. If not exist then below code create `$_SESSION['globalvari']` variable
$globalvari=rand();
$_SESSION['globalvari']=$globalvari;
}
$globalvari1=$_SESSION['globalvari'];
echo $globalvari1;
I am creating short 5 character hashes to make unique classrooms for my students... a typical hash will look like AJ678.
I am generating the hash like this:
public function generateToken($length = 5)
{
return strtoupper(substr(md5(rand()), 0, $length));
}
I am expecting many thousands of classrooms to be generated over the lifetime of the app... so eventually there will be a clash... I want to know how to make sure that every hash will be unique.
I have make the token field a unique field.
I would think that the best way to do this would be to generate the hash, then check if the hash already exists in my database, if it does then generate a new hash, else use the hash.
Is that the correct way to go about this?
EDIT: I am a bit insecure about implementing a function that calls itself... does this look right?
public function generateToken($length = 5)
{
$token = strtoupper(substr(md5(rand()), 0, $length));
if ($this->tokenExistsAlready($token)) {
$this->generateToken();
} else {
return $token;
}
}
public function tokenExistsAlready()
{
$this->db->where('token', $token);
$query = $this->db->get('classes');
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
First, define "unique". Unique in our terms is a string of any length, that does not yet exist in your database.
This pretty much answers your question. You can never be sure, that your string is unique, unless you check it against your database. The longer the string, the slimmer the chance. So in your case, I would have created a while loop checking the database. Starting with the second string you save in the database, you might (and probably will later down the timeline) hit two randomly generated strings in a row. So checking the uniqueness in a loop until you find the "unique" one is a good idea. Something abstract like this:
$token = generateToken();
while(tokenExists($token))
{
$token = generateToken();
}
Keep in mind, that nothing guarantees true uniqueness of a string. You may use the MySQL UUID() or UUID_SHORT(), PHP uniqid() or anything else, that generates a random string. But it still does not guarantee the said uniqueness unless you check it against the existing database.
use uniqid() function
public function generateToken($length = 5)
{
return strtoupper(substr(uniqid(md5(rand()), 0, $length)));
}
Can the token be simply a unique integer? That would be easy to generate with a table with a single, AUTO_INCREMENT, column.
This question already has answers here:
How to generate a random, unique, alphanumeric string?
(31 answers)
Closed 7 years ago.
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.
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.
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.
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.
I'm trying to obfuscate the URLs to the pages where content is displayed. Content pages are displayed by getting the content id number as a GET variable in the URL. I want to obfuscate the URL (as is described by this SO post). I tried the methods in both answers but one method gave overly long codes, and the other gave overly predictable codes.
I'm working in PHP, and I'm using a MySQL table to store content; the content id is an automatically incrementing column. This means that if I didn't obfuscate my URLs users would be able to see in the URL exactly how many posts there are on the website, and could change the URL to see different posts. I want to avoid this.
I was hoping to have obfuscation similar to Imgur.com: their content ID codes are each a 5-character code containing letters, capital letters and lowercase letters.
To avoid needing to do a bunch of "encrypting" and "decrypting" you can use a unique key-pair for each page. Add another field (VARCHAR 5) to your pages table called key and then randomly generate a key for each page.
To generate the key you could crypt a random number
function random_key(){
$crypt = crypt(rand(0,9999999), 'Whatever you want to say here.');
return substr($crypt, 0, 5);
}
Which would result in a URL like ?page=55-so3ph (?page={$id}-{$key})
And then to use it you can do something like
<?php
if(empty($_GET['page']))
die('missing ?page');
$page = explode('-', $_GET['page']);
if(count($page) != 2)
die('invalid ?page');
list($page_id, $page_key) = $page;
if(!is_numeric($page_id))
die('invalid page id');
$Post = your_query_method('SELECT * FROM pages WHERE id = ' . $page_id . ' AND key = "' . your_escape_function($page_key) . '"');
if(!$Post){
header('Location: /invalid_page.html');
exit;
}
//At this point we know that they ID key pair is correct
For a super simple solution that does not really prevent people from reverse engineering your URLs but will deter 99.9999% of users you can do something like
<?php
function hash_id($id){
$crypt = crypt($id, 'Whatever you want to say here. Just SALT it!');
$md5 = md5($crypt . 'You can do another SALT here.');
return substr($md5, 0, 5);
}
if(empty($_GET['page']))
die('missing ?page');
$page = explode('-', $_GET['page']);
if(count($page) != 2)
die('invalid ?page');
list($page_id, $page_key) = $page;
if(!is_numeric($page_id))
die('invalid page id');
$Page = your_function_to_get_page_by_id($page_id);
if(!$Page || hash_id($page_id) != $page_key){
header('Location: /invalid_page.html');
exit;
}
//the URL would look like ?page=55-so3ph
Between crypt and md5 with salts, it would take somebody with a super computer a good chunk of time to start finding the collisions.
What I've ended up doing is quite simple: I cipher the number (ensuring that the output of the cipher is within a certain range) then I convert the number to base 62.
I chose base 62 because the characters in base 62 are numerics, capital alphabets, and lowercase alphabets. I ensured the output of the cipher was within a certain range so that when converted to base 62 it would have a certain number of digits (in my case I chose six digits in base 62).
To reverse the code, I convert it back to base 10 and reverse the cipher.
I want to create a less than or equal to 10 character unique string for an input string which could be a url
http://stackoverflow.com/questions/ask
OR an alpha numeric string
programming124
but the result should be unique for every input...Is their any function or class that you use for your projects in php... Thanks...
If you want a unique and random string, you can use the following function to create a random string:
function randString($length) {
$charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$str = '';
while ($length-- > 0) {
$str .= $charset[rand() % 62];
}
return $str;
}
After you have generated a new string, look up your database if that string already exists. If so, repeat that step until you’ve generated a unique string. Then store that new string in the database:
do {
$randString = randString(10);
// look up your database if $randString already exists and store the result in $exists
} while ($exists);
// store new random string in database
The simplest function available in php is uniqid. It is a little longer that you had mentioned, and wont work well with load balancing, but if you are doing something super simple, it should work alright.