After hours of searching I find probably the best source of data
https://datahub.io/core/country-codesScript for data normalization in Powershell
$downloadedText = ($servers = Invoke-WebRequest -Uri "https://pkgstore.datahub.io/core/country-codes/country-codes_json/data/616b1fb83cbfd4eb6d9e7d52924bb00a/country-codes_json.json").Content
$csvContent = $downloadedText | ConvertFrom-Json
$parsed = $csvContent | Select-Object @{N="Code"; E={$_."ISO3166-1-Alpha-2"}}, @{N="Dial"; E={$_.Dial.Replace("-","")}} | Where-Object { -not ([string]::IsNullOrEmpty($_.Code) -or [string]::IsNullOrEmpty($_.Dial)) }
$parsed | ConvertTo-Json | Out-File "D:\DialCodes.json" -Encoding utf8
Data output example
[
{
"Code": "TW",
"Dial": "886"
},
{
"Code": "AF",
"Dial": "93"
},
......
]
And finally code example how to process data
namespace Example
{
public class DialCodes
{
// sorted from longest to shortest
private static SortedDictionary<string, string> _dialCodes = new SortedDictionary<string, string>(new DialCodeComparer());
private class DialCodeComparer : IComparer<string>
{
public int Compare(string x, string y) =>
(x.Length == y.Length) ? y.CompareTo(x) : y.Length.CompareTo(x.Length);
}
private struct CountryDialCode
{
public string Code { get; set; }
public string Dial { get; set; }
}
static DialCodes()
{
List<CountryDialCode> parsedData;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.DialCodes.json"))
{
using (var reader = new StreamReader(stream))
{
parsedData = JsonSerializer.Deserialize<List<CountryDialCode>>(reader.ReadToEnd());
}
}
foreach (var item in parsedData)
{
var splitted = item.Dial.Split(",");
foreach (var dial in splitted)
{
_dialCodes[dial] = item.Code;
}
}
}
public (string CountryCode, string DialCode, string LocalPart) ParsePhoneNumber(string phoneNumber)
{
int baseIndex = 0;
if (phoneNumber.StartsWith("00"))
{
baseIndex = 2;
}
else if (phoneNumber.StartsWith("+"))
{
baseIndex = 1;
}
if (baseIndex > 0)
{
foreach (var dialCode in _dialCodes)
{
int prefixLength = dialCode.Key.Length + baseIndex;
int index = baseIndex;
if (phoneNumber.Length >= prefixLength)
{
var found = true;
foreach (char c in dialCode.Key)
{
if (phoneNumber[index++] != c)
{
found = false;
break;
}
}
if (!found) continue;
return (
dialCode.Value,
phoneNumber.Substring(0, prefixLength),
phoneNumber.Substring(prefixLength)
);
}
}
}
return (null, null, phoneNumber);
}
}
}
Complete files are available on following link
https://bitbucket.org/petrik_systemart/workspace/snippets/exk5Gj