Hello I hope someone could help me cus Iam little bit confused about task I have to do in PHP
I need php file that is unique registration ID with these parameters:
First is AA00001 and next one is DF00002.
So first letter + 3 and second + 5, but numbers going in +1 order.
Could someone give me hint how to achieve this?
Thank you!
In pseudocode:
get previous ID
separate first letter, second letter and number
convert first letter to number, add 3, modulo 26, convert back to letter
convert second letter to number, add 5, modulo 26, convert back to letter
add 1 to number, add zero-padding to reach 5 digits
concatenate them all together
set this as the new "previous ID"
Note that you'll need to ensure that this happens atomically - i.e. that you don't have multiple processes working on the same ID, else they'd get the same "next" ID. This will IMHO be the hardest part.
You can use substr to split the ID, dechex and hexdec to convert to/from decimal to hexadecimal, which gives you the A+3=D part, and you can use str_pad to front pad the integer with zeros, which gives you the second part, and then you just concatenate them.
ETA: Something like this:
$id = 'AA00001';
$first = dechex((hexdec(substr($id,0,1))+3)%16);
$secnd = dechex((hexdec(substr($id,1,1))+5)%16);
$int = str_pad(substr($id,2)+1,5,"0",STR_PAD_LEFT);
$newid = strtoupper($first.$secnd.$int);
ETA2: Unless you meant to go AA00001, DF00002, GK00003, JP00004, MU00005, PZ00006, SE00007 etc in which case you need
$first = chr(((ord(substr($id,0,1))-62)%26)+65);
$secnd = chr(((ord(substr($id,1,1))-60)%26)+65);
$lastid = 'AA00001';
$first = substr($lastid, 0, 1);
$second = substr($lastid, 1, 1);
$numeric = substr($lastid, 2);
$next_first = chr(((ord($first) - ord('A') + 3) % 26) + ord('A'));
$next_second = chr(((ord($second) - ord('A') + 5) % 26) + ord('A'));
$next_numeric = sprintf('%05d', intval($numeric) + 1);
$new_id = $next_first . $next_second . $next_numeric;
// DF00002
First you have to parse the last reg id.(using substr) Then,
store each value in a var corresponding to the place
$first , $second, $numberpart. then
$first = ($first + 3 ) % 16;
$second =($first + 5 ) % 16;
$number = $number + 1;
THen update the record accordingly converting$first, $second to their appro. letters.
Related
I need to find the first and last number with length n and starting with digit d.
For example.
i need to find the first and last number with length 6 and starting in 2
The result should be first number=200000 and last number=299999 .
I there any functions available in php to help me to get a logic to solve this.??
Hope Someone can help me..
You could try relying on the fact that the smallest number will end in all 0's and the largest in all 9's, and then use str_repeat to generate the appropriate tailing digits:
echo $d . str_repeat('0', $n-1);
echo $d . str_repeat('9', $n-1);
For $d = 2 and $n = 6, this will give you 200000 and 299999.
If you need them as integers, just do
$start = (int)($d . str_repeat('0', $n-1));
$finish = (int)($d . str_repeat('9', $n-1));
var_dump($start);
var_dump($finish);
Output:
int(200000)
int(299999)
Here is an option which uses algebra to get the numbers you want. Based on the width of the number, we can compute the smallest number with that width. Then, the starting number is simply this value times the starting first digit. And the ending number can also be teased out.
$length = 6;
$first = 2;
$begin = pow(10, $length-1);
$start = $first * $begin;
$end = (($first + 1) * $begin) - 1;
echo $start . "\n";
echo $end;
200000
299999
Demo
This should outperform the accepted answer because generating the numbers requires only a few arithmetic operations, rather than complex string manipulation operations.
How can I get the first and the last digit of a number? For example 2468, I want to get the number 28. I am able to get the ones in the middle (46) but I can't do the same for the first and last digit.
For the digits in the middle I can do it
$substrmid = substr ($sum,1,-1); //my $sum is 2468
echo $substrmid;
Thank you in advance.
You can get first and last character from string as below:-
$sum = (string)2468; // type casting int to string
echo $sum[0]; // 2
echo $sum[strlen($sum)-1]; // 8
OR
$arr = str_split(2468); // convert string to an array
echo reset($arr); // 2
echo end($arr); // 8
Best way is to use substr described by Mark Baker in his comment,
$sum = 2468; // No need of type casting
echo substr($sum, 0, 1); // 2
echo substr($sum, -1); // 8
You can use substr like this:
<?php
$a = 2468;
echo substr($a, 0, 1).substr($a,-1);
You can also use something like this (without casting).
$num = 2468;
$lastDigit = abs($num % 10); // 8
However, this solution doesn't work for decimal numbers, but if you know that you'll be working with nothing else than integers, it'll work.
The abs bit is there to cover the case of negative integers.
$num = (string)123;
$first = reset($num);
$last = end($num);
I need to split a string in two so I can do a SELECT query in my DB. For example, I have the number '0801'. I need to split that number into '08' and '01'. How do I manage to do that?
This is easy to do using the substr() function, which lets you pull out parts of a string. Given your comment that you always have a four-digit number and want it split into two two-digit numbers, you want this:
$input = "0801";
$left = substr($input, 0, 2);
$right = substr($input, 2);
echo "Left is $left and right is $right\n";
According to your comment
The first 2 numbers. It's allways a 4 digit number and I allways need
to split it in 2 two digit numbers
You can simply use
$value = '0801';
$split = str_split($value, 2);
var_dump($split[0]);
var_dump($split[1]);
Just keep in mind $value variable should always be of a string type, not int.
you can use str_split and list
$str = '0801';
list($first,$second) = str_split($str,2);
echo $first;
// 08
echo $second;
// 01
No one gave a MySQL answer yet...
If you're selecting that number..
SELECT
SUBSTR(colname, 0, 2) as firstpart,
SUBSTR(colname, 2, 2) as secondpart
FROM table
Is there a term for the idea of storing large numbers as letters? For example let's say I have the (relatively small) number 138201162401719 and I want to shrink the number of characters (I know this does not help with saving disk space) to the fewest possible number of characters. There are 26 letters in the English alphabet (but i count them as 25 since we need a zero letter). If I start splitting up my large number into pieces that are each 25 or less I get:
13, 8, 20, 11, 6, 24, 0, 17, 19
If I then count the numbers of the alphabet a=0, b=1, c=2, d=3... I can convert this to:
NIULGYART
So I went from 15 digits long (138201162401719) to 9 characters long (NIULGYART). This could of course be easily converted back to the original number as well.
So...my first question is "Does this have a name" and my second "Does anyone have PHP code that will do the conversion (in both directions)?"
I am looking for proper terminology so that I can do my own research in Google...though working code examples are cool too.
This only possible if you're considering to store your number before processing as a string. Because you can't store huge number as integers. You will lost the precision (13820116240171986468445 will be stored as 1.3820116240172E+22) so the alot of digits are lost.
If you're considering storing the number as a string this will be your answer:
Functions used: intval, chr and preg_match_all.
<?php
$regex = '/(2[0-5])|(1[0-9])|([0-9])/';
$numberString = '138201162401719';
preg_match_all($regex, $numberString, $numberArray, PREG_SET_ORDER);
echo($numberString . " -> ");
foreach($numberArray as $value){
$character = chr (intval($value[0]) + 65);
echo($character);
}
?>
Demo
This is the result:
138201162401719 -> NIULGYART
Here's how I would do it:
Store the big number as a string and split it into an array of numbers containing one digit each
Loop through the array extract 2-digit chunks using substr()
Check if the number is less than 26 (in which case, it is an alphabet) and add them to an array
Use array_map() with chr() to create a new array of characters from the above array
Implode the resulting array to get the cipher
In code:
$str = '138201162401719';
$arr = str_split($str);
$i = 0; // starting from the left
while ($i < count($arr)) {
$n = substr($str, $i, 2);
$firstchar = substr($n, 0, 1);
if ($n < 26 && $firstchar != 0) {
$result[] = substr($str, $i, 2);
$i += 2; // advance two characters
} else {
$result[] = substr($str, $i, 1);
$i++; // advance one character
}
}
$output = array_map(function($n) {
return chr($n+65);
}, $result);
echo implode($output); // => NIULGYART
Demo.
As an alternative, you could convert the input integer to express it in base 26, instead of base 10. Something like (pseudocode):
func convertBase26(num)
if (num < 0)
return "-" & convertBase26(-num) // '&' is concatenate.
else if (num = 0)
return "A"
endif
output = "";
while (num > 0)
output <- ('A' + num MOD 26) & output // Modulus operator.
num <- num DIV 26 // Integer division.
endwhile
return output
endfunc
This uses A = 0, B = 1, up to Z = 25 and standard place notation: 26 = BA. Obviously a base conversion is easily reversible.
strtr() is a magnificent tool for this task! It replaces the longest match as is traverses the string.
Code: (Demo)
function toAlpha ($num) {
return strtr($num, range("A", "Z"));
}
$string = toAlpha("138201162401719");
echo "$string\n";
$string = toAlpha("123456789012345");
echo "$string\n";
$string = toAlpha("101112131415161");
echo "$string\n";
$string = toAlpha("2625242322212019");
echo "$string";
Output:
NIULGYART
MDEFGHIJAMDEF
KLMNOPQB
CGZYXWVUT
Just flip the lookup array to reverse the conversion: https://3v4l.org/YsFZu
Merged: https://3v4l.org/u3NQ5
Of course, I must mention that there is a vulnerability with converting a sequence of letters to numbers and back to letters. Consider BB becomes 11 then is mistaken for eleven which would traslate to L when converted again.
There are ways to mitigate this by adjusting the lookup array, but that may not be necessary/favorable depending on program requirements.
And here is another consideration from CodeReview.
I have been trying to do the same thing in PHP without success.
Assuming I'm using the 26 letters of the English alphabet, starting with A = 0 down to Z as 25:
I find the highest power of 26 lower than the number I am encoding. I divide it by the best power of 26 I found. Of the result I take away the integer, convert it to a letter and multiply the decimals by 26. I keep doing that until I get a whole number. It's ok to get a zero as it's an A, but if it has decimals it must be multiplied.
For 1 billion which is DGEHTYM and it's done in 6 loops obviously. Although my answer demonstrates how to encode, I'm afraid it does not help doing so on PHP which is what I'm trying to do myself. I hope the algorithm helps people out there though.
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);