I'm having some trouble with Regex never really used it. However basically I'm trying to set a limit on my font-size bbcode tag.
class SizeValidator implements \JBBCode\InputValidator
{
public function validate($input)
{
return (bool) preg_match('regex', $input);
}
}
If someone can help with the regex that'll be perfect! Basically just want Size 7 to 30 max, no px, em, nothing strictly numbers max 2 numbers if anyone with regex experience would be quite helpful possibly explain how it works so I can improve and get a better understanding :)
There really is no reason to use regular expressions here.
Simply verify that what you're getting is a sequence of digits (for instance using ctype_digit, and that the value lies between 7 and 30.
class SizeValidator implements \JBBCode\InputValidator {
public function validate($input) {
return ctype_digit($input) && $input >= 7 && $input <= 30;
}
}
It's much more readable and easier to modify if need be.
You could try something like this:
return (bool)preg_match('/\[size=(([7-9])|([1-2]\d)|(30))\](.*)?\[\/size\]/', $input);
First I am matching if the number is 7-9, if so your function returns true.
([7-9])
Else if your number is with two digits starting with either 1 or 2 then the function also returns true
([1-2]\d)
Or else I check if the number is 30 and return true.
Related
I have written a function that takes in a MD5 hashvalue and finds its input/original value by permuting all possible combinations of a string. As per BIT_CHEETAH's answer on a SO question:
... you cannot decrypt MD5 without attempting something like brute force hacking which is extremely resource intensive, not practical, and unethical.
(Source: encrypt and decrypt md5)
I'm well aware of this, however, I am using this scenario to implement a string permutation function. I would also like to stick to the recursive methodology as opposed to others. The best summary of doing this is probably summarised by Mark Byers post:
- Try each of the letters in turn as the first letter and then find all
the permutations of the remaining letters using a recursive call.
- The base case is when the input is an empty string the only permutation is the empty string.
(Generating all permutations of a given string)
Anyway, so I implemented this and got the following:
function matchMD5($possibleChars, $md5, $concat, $length) {
for($i = 0; $i < strlen($possibleChars); $i++) {
$ch = $possibleChars[$i];
$concatSubstr = $concat.$ch;
if(strlen($concatSubstr) != $length) {
matchMD5($possibleChars, $md5, $concatSubstr, $length);
}
else if(strlen($concatSubstr) == $length) {
$tryHash = hash('md5', $concatSubstr);
if ($tryHash == $md5) {
echo "Match! $concatSubstr ";
return $concatSubstr;
}
}
}
}
Works 100%, however when I pass in a four character array, my server runs 10.7 seconds to generate a match where the match lies approximately 1/10th of the way of all possible permutations. My valid characters in which the functions permutes, called, $possibleChars, contains all alphanumeric characters plus a few selected punctionations:
0123456789.,;:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Question: Can the above code be written to run faster somehow?
When doing brute-force, you have to run through all the possibilities, there is not way of cutting a corner there. So you are left with profiling your code to find out what the application spends the most time doing and then trying to optimize that.
I need to check that a string
contains only digits and
the first digit is 0, and
the whole string has at least 8 digits and maximum 25
I have tried this, but it doesn't work:
if (!preg_match('/^[0][0-9]\d{8-25}$/', $ut_tel))
Try this regex:
/^0\d{7,24}$/
It seemed to work here.
Use this regex pattern
^(0[0-9]{7,24})$
Demo
If I was you, I'd do each check separately. This way you won't have issues in the future, should you decide to remove one of them or add additional checks.
(Note to all potential downvoters: I realize the question asked for a regex way, but since that was already provided in other answers - I think it is good to have a different approach as an answer as well.)
function validateNumber($number){
if(!is_numeric($number))
return false;
if(strlen($number)>25 || strlen($number)<8)
return false;
if(substr($number, 0, 1) != 0)
return false;
return true;
}
var_dump(validateNumber('0234567')); // shorter than 8
var_dump(validateNumber('02345678')); // valid
var_dump(validateNumber('12345678')); // doesn't start with 0
var_dump(validateNumber('02345678901234567890123456')); // longer than 25
I am looking to generate a series of random numbers that have a difference of at least 2 from the previous number that was generated. I thought that a simple function that would call itself would be the way to go - see code below...
function getRandomLength($previous){
$x = rand(1,12);
if(abs($x - $previous) > 2){
return $x;
} else {
getRandomLength($previous);
}
}
For whatever reason, this is not working out the way that I had hoped it would. Any help would be appreciated.
Thanks.
And for those wondering why I want random numbers that are slightly different, I'm building a deck. I need to cut the decking boards and I don't want the joint to line up, or have any perceivable pattern to them, hence, I turn to my trusty random number generator to help out...
Two problems here:
function getRandomLength($previous){
$x = rand(1,12);
if(abs($x - $previous) > 2){
First problem is here - you use > 2 when you meant >= 2, e.g. if the difference is two or more then it's fine.
return $x;
} else {
getRandomLength($previous);
Second problem is here - you call the method again, but you do not return the result of calling it, so the result of the method will be an un-useful null.
Also, you should not code the method to be recursive, it should be iterative, as it doesn't need recursive logic.
}
}
Since you need an offset of at least 2, pick a random number starting from 0 and add 2 to it. Since it's an offset, you add it to the previous value (but I'm sure you could figure that out).
In some PHP I need to compare two strings, but only on the bits that are set as one in the bitmask. How would I implement such a behavior?
I've tried:
$string1='aaabbb';
$string2='ababbb';
$bitmask='101101';
function compare($string1, $string2, $bitmask){
$resultBitmask=(~($string1 ^ $string2)|~$bitmask);
}
For clarity's sake, I've written ff bytes as 1 in the bitmask for illustrative purposes. They would actually be ff in hex when a bitmask is generated. Same goes for 0 being null bytes.
The string and the bitmask are always different lengths each time the function is called. I've managed to get a set of bits for comparison, but am unable to check whether they are all set since the lenths differ. At this time, I've been using preg_match with a regex that matches any number of ff bytes, but is there a more elegant solution?
Edit: Since the strings are any length up to 4096 bits long, they cannot be converted to numbers.
It's not the flashest way of doing it but:
$stillTheSame = true;
for($i=0;$i<=strlen($bitmask); $i++)
{
if($bitmask[$i] == 1)
{
if($string1[$i] != $string2[$i])
{
$stillTheSame = false;
break;
}
}
}
Not sure fof your actual checking logic, but this should help hopefully.
Self-solved:
Since this will repeat with many strings of the same length during a run, but have different lengths between runs, I need to check that the resulting string after the bitwise operations is all ones and the correct length. I realized that this string full of ones can be generated when needed, which is quite rarely, once every 1000 or so string comparisons. I can generate the string before runs as follows:
$ones=str_repeat(chr(255), $byte_length);
and then defining the compare( function a bit differently:
function compare($string1, $string2, $bitmask){
global $ones;
$resultBitmask=(~($string1 ^ $string2)|~$bitmask);
if ($resultBitmask=$ones){
return 1;
} else {return 0};
}
The trick was the str_repeat which I was not aware of before.
I am trying to make a power function to calculate the power of 17^2147482999.
I tried this code:
function ipow($a, $b) {
if ($b<0) {
echo "B must be a positive integer";
}
if ($b==0) return 1;
if ($a==0) return 0;
if ($b%2==0) {
return ipow($a*$a, $b/2);
} else if ($b%2==1) {
return $a*ipow($a*$a,$b/2);
}
return 0;
}
The function call:
echo ipow($a, $b);
The error:
Fatal error: Maximum function nesting level of '100' reached, aborting! in C:\wamp\www\spoj\LASTDIG.php on line 23
Is there any other way to calculate the power for such big values? The inbuilt pow() function is giving an INF output.
UPDATE
If it seems impossible to get the whole answer, is it possible to extract atleast the last 5-10 digits of the answer by some mathematical approach?
You cannot do that with plain PHP arithemtic operations. That's way out of range for integers, even on 64-bit systems.
You need to use the bcmath extension and the bcpow function. (If that doesn't work maybe even gmp.)
print bcpow(17, 2147482999);
You may use bcpowmod function like this:
<?php echo bcpowmod(17,2147482999,10000000000); ?>
the result is 8849802353 which means, 17^2147482999 mod 10000000000 or, the last 10 digits of 17^2147482999 is 8849802353.
The resulting value is something in the order of 1e+2642368139, a lot more than can fit in most libraries. If you want some approximation, you can use some logarithmic logic:
17^2147482999 = 10^(log(17^2147482999))
= 10^(2147482999 * log(17))
= 10^(2147482999 * 1.23045)
= 10^(2642368139.79773)
= 10^2642368139 * 10^0.79773
= 6.27669e+2642368139
GNU Multiple Precision and namely gmp_pow may be what you are looking for.
I suggest you look into BigInteger, the constant PHP_INT_MAX will tell you how big an integer your platform can handle. On 64 bit this returns 9223372036854775807, wich is far from for your result in decimal notation.
Try to change the algorithm and instead of working with numbers (as the data type) ... work with plain strings. It will take a lot of time to compute it but it will be achievable :)