6

This is the problem I'm working with: given a phone number from anywhere in the world and some location information (state, province, possibly country name if I'm lucky, etc.), return the ISO country code for that number.

For the purposes of this question, I will not focus on the location information, as that provides an alternative solution to determining the country code which doesn't even need to use the phone number anymore (though, it would be useful for validation purposes)

When I first started working on the problem, I was hoping there was a deterministic way to figure this out because there was some sort of international standard out there. It became immediately apparent that one does not exist for phone numbers. There are standards within countries, between countries (NANP for example), but no unified international standard.

Playing around with libphonenumbers for a few days, it seems to be able to provide accurate validation of a phone number if I'm given a country code (eg: CA for Canada, GB for United Kingdom, etc).

The library provides two methods: isPossibleNumber, and isValidNumberForRegion. This is the code I'm using

boolean isValid;
PhoneNumber number;
PhoneNumberUtil util = PhoneNumberUtil.getInstance();

String numStr = "(123) 456-7890";
for (String r : util.getSupportedRegions())
{
    try {
        // check if it's a possible number
        isValid = util.isPossibleNumber(numStr, r);
        if (isValid)
        {
            number = util.parse(numStr, r);

            // check if it's a valid number for the given region
            isValid = util.isValidNumberForRegion(number, r);
            if (isValid)
                System.out.println(r + ": " + number.getCountryCode() + ", " + number.getNationalNumber());
        }
    } catch (NumberParseException e)
    {
        e.printStackTrace();
    }
}

So for example, if I took an arbitrary phone number like +44 20 7930 4832 and ran it through the method, I would get the following output

GB: 44, 2079304832

Now, that's assuming I'm given the dialing code (sometimes it's there). If I weren't given the dialing code, I might just get something like 20 7930 4832, and the results are not as pretty

DE: 49, 2079304832
US: 1, 2079304832
GB: 44, 2079304832
FI: 358, 2079304832
AX: 358, 2079304832
RS: 381, 2079304832
CN: 86, 2079304832
NZ: 64, 2079304832
IN: 91, 2079304832
IR: 98, 2079304832
JP: 81, 2079304832

Given a phone number, I can run it through all of the different rules for every country and filter the list down from 244 to around 20 or less if I'm lucky, but I'm not sure if there's anything else I could do to try and guess the country.

  • 2
    Why would guessing such a thing even be useful (or practical)? – Thomas Eding Feb 13 '14 at 21:16
  • Maybe you could use the spacing that separates the digits to help narrow it down. I've seen some places where the pattern is ### ### #### (used in North America), and other places the pattern may be ## #### #### (from your example, this pattern appears to be British). That would help you guess but it would only be "probably" - and if the inputs have had all their whitespace and other characters removed, that probably won't work. – FrustratedWithFormsDesigner Feb 13 '14 at 21:17
  • @ThomasEding are you asking whether country code is useful for anything, or whether using probabilistic methods is practical for real-world applications that require accurate results? – MxLDevs Feb 13 '14 at 21:20
  • @FrustratedWithFormsDesigner I didn't think about the format itself. Some inputs do remove all of the extra characters but others don't, so for the subset of inputs that preserve them this observation could be helpful. – MxLDevs Feb 13 '14 at 21:21
  • @MxyL: It will only work as well as the inputs. I could format a North American number as ##### ##### - the digits will still call someone in my city if I dial them, but it doesn't look like a "normally" formatted North American number. If you provide this to users, you might want to provide a warning in cases where you use this method to guess the country code. – FrustratedWithFormsDesigner Feb 13 '14 at 21:24
7

Telephone switches can figure this out, so there must be some method to the madness. And, in fact, there is:

Country codes are arranged in a tree, where you start at the root and descend into a subtree depending on the value of each digit. When you've reached a leaf node, you're at something that could be a country code. Any digits beyond those you've used to find a leaf node in a tree are would would have to be decoded according to the local numbering plan.

For example, the +1 country code is easy: it covers the North American Numbering Plan. Any number beginning with +1 will fall into that plan; there are no other countries within it with numbers like +12 or +123. If you want to know whether a +1 number is the U.S. or Canada, you'd have to look up the next three digits (the area code) in a table that will tell you that information. (Russia, Kazakhstan and a few other territories are the same way on the Russian numbering plan, which occupies the entire +7 branch.)

The +2 branch has ten sub-branches. All of +20 is Egypt, +27 is South Africa and +28 is unassigned. As above, no countries other than Egypt have a country code that starts with +20. The remaining seven prefixes are divided ten ways each. +21 is subdivided ten ways into +210 through +219 and covers countries like South Sudan, Morocco and Algeria. +22 is divided into +220 through +229 for The Gambia, Senegal, Mauritania, etc.

The tree you need for this can be easily generated from a list of the country codes and their countries.

|improve this answer|||||
2

[T]hese numbers aren't clients we're working with. They are the calls that our clients have made, which can be anyone, anywhere in the world. Depending on how the service provider chooses to format their data, we may or may not have all of the information we need.

Always ready to help the wire-tapping community! :D

On a more serious note, how much effort would you need to expend? Are the requirements on accuracy stringent, and do you need to mark how confident you are in the answer?

There are a number of heuristics I imagine could be useful.

  1. Narrow phone numbers down to cities/areas. If the phone number matches a city with 2 million people and a bunch of towns with 6k people, it's most likely from the country with the big city. (Perhaps the same can be done with the carriers?)

  2. Do you have a timestamp from the call? More likely that a call would happen close to business hours. That may make a few time zones less likely.

  3. Do you have the other phone number in the call? It may be that the callers are more likely to be in the same or neighbouring countries, or countries that share at least one language. Maybe not so useful, since you mention that your clients may call anyone across the globe.

  4. Do you have some sort of call history per client? If you can't narrow down a phone number, but it is possibly in a country that your client frequently communicates with, that's another mark up for that probability.

Maybe these extra guesses can narrow it down to three or five likely suspects. It remains a guessing game without the international prefix, though. Specifically, while each criterion may make it more likely to be country ABC, not matching the criteria doesn't make it impossible.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.