My users have a cookie with a string called code in it, the code is just random numbers or letters between 6 and 15 characters long. How after I receive the code, how can I check to ensure that the code is between 6 and 15 characters long and only contains numbers and letters?
Is using regular expressions the best way?
There are two easy ways you can do this. One is using regular expressions:
$length = strlen($cookie);
if (6 <= $length && $length <= 15 && preg_match('/^[a-zA-Z0-9]*$/', $cookie)) {
//...
}
The other is using the built-in ctype_alnum function which does exactly that (making sure a string is alpha-numeric):
$length = strlen($cookie);
if (6 <= $length && $length <= 15 && ctype_alnum($cookie)) {
//...
}
I would try something like : ^([a-zA-Z]|\d){6,15}$
“between the beginning and the end of the string, there are between 6 and 15 characters, each of them a letter or a digit”.
And, oh, the function you need is preg_match()
php's regex is pretty quick, and this is a case of a simple selector:
"/^[a-zA-Z0-9]{6,15}$/"
But #amosrivera was right about strlen being faster. If the cookie data is being plugged in the page (echo $_COOKIE['key'];) then the XML entities wont matter as the user can only harm their own page. If the cookie is being stored in a database and being displayed for all users, it would be a different matter altogether.
Related
I want to be able to effectively match a string with a number of regular expressions to determine what this string represents.
^[0-9]{1}$ if string matches it is of type 1
^[a-x]{300}$ if string matches it is of type 2
... ...
Iterating over a collection containing all of the regular expressions every time I want to match a string is way too heavy for me.
Is there any more effective way? Maybe I can compile these regexps into one big one? Maybe something that works like Google Suggestions, analysing letter after letter?
In my project, I am using PHP/MySQL, however I will be thankful for a clue in any language.
Edit:
Operation of matching a string will be very frequent and string values will vary.
What you could do, if possible, is grouping your regexes together and determine in which group a string belongs.
For instance, if a string doesn't match \d, you know there is no digit in it and you can skip all regexes that require one. So (for instance) instead of matching against +300 regexes, you can narrow that down to just 25.
You can sum up your regexes like this:
^([0-9])|([a-x]{300})$
Later, if you get more regex, you can do this:
^([0-9])|([a-x]{300})|([x-z]{1,5})|([ab]{2,})$...
Then use this code:
$input=...
preg_match_all('#^([0-9])|([a-x]{300})$#', $input, $matches);
foreach ($matches as $val) {
if (isset($val[1])) {
// type 1
} else if (isset($val[2])) {
// type 2
}
// and so on...
}
Since the regexes are going to be changing, I don't think you can get a generic answer - both your regex(es), and the way you handle them will need to evolve. For now, if you're looking to optimize the processing of your script, test for known strings before evaluating using something like indedOf to lighten the regex load.
For instance, if you have 4 strings:
asdfsdfkjslkdujflkj2lkjsdlkf2lkja
100010010100111010100101001001011
101032021309420940389579873987113
asdfkajhslkdjhflkjshdlfkjhalksjdf
Each belongs to a different "type" as you've described it, so you could do:
//type 1 only contains 0 or 1
//type 2 must have a "2"
//type 3 contains only letters
var arr = [
"asdfsdfkjslkdujflkj2lkjsdlkf2lkja",
"100010010100111010100101001001011",
"101032021309420940389579873987113",
"asdfkajhslkdjhflkjshdlfkjhalksjdf"
];
for (s in arr)
{
if (arr[s].indexOf('2') > 0)
{
//type 2
}
else if (arr[s].indexOf('0') > 0)
{
if ((/^[01]+$/g).test(arr[s]))
//type 1
else
//ignore
}
else if ((/^[a-z]+$/gi).test(arr[s]))
//type 3
}
See it in action here: http://jsfiddle.net/remus/44MdX/
I want to generate random alphanumeric strings in PHP. They will be used in places where the strength of random numbers is important (publicly visible IDs in URLs and the like).
As I understand, in PHP the main source of cryptographically strong randomness is openssl_random_pseudo_bytes(). This however returns an array of bytes, not alphanumeric characters.
To convert them to alphanumerics I could either hash them (which would produce a longer-than-necessary string of a limited set of hex characters), or base64_encode() them (which would produce a string with +, / and = in it - not alphanumerics).
So I think that instead I could use the random bytes as a source of entropy and generated my own string consisting only of the characters 0-9a-zA-Z.
The problem then becomes - how to translate from 256 distinct values (one byte of input) to 62 distinct value (one character of output). And in a way, that all 62 characters are equally as likely. (Otherwise there will be 8 characters that appear more often than the rest).
Or perhaps I should use another approach entirely? I would like my string to be as short as possible (say, 20 characters or so - shorter URLs are better) and consist only of alphanumeric characters (so that it doesn't need to be specially escaped anywhere).
You can implement your own base64 encoding, sort of. If you can allow two specific symbols - these can be anything, for example . and -, it doesn't really matter. It can even be a space for one of them. In any case, what you would do is this:
$alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-";
// using . and - for the two symbols here
$input = [123,193,21,13]; // whatever your input it, I'm assuming an array of bytes
$output = "";
foreach($input as $byte) {
$output .= $alphabet[$byte%64];
}
Assuming random input, all characters have equal probability of appearing.
That being said, if you can't allow anything except pure alphanumeric, cut the symbols from the $alphabet and use %62 instead of %64. While this does mean you have a small bias towards the chracters 0 through 7, I don't think it's significant enough to worry about.
I found this function on php.net in the user comments.
function crypto_rand($min,$max) {
$range = $max - $min;
if ($range == 0) return $min; // not so random...
$length = (int) (log($range,2) / 8) + 1;
return $min + (hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s))) % $range);
}
Then do something like
for($i=0; $i<20; $i++)
{
$string.= chr(crypto_rand(1,26)+96); //or +64 for upper case
}
Or similar.
note: THIS IS WRONG! I leave this attempted answer for reference only.
(31 * 256) % 62 = 0
For each output alphanumeric character, generate 31 random values. Sum these 31 values and take the modulo 62.
Kind of brutal, but this is the only "mathematicaly correct" option I can think of :)
I am working in PHP and I want to check if a given user submitted numeric input is not too big or too small.
I am storing the amounts in the database as 64 bit integers (multiply them by 10^8 to avoid rounding errors in future calculations). I am limiting the amounts so that they cannot exceed the following precision: no more than 4 numbers after the decimal point. Also since the upper limit on user input should be 99 million, I also want to specify no more than 8 numbers precending the decimal point. How can I achieve this neatly?
My current approach seems a bit hack-ish:
Code:
//Check for existence of decimal point in string using strpos
//explode the string by the decimal point
//do a strlen on both the strings and check they dont exceed 8 and 4 respectively
//if no decimal point, simply do a strelen and check it's not greater than 8
Also, I don't want the inputted data to be smaller than 0.0001. I am proficient in php for web design not familiar with the math functions of php is there an easy way to handle this?
Thanks for any tips
Using the code below you can check whether the $input conforms to your requirements.
(See also this short demo.)
$input = ...;
$pattern = "~^\s*\d{1,8}(?:\.\d{1,4})?\s*$~";
if (($input > 0) && preg_match($pattern, $input)) {
/* $input is OK */
} else {
/* $input is NOT OK */
}
Requirements:
$input has an integral part that is between 1 and 8 digits long.
$input optionally contains a . followed by 1 to 4 digits (fractional part).
$input is a positive number greater than or equal to 0.0001.
You can use regular expressions and the mb_ereg_match(regex,string) function
you can try this:
if (preg_match('~^(?>[1-9]\d{0,7}+|0)(?>\.\d{0,3}+[1,9])?$~', trim($number), $result))
// true
else
// false
This pattern avoids things like 00015 or 1.000, but if you want to allow this, just replace [1-9] by \d or better use ~^\d{1,8}+(?>\.\d{1,4}+)?$~ instead.
You must work after with $result which contain the trimed and verified number.
I think the following regex will match your needs.
It will match all numbers between 99999999.9999 and 00000000.0000 with and without the decimal point and also empty string.
The fractal part contains no more than 4 digits
if (preg_match('~^[0..9]{0,8}(?:\.[0..9]{1,4})?$~'), $number) {
$match = TRUE;
} else{
$match = FALSE;
}
See if this works:
$number = '123.4567';
if(preg_match('/^\s*\d*\.?\d{4}\s*$/', $number)) echo "Match";
else echo "Not match";
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Regular expression to limit number of characters to 10
I retrieve a POST to a standard form and I need to test two things:
The value must be 40 characters
The value must contain only letters and numbers
I think it is possible to do this with preg_match, but I do not know how.
In the global $_POST you have all your posted data on the http request.
then:
$myvar = $_POST['your_posted_variable_here'];
$result = preg_match('/^([\w\d]){40}$/i', $myvar);
$result will be true if your posted data only contains letters and digits and is 40 characters long, otherwise will be false.
For exactly 40 characters:
^[a-zA-Z0-9]{40}$
For at least 40 characters:
^[a-zA-Z0-9]{40,}$
Information on preg_match
http://php.net/manual/en/function.preg-match.php
if (preg_match("#^[a-z0-9]{40}$#mis", $_POST['username'])) {
print 'matched';
}
You can also check the length of the string using strlen() first, then if it satisfies the desired length, go forth with the checking of alpha numerics.
But General has the right idea...
Here's another way:
preg_match("/^[0-9a-zA-Z_]{40,}$/", $_POST["something"])
This is alpha numeric, and checks for at least 40 characters, but will accept more. The missing value after the comma means that it can be of any value equal or bigger than 40.
PHP provides a function for checking alphanumeric characters ctype_alnum and strlen to check the length of a string so using both functions you can validate it
$yourInput=$_POST['yourInput'];
if(ctype_alnum($yourInput) && strlen($strlen)==40)
{
//...
}
This question already has answers here:
How to validate phone numbers using regex
(43 answers)
Closed 9 years ago.
How to validate phone number using php
Here's how I find valid 10-digit US phone numbers. At this point I'm assuming the user wants my content so the numbers themselves are trusted. I'm using in an app that ultimately sends an SMS message so I just want the raw numbers no matter what. Formatting can always be added later
//eliminate every char except 0-9
$justNums = preg_replace("/[^0-9]/", '', $string);
//eliminate leading 1 if its there
if (strlen($justNums) == 11) $justNums = preg_replace("/^1/", '',$justNums);
//if we have 10 digits left, it's probably valid.
if (strlen($justNums) == 10) $isPhoneNum = true;
Edit: I ended up having to port this to Java, if anyone's interested. It runs on every keystroke so I tried to keep it fairly light:
boolean isPhoneNum = false;
if (str.length() >= 10 && str.length() <= 14 ) {
//14: (###) ###-####
//eliminate every char except 0-9
str = str.replaceAll("[^0-9]", "");
//remove leading 1 if it's there
if (str.length() == 11) str = str.replaceAll("^1", "");
isPhoneNum = str.length() == 10;
}
Log.d("ISPHONENUM", String.valueOf(isPhoneNum));
Since phone numbers must conform to a pattern, you can use regular expressions to match the entered phone number against the pattern you define in regexp.
php has both ereg and preg_match() functions. I'd suggest using preg_match() as there's more documentation for this style of regex.
An example
$phone = '000-0000-0000';
if(preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $phone)) {
// $phone is valid
}
I depends heavily on which number formats you aim to support, and how strict you want to enforce number grouping, use of whitespace and other separators etc....
Take a look at this similar question to get some ideas.
Then there is E.164 which is a numbering standard recommendation from ITU-T