I use the following method to pad out a ID for a property on our website:
function generateAgentRef($id,$length=5,$strPrefix='1'){
return $strPrefix . str_pad($id,$length,0,0);
}
Basically it will prefix 1 and then pad out the id with 0's until the string reaches $length.
But, I now have a requirement to revert this process. For example if I have the following IDs: 100650,100359,100651,100622,100112,100687, how can I get the ID e.g. 650, 359, 651, 622, 112, 687?
Hope this explains what I'm trying to achieve.
The ID in the database will never start with 0, so I was thinking of iterating over the components of the string and detecting when I hit something other than 0 and then splitting the string.
substract 100000 from the generated ref and intval() it could work if the length is 6 numbers exactly.
try using this
$a = substr($num,3);
here $num is the id you get
$a will be your desired number i.e 100659 shortened to 659
Expanding on your initial function
function getAgentId($id, $length = 5, $strPrefix = 1){
return $id - generateAgentRef(0, $length, $strPrefix);
}
$id = generateAgentRef(255);
echo $id, PHP_EOL; // 100255
echo getAgentId($id), PHP_EOL; //255
Related
So, I,been trying to write a code for a "Dice generator" and I want it to generate random numbers (from 1-6) a x numbers of times.
The x number of times is given as a parameter by the user through the terminal, with this "$argc argv" function, but this is not really important.
What I want to know is: how do I generate random values x number of times?
FOR EXAMPLE:
User input: 4
Output: 5 3 6 8
User input: 3
Output: 5 1 2
This is what I am trying to write. I used the array_rand function with the array as a parameter, and the number of times I want as the second parameter, but It does not work! What am I not getting here?
<?php
if ($argc < 2) {
print "You have to write at least one parameter" .PHP_EOL;
exit(1);
}
//This is the variable that corresponds to the number of times the user will give on the Terminal as a parameter.
//$randoms = $argv[1];
$num = 3;
$diceNumbers = [1, 2, 3, 4, 5, 6];
$keys = array_rand($diceNumbers, $num);
print $diceNumbers[$keys[0]]." ".$diceNumbers[$keys[1]] .PHP_EOL;
?>
Given your use case is for a 'dice roll' I wonder if you would be better off using a cryptographically secure random number generation function like random_int() rather than array_rand(), which is not.
You can then use a for loop for your output as you know in advance how many times you want the loop to run.
$num = 3;
for($i = 0; $i < $num; $i++){
print random_int(1,6) . PHP_EOL;
}
The array_rand(arry, n) function returns an array with length n, composed of elements from arry. It looks like you did everything right, however when you print it you only ask for the first 2 random numbers. If you want to print all of the numbers, you will need a for/foreach loop.
foreach($keys as $key) {
print $key . " ";
}
In my database field i have varchar field like this format HPDO1209180000.What i am doing is if i dont have any data i am adding four digits at last it is working fine.And if if it is there i am incrementing one each time.but the problem is after 0001 also incrementing all the 0001 only not 0002 like that.I am doing like this please help me.thanks in Advance.
$this->db->select('grmno');
$this->db->from('procurement_receive_material');
$this->db->where('DATE(createdon)',$currentdate);
$this->db->where('SUBSTRING(grmno,1,10)',$grn_code);
$this->db->order_by('prmid','desc');
$query = $this->db->get();
if($query->num_rows()>0){
$output = $query->row();
$grmNumber = $output->grmno;
//after 0001 also it incrementing 0001 not incrementing;
$inrno=str_pad((int)$grmNumber+1, 4, 0, STR_PAD_LEFT);
$grmNumber=$vendor_result.$branch_result.$currentDate.$currentmonth.$currentyear.$inrno;
}else{
$grmNumber = $vendor_result.$branch_result.$currentDate.$currentmonth.$currentyear.'0000';
}
If I'm reading this correctly, it looks like this line:
$inrno=str_pad((int)$grmNumber+1, 4, 0, STR_PAD_LEFT);
Is taking the int value of $output->grmno. And this field, again if I'm interpreting your problem directly, can be evaluated as something like this:
HPDO1209180001
The integer value of such a string would be 0. Hence, why they always end up as 0001.
To fix this, you need to grab the last 4 characters of the string, and increment only that. For example:
$suffix = substr($grmNumber, -4);
$newsuffix = intval($suffix) + 1;
$irno = str_pad($newsuffix, 4, 0, STR_PAD_LEFT);
This would properly grab the last 4 digits, add one to the value, and again pad it with zeros to be added to the new string.
What would be an elegant way of doing this?
I have this -> "MC0001" This is the input. It always begins with "MC"
The output I'd be aiming with this input is "MC0002".
So I've created a function that's supposed to return "1" after removing "MC000". I'm going to convert this into an integer later on so I could generate "MC0002" which could go up to "MC9999". To do that, I figured I'd need to loop through the string and count the zeros and so on but I think I'd be making a mess that way.
Anybody has a better idea?
This should do the trick:
<?php
$string = 'MC0001';
// extract the part succeeding 'MC':
$number_part = substr($string, 2);
// count the digits for later:
$number_digits = strlen($number_part);
// turn it into a number:
$number = (int) $number_part;
// make the next sequence:
$next = 'MC' . str_pad($number + 1, $number_digits, '0', STR_PAD_LEFT);
using filter_var might be the best solution.
echo filter_var("MC0001", FILTER_SANITIZE_NUMBER_INT)."\n";
echo filter_var("MC9999", FILTER_SANITIZE_NUMBER_INT);
will give you
0001
9999
These can be cast to int or just used as they are, as PHP will auto-convert anyway if you use them as numbers.
just use ltrim to remove any leading chars: http://php.net/manual/en/function.trim.php
$str = ltrim($str, 'MC0');
$num = intval($str);
<php
// original number to integer
sscanf( $your_string, 'MC%d', $your_number );
// pad increment to string later on
sprintf( 'MC%04u', $your_number + 1 );
Not sure if there is a better way of parsing a string as an integer when there are leading zero's.
I'd suggest doing the following:
1. Loop through the string ( beginning at location 2 since you don't need the MC part )
2. If you find a number thats bigger than 0, stop, get the substring using your current location and the length of the string minus your current location. Cast to integer, return value.
You can remove the "MC" par by doing a substring operating on the string.
$a = "MC0001";
$a = substr($a, 2); //Lengths of "MC"
$number = intval($a); //1
return intval(str_replace($input, 'MC', ''), 10);
how does the "tiny url" sites get so tiny ID url ?
i mean this : blabla.com/JH7
how can i get to such result? a functionality that is like md5 that does not repeat it self.
thanks in advance!
For example you can simply iterate trough string:
php > $str = 'aaa';
php > $str++;
php > echo $str;
aab
The another option is to prepare function which will generate random strings containing of a-zA-Z0-9 and than generate few millions of them into db (so you could just use them when needed) or do it in loop:
while( 1){
$rand = randomString();
if( isUnique( $rand)){
break;
}
}
Make a database table with the columns short_url and url.
Start by inserting the record a, example.com.
Increment short_url with each new entry (b, c, ..., a1 ...).
That's basically how these services work.
They use base36 encoding to convert an integer to a compact string like that.
Using PHP:
<?php
$id = 18367;
$base36 = base_convert($id, 10, 36); // convert to base36 "e67"
$base10 = base_convert($base36, 36, 10); // "e67" back to base 10, $id
As stated by deceze, base62 is also suitable which gives you a character set of a-zA-Z0-9 instead of just a-z0-9 like base36 does.
I want to generate a unique 4-6 char long AlphaNumeric string to save in db with each record(user). The db field has a unique index, so trying to save a pre-existing string generates an error. Right now I am generating a random string and using try-catch, so when adding a new record if it throws an exception, I generate another random string and attempt to save again, and the code keep trying until it adds a record successfully. This whole solution not only looks heavy but also ugly, so I want to change it. I am interested in an elegant solution, so any help/guidance is welcome.
With the given information :
id must be unique
id must not be numeric
id must not represent a sequential series
id will not be input by the user
The PHP function uniqid is exactly what you need. Though it returns a 13 character long hexadecimal value.
** Edit **
Yes, uniqid will return a seamingly sequential number, but we can get around this easily. Consider this code
class IDGenerator {
//const BIT_MASK = '01110011';
static public function generate() {
$id = uniqid();
$id = base_convert($id, 16, 2);
$id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);
$chunks = str_split($id, 8);
//$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);
$id = array();
foreach ($chunks as $key => $chunk) {
//$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
if ($key & 1) { // odd
array_unshift($id, $chunk);
} else { // even
array_push($id, $chunk);
}
}
return base_convert(implode($id), 2, 36);
}
}
echo IDGenerator::generate();
Which will give results like
ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2
Since there is nothing added or modified, except shuffling the bits around, there should not be any duplicated values and everything seems random. VoilĂ !
** Update (2014-02-24) **
I update this piece of code since the time it was originally posted. You may find the revised version here