What's a good way to validate phone numbers being input in codeigniter?
It's my first time writing an app, and I don't really understand regex at all.
Is it easier to have three input fields for the phone number?
Here's a cool regex I found out on the web. It validates a number in almost any US format and converts it to (xxx) xxx-xxxx. I think it's great because then people can enter any 10 digit US phone number using whatever format they are used to using and you get a correctly formatted number out of it.
Here's the whole function you can drop into your MY_form_validation class. I wanted my form to allow empty fields so you'll have to alter it if you want to force a value.
function valid_phone_number_or_empty($value)
{
$value = trim($value);
if ($value == '') {
return TRUE;
}
else
{
if (preg_match('/^\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/', $value))
{
return preg_replace('/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/', '($1) $2-$3', $value);
}
else
{
return FALSE;
}
}
}
The best way is not to validate phone numbers at all, unless you're absolutley 100% positive that you're only dealing with phone numbers in the US or at least North America. As soon as you allow phone numbers from Europe I don't think there's a regex which covers all possibilities.
strip out the non-digits with this:
$justNumbers = preg_replace( '/\D/', $_POST[ 'phone_num' ] );
and see if there are enough characters!
$numRequired = 7; // make your constraints here
if( strlen( $justNumbers ) < $numRequired ){ /* ... naughty naughty ... */ }
this is loose, of course, but will work for international numbers as well (as all it's really doing is seeing if there are over 7 numbers in the input).
just change the number of required digits according to your specifications.
The regex solution as explained by Dan would be the way to do it - but you might want to re-think validating phone numbers at all. What if the user wants to add a note like he/she would do on paper? - I see many values entered in the phone number fields to be stuff like:
307-555-2323 (home)
or
307-555-3232 after 6pm
I think today we can assume the users knows what to enter.
Related
When creating a password sometimes I need the password to contain uppercase, lowercase, number or a symbol. If I create the password like this it's not guaranteed that each is represented:
$input = 'a..zA..Z0..9$!_'; // generally the whole allowed alphabet
while (strlen($password) < 10) {
$password .= securelyPickRandomCharacterFromString($input);
}
In this case there is a chance that the random process (even though it's safe and completely random) will only select lowercase letters.
I can think of naive approaches like first selecting 1 from each group and then filling the rest randomly. But that would not be cryptographically safe as say random_bytes() is. Maybe shuffle after?
What would be a good and safe algorithm to generate the password containing each "group" of characters.
Note: The password requirements are usually for external system and are out of my control.
Here's a really naive way of doing it (pseudo code):
// Create your lists/arrays of groups
char listLowerCase[] = {'a','b',....};
char listUpperCase[] = {'A','B',....};
char listNums[] = {'1','2',....};
char listSpecialChars[] = {'#','#',...};
// Form a password from those groups (I'm just gonna use length 4 as example)
String pwd = listLowerCase[randomNumber] + listUpperCase[randomNumber]
+ listNums[randomNumber] + listSpecialChars[randomNumber];
// Shuffle the password
String shuffledPwd = shuffle(pwd);
In case you don't want to have the same number of characters from each group, you could try also setting random numbers that determine how many characters you will use in each group. Hope that helped you.
The simplest approach by far is to generate a random password using the chosen alphabet. Then check for constraints such as “must contain at least one of each character class”. If the password doesn't match the constraints, try again in a loop.
do {
$password = '';
while (strlen($password) < 10) {
$password .= securelyPickRandomCharacterFromString($input);
}
} while (!matches_constraints($password));
Within the given constraints on acceptable passwords, this has optimal security, since every acceptable password of the chosen length is equally likely.
In addition to simplicity and security, another benefit of this approach is that it accommodates arbitrary constraints, such as the common “must contain at least 3 of 4 character classes”, without having to write different, complex code for each different constraint.
With any sensible parameters, the number of redraws will be small. For example, a 10-character password generated from non-space printable ASCII characters (94-character alphabet) has a ((94-10)/94)^10 ≈ 0.32 chance of not containing a digit, the smallest of the four character classes. The chance of missing one of the four classes is a little under 0.42. So on average you'll need a little less than 2 iterations to get a suitable password with these particular parameters. Generating random letters is cheap, so performance is not a problem.
You should include protection against nonsensical parameters, for example attempting to generate a 3-character password that contains characters from all 4 classes (which would loop forever), or a 4-character password that contains characters from all 4 classes (which could take a very long time). So add a maximum iteration count.
$iterations = 0;
do {
if ($iterations >= 10) throw new NonsensicalPasswordConstraintException;
$password = '';
while (strlen($password) < 10) {
$password .= securelyPickRandomCharacterFromString($input);
}
++$iterations;
} while (!matches_constraints($password));
I have a system that contains x number of strings. These string are shown in a UI based on some logic. For example string number 1 should only show if the current time is past midday and string 3 only shows if a randomly generated number between 0-1 is less than 0.5.
How would be the best way to model this?
Should the logic just be in code and be linked to a string by some sort or ID?
Should the logic be some how stored with the strings?
NOTE The above is a theoretical example before people start questioning my logic.
It's usually better to keep resources (such as strings) separate from logic. So referring strings by IDs is a good idea.
It seems that you have a bunch of rules which you have to link to the display of strings. I'd keep all three as separate entities: rules, strings, and the linking between them.
An illustration in Python, necessarily simplified:
STRINGS = {
'morning': 'Good morning',
'afternoon': 'Good afternoon',
'luck': 'you must be lucky today',
}
# predicates
import datetime, random
def showMorning():
return datetime.datetime.now().hour < 12
def showAfternoon():
return datetime.datetime.now().hour >= 12
def showLuck():
return random.random() > 0.5
# interconnection
RULES = {
'morning': showMorning,
'afternoon': showAfternoon,
'luck': showLuck,
}
# usage
for string_id, predicate in RULES.items():
if predicate():
print STRINGS[string_id]
I need to validate user input of an international phone number. According to E.164, the maximum length is 15 digits, but I was unable to find any information about the minimum. I consider digits only, no plus sign or separators.
As per different sources, I think the minimum length in E-164 format depends on country to country. For eg:
For Israel: The minimum phone number length (excluding the
country code) is 8 digits. - Official Source
(Country Code 972)
For Sweden : The minimum number length (excluding
the country code) is 7 digits. - Official Source (country code 46)
For Solomon Islands its 5 for fixed line phones. - Source (country code 677)
... and so on.
So including country code, the minimum length is 9 digits for Sweden and 11 for Israel and 8 for Solomon Islands.
Edit (Clean Solution): Actually, Instead of validating an international phone number by having different checks like length etc, you can use the Google's libphonenumber library. It can validate a phone number in E164 format directly. It will take into account everything and you don't even need to give the country if the number is in valid E164 format. Its pretty good!
Taking an example:
String phoneNumberE164Format = "+14167129018"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber phoneNumberProto = phoneUtil.parse(phoneNumberE164Format, null);
boolean isValid = phoneUtil.isValidNumber(phoneNumberProto); // returns true if valid
if (isValid) {
// Actions to perform if the number is valid
} else {
// Do necessary actions if its not valid
}
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
If you know the country for which you are validating the numbers, you don;t even need the E164 format and can specify the country in .parse function instead of passing null.
The minimum length is 4 for Saint Helena (Format: +290 XXXX) and Niue (Format: +683 XXXX).
EDIT 2015-06-27: Minimum is actually 8, including country code. My bad.
Original post
The minimum phone number that I use is 10 digits. International users should always be putting their country code, and as far as I know there are no countries with fewer than ten digits if you count country code.
More info here: https://en.wikipedia.org/wiki/Telephone_numbering_plan
I don't really like people who write with Caps Lock. In addition the aversion, it defaces the whole application. I am wondering how to prevent users writing all characters with caps lock. I cannot force all text to lowercase due to special names and abbreviations. What logic should I use?
Politely decline their posts—explaining why—if the number of capital letter exceeds the number of lowercase letters by more than 30, say.
Don't implement this on a FORTRAN forum
You could check how many upper case characters are in a word, then limit that. Someone above has given the example of names like 'McLaren', this way would allow that. the down side is, if you put the maximum on 3, 'LOL' would stil be possible.
The way to go would be to take the length of the word 'McLaren' would be 7 then cap it on a percentage like 20%, this enables longer words to have more uppercase characters, but not be all caps. (nothing will completely prevent it, but this will make it harder for them.)
Fun fact, today is international caps-lock day. :)
keypress: function(e) {
var ev = e ? e : window.event;
if (!ev) {
return;
}
var targ = ev.target ? ev.target : ev.srcElement;
// get key pressed
var which = -1;
if (ev.which) {
which = ev.which;
} else if (ev.keyCode) {
which = ev.keyCode;
}
// get shift status
var shift_status = false;
if (ev.shiftKey) {
shift_status = ev.shiftKey;
} else if (ev.modifiers) {
shift_status = !!(ev.modifiers & 4);
}
// At this point, you have the ASCII code in "which",
// and shift_status is true if the shift key is pressed
}
Source --http://24ways.org/2007/capturing-caps-lock
I am doing a CSV Import tool for the project I'm working on.
The client needs to be able to enter the data in excel, export them as CSV and upload them to the database.
For example I have this CSV record:
1, John Doe, ACME Comapny (the typo is on purpose)
Of course, the companies are kept in a separate table and linked with a foreign key, so I need to discover the correct company ID before inserting.
I plan to do this by comparing the company names in the database with the company names in the CSV.
the comparison should return 0 if the strings are exactly the same, and return some value that gets bigger as the strings get more different, but strcmp doesn't cut it here because:
"Acme Company" and "Acme Comapny" should have a very small difference index, but
"Acme Company" and "Cmea Mpnyaco" should have a very big difference index
Or "Acme Company" and "Acme Comp." should also have a small difference index, even though the character count is different.
Also, "Acme Company" and "Company Acme" should return 0.
So if the client makes a type while entering data, i could prompt him to choose the name he most probably wanted to insert.
Is there a known algorithm to do this, or maybe we can invent one :)
?
You might want to check out the Levenshtein Distance algorithm as a starting point. It will rate the "distance" between two words.
This SO thread on implementing a Google-style "Do you mean...?" system may provide some ideas as well.
I don't know what language you're coding in, but if it's PHP, you should consider the following algorithms:
levenshtein(): Returns the minimal number of characters you have to replace, insert or delete to transform one string into another.
soundex(): Returns the four-character soundex key of a word, which should be the same as the key for any similar-sounding word.
metaphone(): Similar to soundex, and possibly more effective for you. It's more accurate than soundex() as it knows the basic rules of English pronunciation. The metaphone generated keys are of variable length.
similar_text(): Similar to levenshtein(), but it can return a percent value instead.
I've had some success with the Levenshtein Distance algorithm, there is also Soundex.
What language are you implementing this in? we may be able to point to specific examples
I have actually implemented a similar system. I used the Levenshtein distance (as other posters already suggested), with some modifications. The problem with unmodified edit distance (applied to whole strings) is that it is sensitive to word reordering, so "Acme Digital Incorporated World Company" will match poorly against "Digital Incorporated World Company Acme" and such reorderings were quite common in my data.
I modified it so that if the edit distance of whole strings was too big, the algorithm fell back to matching words against each other to find a good word-to-word match (quadratic cost, but there was a cutoff if there were too many words, so it worked OK).
I've taken SoundEx, Levenshtein, PHP similarity, and double metaphone and packaged them up in C# in one set of extension methods on String.
Entire blog post here.
There's multiple algorithms to do just that, and most databases even include one by default. It is actually a quite common concern.
If its just about English words, SQL Server for example includes SOUNDEX which can be used to compare on the resulting sound of the word.
http://msdn.microsoft.com/en-us/library/aa259235%28SQL.80%29.aspx
I'm implementing it in PHP, and I am now writing a piece of code that will break up 2 strings in words and compare each of the words from the first string with the words of the second string using levenshtein and accept the lowes possible values. Ill post it when I'm done.
Thanks a lot.
Update: Here's what I've come up with:
function myLevenshtein( $str1, $str2 )
{
// prepare the words
$words1 = explode( " ", preg_replace( "/\s+/", " ", trim($str1) ) );
$words2 = explode( " ", preg_replace( "/\s+/", " ", trim($str2) ) );
$found = array(); // array that keeps the best matched words so we don't check them again
$score = 0; // total score
// In my case, strings that have different amount of words can be good matches too
// For example, Acme Company and International Acme Company Ltd. are the same thing
// I will just add the wordcount differencre to the total score, and weigh it more later if needed
$wordDiff = count( $words1 ) - count( $words2 );
foreach( $words1 as $word1 )
{
$minlevWord = "";
$minlev = 1000;
$return = 0;
foreach( $words2 as $word2 )
{
$return = 1;
if( in_array( $word2, $found ) )
continue;
$lev = levenshtein( $word1, $word2 );
if( $lev < $minlev )
{
$minlev = $lev;
$minlevWord = $word2;
}
}
if( !$return )
break;
$score += $minlev;
array_push( $found, $minlevWord );
}
return $score + $wordDiff;
}