What is the minimum length of a valid international phone number? - validation

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

Related

Split test groups base on GUID

Users in the system are identified by GUID, and with a new feature, I want to divide users into two groups - test and control.
Is there a easy way to split users into one of the two group with a 50/50 chance, based on their GUID?
e.g. If the nth character's ascii code is an odd -> test group, otherwise control group.
What about 70/30, or other ratio?
The reason I want to classify users base on GUID, is because later I can easily tell which users are in which group and compare the performance between two groups, without having to keep track of the group assignment - I simply need to calculate it again.
As Derek Li notes, the GUID's bits might be based on a timestamp, so you shouldn't use them directly.
The safest solution is to hash the GUID using a hash function like MurmurHash. This will produce a random number (but the same random number every time for any given GUID) which you can then use to do the split.
For example, you could do a 30/70 split like this:
function isInTestGroup(user) {
var hash = murmurHash(user.guid);
return (hash % 100) < 30;
}
If some character in the GUID has a 1 in 16 change of being one of the following characters: "0123456789ABCEDF", then perhaps you could test a scheme that determines placement by that character.
Say the last character of the guid called c has a 1/16 chance of being any hex digit:
for 50/50 distribution -> c <= 7 for group 1, c > 7 for group 2
for 70/30 c <= A for group 1, c > A for group 2
etc...

Hashing a long integer ID into a smaller string

Here is the problem, where I need to transform an ID (defined as a long integer) to a smaller alfanumeric identifier. The details are the following:
Each individual on the problem as an unique ID, a long integer of size 13 (something like 123123412341234).
I need to generate a smaller representation of this unique ID, a alfanumeric string, something like A1CB3X. The problem is that 5 or 6 character length will not be enough to represent such a large integer.
The new ID (eg A1CB3X) should be valid in a context where we know that only a small number of individuals are present (less than 500). The new ID should be unique within that small set of individuals.
The new ID (eg A1CB3X) should be the result of a calculation made over the original ID. This means that taking the original ID elsewhere and applying the same calculation, we should get the same new ID (eg A1CB3X).
This calculation should occur when the individual is added to the set, meaning that not all individuals belonging to that set will be know at that time.
Any directions on how to solve such a problem?
Assuming that you don't need a formula that goes in both directions (which is impossible if you are reducing a 13-digit number to a 5 or 6-character alphanum string):
If you can have up to 6 alphanumeric characters that gives you 366 = 2,176,782,336 possibilities, assuming only numbers and uppercase letters.
To map your larger 13-digit number onto this space, you can take a modulo of some prime number slightly smaller than that, for example 2,176,782,317, the encode it with base-36 encoding.
alphanum_id = base36encode(longnumber_id % 2176782317)
For a set of 500, this gives you a
2176782317P500 / 2176782317500 chance of a collision
(P is permutation)
Best option is to change the base to 62 using case sensitive characters
If you want it to be shorter, you can add unicode characters. See below.
Here is javascript code for you: https://jsfiddle.net/vewmdt85/1/
function compress(n) {
var symbols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïð'.split('');
var d = n;
var compressed = '';
while (d >= 1) {
compressed = symbols[(d - (symbols.length * Math.floor(d / symbols.length)))] + compressed;
d = Math.floor(d / symbols.length);
}
return compressed;
}
$('input').keyup(function() {
$('span').html(compress($(this).val()))
})
$('span').html(compress($('input').val()))
How about using some base-X conversion, for example 123123412341234 becomes 17N644R7CI in base-36 and 9999999999999 becomes 3JLXPT2PR?
If you need a mapping that works both directions, you can simply go for a larger base.
Meaning: using base 16, you can reduce 1 to 16 to a single character.
So, base36 is the "maximum" that allows for shorter strings (when 1-1 mapping is required)!

how bytes are used to store information in protobuf

i am trying to understand the protocol buffer here is the sample , what i am not be able to understand is how bytes are being used in following messages. i dont know what this number
1 2 3 is used for.
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}
message Polyline {
repeated Point point = 1;
optional string label = 2;
}
i read following paragraph in google protobuf but not able to understand what is being said here , can anyone help me in understanding how bytes are being used to store info.
The " = 1", " = 2" markers on each element identify the unique "tag" that field uses in the binary encoding. Tag numbers 1-15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional element.
The general form of a protobuf message is that it is a sequence of pairs of the form:
field header
payload
For your question, we can largely forget about the payload - that isn't the bit that relates to the 1/2/3 and the <=16 restriction - all of that is in the field header. The field header is a "varint" encoded integer; "varint" uses the most-significant-bit as an optional continuation bit, so small values (<=127, assuming unsigned and not zig-zag) require one byte to encode - larger values require multiple bytes. Or in other words, you get 7 useful bits to play with before you need to set the continuation bit, requiring at least 2 bytes.
However! The field header itself is composed of two things:
the wire-type
the field-number / "tag"
The wire-type is the first 3 bits, and indicates the fundamental format of the payload - "length-delimited", "64-bit", "32-bit", "varint", "start-group", "end-group". That means that of the 7 useful bits we had, only 4 are left; 4 bits is enough to encode numbers <= 16. This is why field-numbers <= 16 are suggested (as an optimisation) for your most common elements.
In your question, the 1 / 2 / 3 is the field-number; at the time of encoding this is left-shifted by 3 and composed with the payload's wire-type; then this composed value is varint-encoded.
Protobuf stores the messages like a map from an id (the =1, =2 which they call tags) to the actual value. This is to be able to more easily extend it than if it would transfer data more like a struct with fixed offsets. So a message Point for instance would look something like this on a high level:
1 -> 100,
2 -> 500
Which then is interpreted as x=100, y=500 and label=not set. On a lower level, protobuf serializes this tag-value mapping in a highly compact format, which among other things, stores integers with variable-length encoding. The paragraph you quoted just highlights exactly this in the case of tags, which can be stored more compactly if they are < 16, but the same for instance holds for integer values in your protobuf definition.

Secure Random hex digits only

Trying to generate random digits with SecureRandom class of rails. Can we create a random number with SecureRandom.hex which includes only digits and no alphabets.
For example:
Instead of
SecureRandom.hex(4)
=> "95bf7267"
It should give
SecureRandom.hex(4)
=> "95237267"
Check out the api for SecureRandom: http://rails.rubyonrails.org/classes/ActiveSupport/SecureRandom.html
I believe you're looking for a different method: #random_number.
SecureRandom.random_number(a_big_number)
Since #hex returns a hexadecimal number, it would be unusual to ask for a random result that contained only numerical characters.
For basic use cases, it's simple enough to use #rand.
rand(9999)
Edited:
I'm not aware of a library that generates a random number of specified length, but it seems simple enough to write one. Here's my pass at it:
def rand_by_length(length)
rand((9.to_s * length).to_i).to_s.center(length, rand(9).to_s).to_i
end
The method #rand_by_length takes an integer specifying length as a param and tries to generate a random number of max digits based on the length. String#center is used to pad the missing numbers with random number characters. Worst case calls #rand for each digit of specified length. That may serve your need.
Numeric id's are good because they are easier to read over the phone (no c for charlie).
Try this
length = 20
id = (SecureRandom.random_number * (10**length)).round.to_s # => "98075825200269950976"
and for bonus points break it up for easier reading
id.split(//).each_slice(4).to_a.map(&:join).join('-') # => "9807-5825-2002-6995-0976"
This will create a number of the desired length.
length = 11
rand(10**length..(10**length+1)-1).to_s
length = 4
[*'0'..'9'].sample(length).join
as simple as that :)

codeigniter form validation with phone numbers

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.

Resources