How to generate an alphanumeric incrementing id in PHP? - php

I have system in PHP in which I have to insert a Number which has to like
PO_ACC_00001,PO_ACC_00002,PO_ACC_00003.PO_ACC_00004 and so on
this will be inserted in Database for further reference also "PO and ACC" are dynamic prefix they could different as per requirement
Now my main concern is how can is increment the series 00001 and mantain the 5 digit series in the number?

>> $a = "PO_ACC_00001";
>> echo ++$a;
'PO_ACC_00002'

You can get the number from the string with a simple regex, then you have a simple integer.
After incrementing the number, you can easily format it with something like
$cucc=sprintf('PO_ACC_%05d', $number);

Create a helper function and a bit or error checking.
/**
* Takes in parameter of format PO_ACC_XXXXX (where XXXXX is a 5
* digit integer) and increment it by one
* #param string $po
* #return string
*/
function increment($po)
{
if (strlen($po) != 12 || substr($po, 0, 7) != 'PO_ACC_')
return 'Incorrect format error: ' . $po;
$num = substr($po, -5);
// strip leading zero
$num = ltrim($num,'0');
if (!is_numeric($num))
return 'Incorrect format error. Last 5 digits need to be an integer: ' . $po;
return ++$po;
}
echo increment('PO_ACC_00999');

Sprintf is very useful in situations like this, so I'd recommend reading more about it in the documentation.
<?php
$num_of_ids = 10000; //Number of "ids" to generate.
$i = 0; //Loop counter.
$n = 0; //"id" number piece.
$l = "PO_ACC_"; //"id" letter piece.
while ($i <= $num_of_ids) {
$id = $l . sprintf("%05d", $n); //Create "id". Sprintf pads the number to make it 4 digits.
echo $id . "<br>"; //Print out the id.
$i++; $n++; //Letters can be incremented the same as numbers.
}
?>

Related

PHP Decimal128 string formating

I am using MongoDB to store values as Decimal128 and using PHP with Twig to display them. My question is there a format the output with a thousands separator? I have tried using number_format, but that doesn't work because the value is a string not a int or float. I don't want to type cast the value because I want the value to be precision.
Examples:
1000.382 = 1,000.382
99.01 = 99.01
1900000 = 1,900,000
I wrote a function to do this. Still wondering if there is a better way to do it.
<?php
$n = '12345.001';
echo fNumString($n);
function fNumString ($number_string) {
$ex_num = explode('.', $number_string);
$whole_num_len = strlen($ex_num[0]);
$formated = '';
if ($whole_num_len > 3) {
for ($i = 0; $i < $whole_num_len; $i++) {
$formated .= $ex_num[0][$i];
if ((($whole_num_len - ($i + 1)) % 3) == 0 && $whole_num_len != ($i + 1))
$formated .= ',';
}
} else
$formated = $ex_num[0];
if (count($ex_num) == 2)
$formated .= '.' . $ex_num[1];
return $formated;
}
You could:
split the number string into integer and decimal parts using explode,
reverse the integer part using strrev,
add a thousands separator every 3 digits within that integer part using preg_replace,
reverse the integer part back using strrev,
return it concatenated with the decimal separator and the decimal part
Code:
function fNumString(string $numberString, string $decimalPoint = '.', string $thousandsSeparator = ','): string
{
[$integerPart, $decimalPart] = array_pad(explode('.', $numberString, 2), 2, null);
$integerPart = strrev(preg_replace('/\d{3}(?=\d)/', '\0' . $thousandsSeparator, strrev($integerPart)));
return $integerPart . ($decimalPart ? $decimalPoint . $decimalPart : '');
}
Demo: https://3v4l.org/m3jUC
Note: you could leave out the last 2 parameters of number_format, I like keeping them out for clarity (and in case they change the default values later for some reason).

Could not generate 6 digit random number including date time using PHP

I need one help . I need to generate random number including date and time using PHP. I am explaining my code below.
$random=generateRandom();
echo $random;
function generateRandom() {
$result = base_convert((float) rand() / (float) getrandmax() * round(microtime(true) * 1000),6, 36);
return $result;
}
The above function giving the 3 digit output. Here i need to generate up to 6 digit. Please help me.
Here it is with microtime :
$random=generateRandom();
echo $random;
function generateRandom() {
$numbers = str_split((string)(int)microtime(true));
shuffle($numbers);
$rand = '';
foreach (array_rand($numbers, 6) as $k) $rand .= $numbers[$k];
return $rand;
}
Conversion are here to eliminated the dot character.

Generate an id with fixed alpha numeric string and variable integer part php

I am trying to generate an id with fixed alphanumeric part and a varying 3 digit numeric part.
That is, the id will look like:
LAB-SER-420316-1415-000
LAB-SER-420316-1415-001
...
LAB-SER-420316-1415-010
LAB-SER-420316-1415-020
...
LAB-SER-420316-1415-110
LAB-SER-420316-1415-210
.....
My task is to generate this id's only once, that is repeating id has to be avoided. Also once the page is loaded, it should generate single id.This is like giving a bill number or something like that. I've created a function to generate this string upto a limit. But I need it to generate everytime the page is loaded.
Code:
<?php
function generatebillno()
{
$saved="LAB-SER-420316-1415-";
for($count = 0; $count <= 999; $count++)
{
$var= str_pad($count, 3, '0', STR_PAD_LEFT);
return $saved.$var;
}
}
echo generatebillno();
?>
Can anyone help me to do this. I am stuck here..
try this -
//fetch the max id (the last digit as number)
$sql = $mysqli->query('select max(cast(substring(demo_field, 21) as unsigned)) as digit,
demo_field from demo');
$res = $sql->fetch_assoc();
//check for empty valyues
if (empty($res['demo_field'])) {
$str = "LAB-SER-420316-1415";
$res['digit'] = 0;
} else {
$str = substr($res['demo_field'], 0, 19);
}
$dig = $res['digit'] + 1;
//add padding if needed
$dig= str_pad($dig, 3, '0', STR_PAD_LEFT);
$newStr = $str.'-'.$dig;
var_dump($newStr);

One-line PHP random string generator?

I am looking for the shortest way to generate random/unique strings and for that I was using the following two:
$cClass = sha1(time());
or
$cClass = md5(time());
However, I need the string to begin with a letter, I was looking at base64 encoding but that adds == at the end and then I would need to get rid of that.
What would be the best way to achieve this with one line of code?
Update:
PRNDL came up with a good suggestions which I ended up using it but a bit modified
echo substr(str_shuffle(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ),0, 1) . substr(str_shuffle(aBcEeFgHiJkLmNoPqRstUvWxYz0123456789),0, 31)
Would yield 32 characters mimicking the md5 hash but it would always product the first char an alphabet letter, like so;
However, Uours really improved upon and his answer;
substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1).substr(md5(time()),1);
is shorter and sweeter
The other suggestion by Anonymous2011 was very awesome but the first character for some reason would always either M, N, Y, Z so didn't fit my purposes but would have been the chosen answer, by the way does anyone know why it would always yield those particular letters?
Here is the preview of my modified version
echo rtrim(base64_encode(md5(microtime())),"=");
Rather than shuffling the alphabet string , it is quicker to get a single random char .
Get a single random char from the string and then append the md5( time( ) ) to it . Before appending md5( time( ) ) remove one char from it so as to keep the resulting string length to 32 chars :
substr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", mt_rand(0, 51), 1).substr(md5(time()), 1);
Lowercase version :
substr("abcdefghijklmnopqrstuvwxyz", mt_rand(0, 25), 1).substr(md5(time()), 1);
Or even shorter and a tiny bit faster lowercase version :
chr(mt_rand(97, 122)).substr(md5(time()), 1);
/* or */
chr(mt_rand(ord('a'), ord('z'))).substr(md5(time()), 1);
A note to anyone trying to generate many random strings within a second: Since time( ) returns time in seconds , md5( time( ) ) will be same throughout a given second-of-time due to which if many random strings were generated within a second-of-time, those probably could end up having some duplicates .
I have tested using below code . This tests lower case version :
$num_of_tests = 100000;
$correct = $incorrect = 0;
for( $i = 0; $i < $num_of_tests; $i++ )
{
$rand_str = substr( "abcdefghijklmnopqrstuvwxyz" ,mt_rand( 0 ,25 ) ,1 ) .substr( md5( time( ) ) ,1 );
$first_char_of_rand_str = substr( $rand_str ,0 ,1 );
if( ord( $first_char_of_rand_str ) < ord( 'a' ) or ord( $first_char_of_rand_str ) > ord( 'z' ) )
{
$incorrect++;
echo $rand_str ,'<br>';
}
else
{
$correct++;
}
}
echo 'Correct: ' ,$correct ,' . Incorrect: ' ,$incorrect ,' . Total: ' ,( $correct + $incorrect );
I had found something like this:
$length = 10;
$randomString = substr(str_shuffle(md5(time())),0,$length);
echo $randomString;
If you need it to start with a letter, you could do this. It's messy... but it's one line.
$randomString = substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1) . substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
echo $randomString;
I decided this question needs a better answer. Like code golf! This also uses a better random byte generator.
preg_replace("/[\/=+]/", "", base64_encode(openssl_random_pseudo_bytes(8)));
Increase the number of bytes for a longer password, obviously.
Creates a 200 char long hexdec string:
$string = bin2hex(openssl_random_pseudo_bytes(100));
maaarghk's answer is better though.
base_convert(microtime(true), 10, 36);
You can try this:
function KeyGenerator($uid) {
$tmp = '';
for($z=0;$z<5;$z++) {
$tmp .= chr(rand(97,122)) . rand(0,100);
}
$tmp .= $uid;
return $tmp;
}
I have generated this code for you. Simple, short and (resonably) elegant.
This uses the base64 as you mentioned, if length is not important to you - However it removes the "==" using str_replace.
<?php
echo str_ireplace("==", "", base64_encode(time()));
?>
I use this function
usage:
echo randomString(20, TRUE, TRUE, FALSE);
/**
* Generate Random String
* #param Int Length of string(50)
* #param Bool Upper Case(True,False)
* #param Bool Numbers(True,False)
* #param Bool Special Chars(True,False)
* #return String Random String
*/
function randomString($length, $uc, $n, $sc) {
$rstr='';
$source = 'abcdefghijklmnopqrstuvwxyz';
if ($uc)
$source .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if ($n)
$source .= '1234567890';
if ($sc)
$source .= '|##~$%()=^*+[]{}-_';
if ($length > 0) {
$rstr = "";
$length1= $length-1;
$input=array('a','b','c','d','e','f','g','h','i','j,''k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')
$rand = array_rand($input, 1)
$source = str_split($source, 1);
for ($i = 1; $i <= $length1; $i++) {
$num = mt_rand(1, count($source));
$rstr1 .= $source[$num - 1];
$rstr = "{$rand}{$rstr1}";
}
}
return $rstr;
}
I'm using this one to generate dozens of unique strings in a single go, without repeating them, based on other good examples above:
$string = chr(mt_rand(97, 122))
. substr(md5(str_shuffle(time() . rand(0, 999999))), 1);
This way, I was able to generate 1.000.000 unique strings in ~5 seconds. It's not THAT fast, I know, but as I just need a handful of them, I'm ok with it. By the way, generating 10 strings took less than 0.0001 ms.
JavaScript Solution:
function randomString(pIntLenght) {
var strChars = “0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz”;
var strRandomstring = ”;
for (var intCounterForLoop=0; intCounterForLoop < pIntLenght; intCounterForLoop++) {
var rnum = Math.floor(Math.random() * strChars.length);
strRandomstring += strChars.substring(rnum,rnum+1);
}
return strRandomstring;
}
alert(randomString(20));
Reference URL : Generate random string using JavaScript
PHP Solution:
function getRandomString($pIntLength = 30) {
$strAlphaNumericString = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;
$strReturnString = ”;
for ($intCounter = 0; $intCounter < $pIntLength; $intCounter++) {
$strReturnString .= $strAlphaNumericString[rand(0, strlen($strAlphaNumericString) - 1)];
}
return $strReturnString;
}
echo getRandomString(20);
Reference URL : Generate random String using PHP
This function returns random lowercase string:
function randomstring($len=10){
$randstr='';
for($iii=1; $iii<=$len; $iii++){$randstr.=chr(rand(97,122));};
return($randstr);
};
I find that base64 encoding is useful for creating random strings, and use this line:
base64_encode(openssl_random_pseudo_bytes(9));
It gives me a random string of 12 positions, with the additional benefit that the randomness is "cryptographically strong".
to generate strings consists of random characters, you can use this function
public function generate_random_name_for_file($length=50){
$key = '';
$keys = array_merge(range(0, 9), range('a', 'z'));
for ($i = 0; $i < $length; $i++) {
$key .= $keys[array_rand($keys)];
}
return $key;
}
It really depends on your requirements.
I needed strings to be unique between test runs, but not many other restrictions.
I also needed my string to start with a character, and this was good enough for my purpose.
$mystring = "/a" . microtime(true);
Example output:
a1511953584.0997
How to match the OPs original request in an awful way (expanded for readability):
// [0-9] ASCII DEC 48-57
// [A-Z] ASCII DEC 65-90
// [a-z] ASCII DEC 97-122
// Generate: [A-Za-z][0-9A-Za-z]
$r = implode("", array_merge(array_map(function($a)
{
$a = [rand(65, 90), rand(97, 122)];
return chr($a[array_rand($a)]);
}, array_fill(0, 1, '.')),
array_map(function($a)
{
$a = [rand(48, 57), rand(65, 90), rand(97, 122)];
return chr($a[array_rand($a)]);
}, array_fill(0, 7, '.'))));
One the last array_fill() would would change the '7' to your length - 1.
For one that does all alpha-nurmeric (And still slow):
// [0-9A-Za-z]
$x = implode("", array_map(function($a)
{
$a = [rand(48, 57), rand(65, 90), rand(97, 122)];
return chr($a[array_rand($a)]);
}, array_fill(0, 8, '.')));
The following one-liner meets the requirements in your question: notably, it begins with a letter.
substr("abcdefghijklmnop",random_int(0, 16),1) . bin2hex(random_bytes(15))
If you didn't care whether the string begins with a letter, you could just use:
bin2hex(random_bytes(16))
Note that here we use random_bytes and random_int, which were introduced in PHP 7 and use cryptographic random generators, something that is important if you want unique strings to be hard to guess. Many other solutions, including those involving time(), microtime(), uniqid(), rand(), mt_rand(), str_shuffle(), array_rand(), and shuffle(), are much more predictable and are unsuitable if the random string will serve as a password, a bearer credential, a nonce, a session identifier, a "verification code" or "confirmation code", or another secret value.
I also list other things to keep in mind when generating unique identifiers, especially random ones.
True one liner random string options:
implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21));
md5(microtime() . implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21)));
sha1(microtime() . implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21)));

How to trim leading and trailing zeros in a number in PHP

I have the following numbers:
000000006375 and I want to output 63.75
000000004500 and I want to output just 45
Basically, if the last two numbers are not zero, I wanted to make it a float value wherein a decimal point will be added. But if the last 2 numbers are zeros I just want to output a whole number which in the example is just 45.
I was thinking of casting the numbers to int first but I do not know how to convert it to a float number if there last 2 digits are non-zeros.
You can use this code:
$s = '000000006375';
$i = (int) $s /100; // 63.75
echo "000000006375" / 100;
echo '<br />';
echo "000000004500" / 100;
// Output: 63.75<br />45
For your use case you might just cast it into an integer and divide with 100, like this:
$t1 = "000000006375";
$t2 = "000000004500";
var_dump(myfunc($t1), myfunc($t2));
function myfunc($in) {
$out = (int) $in / 100;
return $out;
}
The output will be something like...
float(63.75)
int(45)
print round('000000006375'/100,2);
print '<br/>';
print round('000000004500'/100,2);
$int = (int)'000000004500';
echo round((substr($int, 0, -2) . '.' . substr($int, -2)),2);
This is one way to do it :)

Categories