I am generating random numbers using php random function, but I want the generated number should be unique and it should not be repeated again.
----------
php code
$number = rand(100,100000); //a six digit random number between 100 to 100000
echo $number;
----------
but I am using this function for multiple times in my code for users so at very rare case there should be a chance of generating same number again. how can i avoid that.
I would do this:
You said you have branches. The receipt id could look something like this:
$dateString = date('Ymd'); //Generate a datestring.
$branchNumber = 101; //Get the branch number somehow.
$receiptNumber = 1; //You will query the last receipt in your database
//and get the last $receiptNumber for that branch and add 1 to it.;
if($receiptNumber < 9999) {
$receiptNumber = $receiptNumber + 1;
}else{
$receiptNumber = 1;
}
Update the receipt database with the receipt number.
$dateString . '-' . $branchNumber . '-' . $receiptNumber;
This will read:
20180406-101-1
This will be unique(Provided you do less than 10,000 transactions a day.) and will show your employees easily readable information.
If you are storing users in DB you should create column [ID] as primary key with auto increment and that would be best solution.
In other case I'd recommend you to simply store all user id's in ascending order from N to M by reading last ID and adding 1 to it because I see no real gain from random order that only adds complexity to your code.
There are many ways, example:
$freq = [];
$number = rand(100,100000);
$times = 10;
while($times-- > 0)
{
while(in_array($number, $freq))$number = rand(100,100000);
$freq[] = $number;
echo $number . "<br>";
}
This will print 10 random unique numbers.
random_int
(PHP 7)
<?php
$number = random_int(100, 100000);
echo $number;
All you need to do is use timestamp in php as timestamp never cross each other hence it will always generate unique number.You can use time() function in php.
The time() function is used to format the timestamp into a human desired format. The timestamp is the number of seconds between the current time and 1st January, 1970 00:00:00 GMT. It is also known as the UNIX timestamp.
<?php
$t=time();
echo $t;
?>
Also you add a rand() function and insert it in front of the $t to make it more random as if few users work at same time then the timestamp might collide.
<?php
$number = rand(100,100000);
$t=time();
$random = $number.''.$t;
echo $random;
?>
The above will reduce the chance to timestamp collide hence making the probability of number uniqueness almost 100%.
And if you make your column unique in your database then the php wont insert the number hence this bottleneck will ensure you will always get a unique random number.
bill_id not null unique
If you are using it for something like user id, then you can use uniqid for that. This command gets a prefixed unique identifier based on the current time in microseconds.
Here's how to use it:
string uniqid ([ string $prefix = "" [, bool $more_entropy = FALSE]] )
Where prefix is used if you are generating ids for a lot if hosts at the same time, you can use this to differentiate between various hosts if id is generated at the same microsecond.
more_entropy increases the likeness of getting unique values.
Usage:
<?php
/* A uniqid, like: 4b3403665fea6 */
printf("uniqid(): %s\r\n", uniqid());
/* We can also prefix the uniqid, this the same as
* doing:
*
* $uniqid = $prefix . uniqid();
* $uniqid = uniqid($prefix);
*/
printf("uniqid('php_'): %s\r\n", uniqid('php_'));
/* We can also activate the more_entropy parameter, which is
* required on some systems, like Cygwin. This makes uniqid()
* produce a value like: 4b340550242239.64159797
*/
printf("uniqid('', true): %s\r\n", uniqid('', true));
?>
this code must work
some description about code:
generate unique id
extract numbers form unique id with regex
gathering numbers from regex with a loop
<?php
$unique = uniqid("",true);
preg_match_all("!\d+!", $unique ,$matches);
print_r($matches);
$numbers = "";
foreach($matches[0] as $key => $num){
$numbers .= $num;
}
echo $numbers;
Related
I'm currently searching for a good way to generate a unique random number for SEPA transactions (End-to-End reference) with 27 digits in PHP. My requirements are:
Must be unique
Only int values, no letters
Length of 27 digits
Use an user id and time to make the ID unique
I've tried this solution here but this only gives me a string with letters and numbers:
md5( uniqid( mt_rand(), true ) );
Does anyone has a lightweight solution or idea?
echo $bira = date('YmdHis').rand(1000000000000,9000000000000);
echo "<br/>";
echo strlen($bira);
Add the time stamp in the front, so it will be unique always.
OR echo $bira = time().rand(10000000000000000,90000000000000000);
outoput:
201901220142532979656312614
27
How about this:
$array = [];
$numberOfTransactions = 1;
while (count($array) < $numberOfTransactions) {
$rand = mt_rand(100000000000000000000000000, 999999999999999999999999999);
$array[$rand] = $rand;
}
print_r($array);
Associative array keys are unique, so you won't get any duplicates.
I want to create user accounts with a public_id which is always a unique, integer random (not incremental) value.
I can use loops to check if the random integer is unique, but that doesn't seem like a really nice solution.
I found some alphabetic-numeric generators, and I guess I could convert them to integers using some string to integer converter, but are there an integer -specific ways?
I also worry about possible collisions, but it looks like the chance will be always there in a long run.(?)
You can either use one of native php functions like mt_rand or use more reliably way - generating integer based on microtime function.
To ensure that the value is unique you need to add a unique index on a column in DB and write 'ON DUPLICATE UPDATE' to insert/update queries which will add some digits to the value if it is not unique
There are 2 possible solutions:
1) If your "long run" is really really long - it means this is
possible, that you are out of PHP_INT_MAX and there is no
only-integer-specific way.
2) If you are not out of PHP_INT_MAX - then you need some storage for
checking the ids.
In case of 1 you can use library hashids. To avoid collisions - you'll need some incremental counter on input. Then you can convert strings by each letter back to integer.
In case of 2 - you can use some in-memory database like redis for performance.
Using timeStamp will really do a great job since it uses time to generate it random numbers .you can also concatenate the below function with other random generated numbers.
function passkey($format = 'u', $utimestamp = null){
if (is_null($utimestamp)) {
$utimestamp = microtime(true);
}
$timestamp = floor($utimestamp);
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format),$timestamp);
}
echo passkey(); // 728362
You can use a linear congruential generator with a large period.
Here is one that generates unique integers which always have 6 digits. It will not generate duplicates until it has generated all numbers between 100000 and 996722, which gives you almost 900 000 different numbers.
The condition is that you can provide the function the number it last generated. So if you store the number in the database, you have to somehow retrieve the last assigned one, so you can feed it to this function:
function random_id($prev) {
return 100000 + (($prev-100000)*97 + 356563) % 896723;
}
$prev = 100000; // must be a 6 digit number: the initial seed.
// Generate the first 10 pseudo-random integers.
for ($i = 0; $i < 10; $i++) {
$prev = random_id($prev);
echo $prev . "\n";
}
The above generation of the first 10 numbers yields:
456563
967700
331501
494085
123719
963860
855744
232445
749606
697735
You can do this for other ranges by following the rules in the referenced article on getting a full period in linear congruential generators. Concretely, if you want to generate numbers with n digits, where the first digit cannot be zero (so between 10n-1 and 10n-1), then I find it easiest to find a large prime just below 9⋅10n-1 to serve as the last number of the formula. The other two numbers can then be any positive integer, but better keep the first one small to avoid overflow.
However, PHP integers are limited to PHP_INT_MAX (typically 2147483647), so for numbers with 10 or more digits you will need to use floating point operators. The % operator should not be used then. Use fmod instead.
For example, to generate numbers with 12 digits, you could use this formula:
function random_id($prev) {
return 100000000000 + fmod((($prev-100000000000)*97 + 344980016453), 899999999981);
}
$prev = 100000000000; // must be a 12 digit number: the initial seed.
// Generate the first 10 pseudo-random integers.
for ($i = 0; $i < 10; $i++) {
$prev = random_id($prev);
echo $prev . "\n";
}
I want to generate unique identificator in following 12 numeric format:
YYYYMMDDXXXX
Example:
201403052318
Where:
YYYYMMDD is a current date value and other XXXX is randomly generated value.
$today = date("Ymd");
$rand = sprintf("%04d", rand(0,9999));
$unique = $today . $rand;
Daily required unique volume is about 100. What methods using PHP should I use to prevent possible duplicates in rand values or make all id maximum unique? Maybe possible use current time functions to compact these numbers in last 4 characters?
EDITED:
Unique value connected to MySQL database as prime index of table. It is initial values not connected to any stored information in database.
You can't rely on rand() , There is a possibility you will generate a duplicate (Pretty rare for a rand(0,9999) to generate a duplicate, but that will at some point).
So instead of going for rand(), just create an incremental value (say.. starting from 1) and append to your generated date.
Next time when you regenerate a new id, grab that incremental value's (say if you had stored it somewhere.. must be 1 right ?) status, increment it and append it to your new date.
Not an ideal solution.. (Critics welcome)
You can make use of a uniqid coupled with sha-1 and time and do a substr() on them for first 4 chars.
<?php
$today = date("Ymd");
$rand = strtoupper(substr(uniqid(sha1(time())),0,4));
echo $unique = $today . $rand;
OUTPUT :
201403094B3F
I needed to do something similar, a solution that would keep time and also keep the id unique and i ended up with a solution to use PHP function time() like this
$reference_number = 'BFF-' . time(); you can change the BFF to something that makes more sense to your business logic.
My unique reference id looks like BFF-1393327176 and the number can be converted from Unix to real time which will give you, Tue, 25 Feb 2014 11:19:36
I hope this helps
If the unique values generated once, you just need to make conditional choice for the rand value and store the value in an array which is going to be the condition -using inarray-:
$amount = 100; // the amount of ids
$previousValues = array();
for ($i = 0; $i < $amount; $i++){
$rand = rand(0,9999);
while (in_array($rand, $previousValues)){
$rand = rand(0, 9999);
}
$previousValues[] = $rand;
$today = date("Ymd");
$unique = $today.$rand;
echo $unique."\n";
}
Checkout this demo.
A possible solution for creating unique "Unique Order Number" is following, I assume that you have orders table and field order_number, then the code is:
$orderNumber = DB::table('orders')->max('order_number') + random_int(10, 100);
If first order number is inserted as "100000000000" that method will give you this numbers:
100000000025
100000000056
100000000089
100000000123
100000000199
100000000232
100000000249
with that approach there is no possibility for non-unique number, but cons is that each number is greater the previous (not 100% random) but that approach is acceptable for most of the cases.
This code creates a new random number each second.
srand(floor(time() / (1)));
echo rand(0,5);
How can it echo random numbers (0-5) uniquely, and then cycle?
For example, I'd love to get a sequence like this:
1,5,4,3,2,1,4,5,3,2,5,4,1,2,3...
Rather than this:
2,2,1,4,3,4,5,5,5,5,5,1,2,3,4...
(Just to clarify, the second gap is important, and you're to assume there's been a one second delay between each page load. Each page load results in a random number)
do you want to get rid of sequences like "2,2" and "5,5,5,5"? it's possible only if you store previous number somewhere, e.g. in $_SESSION superglobal var:
session_start();
$ran_num = rand(0, 5);
while ($ran_num == $_SESSION['ran_num']) {
$ran_num = rand(0, 5);
}
$_SESSION['ran_num'] = $ran_num;
echo $ran_num;
Is there is any way to avoid duplication in random number generation .
I want to create a random number for a special purpose. But it's should be a unique value. I don't know how to avoid duplicate random number
ie, First i got the random number like 1892990070. i have created a folder named that random number(1892990070). My purpose is I will never get that number in future. I it so i have duplicate random number in my folder.
A random series of number can always have repeated numbers. You have to keep a record of which numbers are already used so you can regenerate the number if it's already used. Like this:
$used = array(); //Initialize the record array. This should only be done once.
//Do like this to draw a number:
do {
$random = rand(0, 2000);
}while(in_array($random, $used));
$used[] = $random; //Save $random into to $used array
My example above will of course only work across a single page load. If it should be static across page loads you'll have to use either sessions (for a single user) or some sort of database (if it should be unique to all users), but the logic is the same.
You can write a wrapper for mt_rand which remembers all the random number generated before.
function my_rand() {
static $seen = array();
do{
$rand = mt_rand();
}while(isset($seen[$rand]));
$seen[$rand] = 1;
return $rand;
}
The ideas to remember previously generated numbers and create new ones is a useful general solution when duplicates are a problem.
But are you sure an eventual duplicate is really a problem? Consider rolling dice. Sometimes they repeat the same value, even in two sequential throws. No one considers that a problem.
If you have a controlled need for a choosing random number—say like shuffling a deck of cards—there are several approaches. (I see there are several recently posted answer to that.)
Another approach is to use the numbers 0, 1, 2, ..., n and modify them in some way, like a Gray Code encoding or exclusive ORing by a constant bit pattern.
For what purpose are you generating the random number? If you are doing something that generates random "picks" of a finite set, like shuffling a deck of cards using a random-number function, then it's easiest to put the set into an array:
$set = array('one', 'two', 'three');
$random_set = array();
while (count($set)) {
# generate a random index into $set
$picked_idx = random(0, count($set) - 1);
# copy the value out
$random_set []= $set[$picked_idx];
# remove the value from the original set
array_splice($set, $picked_idx, 1);
}
If you are generating unique keys for things, you may need to hash them:
# hold onto the random values we've picked
$already_picked = array();
do {
$new_pick = rand();
# loop until we know we don't have a value that's been picked before
} while (array_key_exists($new_pick, $already_picked));
$already_picked[$new_pick] = 1;
This will generate a string with one occurence of each digit:
$randomcharacters = '0123456789';
$length = 5;
$newcharacters = str_shuffle($randomcharacters);
$randomstring = substr($newcharacters, 0, $length);