Initial version

master
Hans Viken Duedal 2019-07-12 21:48:08 +02:00
parent eb5d263dca
commit b50cf84e0a
12 changed files with 3972 additions and 0 deletions

42
.golangci.yaml Normal file
View File

@ -0,0 +1,42 @@
linters:
enable-all: true
disable:
- maligned
- prealloc
- gochecknoglobals
- gochecknoinits
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0
gocyclo:
min-complexity: 20
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
min-len: 2
min-occurrences: 2
misspell:
locale: US
lll:
line-length: 140
goimports:
local-prefixes: github.com/golangci/golangci-lint
gocritic:
enabled-tags:
- performance
- style
- experimental
disabled-checks:
- wrapperFunc
- unnamedResult
issues:
exclude-rules:
- text: "Binds to all network interfaces"
linters:
- gosec

25
README.md Normal file
View File

@ -0,0 +1,25 @@
# phone-iso3166
Maps an E.164 (international) phone number to the ISO-3166-1 alpha 2 (two letter) country code, associated with that number.
Also provides mapping for E.212 (mobile network codes, mcc+mnc) to the country.
It's based on it's python namesake [onlinecity/phone-iso3166](https://github.com/onlinecity/phone-iso3166) - but uses a [radix](https://github.com/hashicorp/go-immutable-radix) as it's datastructure.
### Performance
phone-iso3166 is reasonable fast
```
goos: darwin
goarch: amd64
pkg: github.com/onlinecity/go-phone-iso3166
BenchmarkE164Lookup-8 20000000 102 ns/op 16 B/op 1 allocs/op
BenchmarkE164LookupPrealloc-8 20000000 74.3 ns/op 0 B/op 0 allocs/op
BenchmarkE164LookupBuffer-8 20000000 105 ns/op 16 B/op 1 allocs/op
BenchmarkE164LookupString-8 20000000 61.5 ns/op 0 B/op 0 allocs/op
BenchmarkE164LookupBytes-8 30000000 53.8 ns/op 0 B/op 0 allocs/op
BenchmarkE164LookupNoExist-8 10000000 151 ns/op 16 B/op 1 allocs/op
BenchmarkE212Lookup-8 10000000 163 ns/op 3 B/op 1 allocs/op
```

13
cloudbuild.yaml Normal file
View File

@ -0,0 +1,13 @@
steps:
- name: 'golang:1.12-stretch'
entrypoint: 'bash'
args:
- '-c'
- >-
go build ./...;
wget -q -O - https://github.com/golangci/golangci-lint/releases/download/v$$GOLANGCI_VERSION/golangci-lint-$$GOLANGCI_VERSION-linux-amd64.tar.gz |
tar xzf -;
golangci-lint-$$GOLANGCI_VERSION-linux-amd64/golangci-lint run;
go test -v -bench=. -benchmem ./...
env:
- 'GOLANGCI_VERSION=1.17.1'

644
e164.go Normal file
View File

@ -0,0 +1,644 @@
// Code generated by gen/gen.py DO NOT EDIT.
// https://blog.golang.org/generate
package phoneiso3166
import iradix "github.com/hashicorp/go-immutable-radix"
func getE164() *iradix.Tree {
r := iradix.New()
t := r.Txn()
t.Insert([]byte("1201"), "US")
t.Insert([]byte("1202"), "US")
t.Insert([]byte("1203"), "US")
t.Insert([]byte("1204"), "CA")
t.Insert([]byte("1205"), "US")
t.Insert([]byte("1206"), "US")
t.Insert([]byte("1207"), "US")
t.Insert([]byte("1208"), "US")
t.Insert([]byte("1209"), "US")
t.Insert([]byte("1210"), "US")
t.Insert([]byte("1212"), "US")
t.Insert([]byte("1213"), "US")
t.Insert([]byte("1214"), "US")
t.Insert([]byte("1215"), "US")
t.Insert([]byte("1216"), "US")
t.Insert([]byte("1217"), "US")
t.Insert([]byte("1218"), "US")
t.Insert([]byte("1219"), "US")
t.Insert([]byte("1220"), "US")
t.Insert([]byte("1223"), "US")
t.Insert([]byte("1224"), "US")
t.Insert([]byte("1225"), "US")
t.Insert([]byte("1226"), "CA")
t.Insert([]byte("1227"), "US")
t.Insert([]byte("1228"), "US")
t.Insert([]byte("1229"), "US")
t.Insert([]byte("1231"), "US")
t.Insert([]byte("1234"), "US")
t.Insert([]byte("1236"), "CA")
t.Insert([]byte("1239"), "US")
t.Insert([]byte("1240"), "US")
t.Insert([]byte("1242"), "BS")
t.Insert([]byte("1246"), "BB")
t.Insert([]byte("1248"), "US")
t.Insert([]byte("1249"), "CA")
t.Insert([]byte("1250"), "CA")
t.Insert([]byte("1251"), "US")
t.Insert([]byte("1252"), "US")
t.Insert([]byte("1253"), "US")
t.Insert([]byte("1254"), "US")
t.Insert([]byte("1256"), "US")
t.Insert([]byte("1257"), "CA")
t.Insert([]byte("1260"), "US")
t.Insert([]byte("1262"), "US")
t.Insert([]byte("1263"), "CA")
t.Insert([]byte("1264"), "AI")
t.Insert([]byte("1267"), "US")
t.Insert([]byte("1268"), "AG")
t.Insert([]byte("1269"), "US")
t.Insert([]byte("1270"), "US")
t.Insert([]byte("1272"), "US")
t.Insert([]byte("1273"), "CA")
t.Insert([]byte("1274"), "US")
t.Insert([]byte("1276"), "US")
t.Insert([]byte("1281"), "US")
t.Insert([]byte("1283"), "US")
t.Insert([]byte("1284"), "VG")
t.Insert([]byte("1289"), "CA")
t.Insert([]byte("1301"), "US")
t.Insert([]byte("1302"), "US")
t.Insert([]byte("1303"), "US")
t.Insert([]byte("1304"), "US")
t.Insert([]byte("1305"), "US")
t.Insert([]byte("1306"), "CA")
t.Insert([]byte("1307"), "US")
t.Insert([]byte("1308"), "US")
t.Insert([]byte("1309"), "US")
t.Insert([]byte("1310"), "US")
t.Insert([]byte("1312"), "US")
t.Insert([]byte("1313"), "US")
t.Insert([]byte("1314"), "US")
t.Insert([]byte("1315"), "US")
t.Insert([]byte("1316"), "US")
t.Insert([]byte("1317"), "US")
t.Insert([]byte("1318"), "US")
t.Insert([]byte("1319"), "US")
t.Insert([]byte("1320"), "US")
t.Insert([]byte("1321"), "US")
t.Insert([]byte("1323"), "US")
t.Insert([]byte("1325"), "US")
t.Insert([]byte("1327"), "US")
t.Insert([]byte("1330"), "US")
t.Insert([]byte("1331"), "US")
t.Insert([]byte("1332"), "US")
t.Insert([]byte("1334"), "US")
t.Insert([]byte("1336"), "US")
t.Insert([]byte("1337"), "US")
t.Insert([]byte("1339"), "US")
t.Insert([]byte("1340"), "VI")
t.Insert([]byte("1341"), "US")
t.Insert([]byte("1343"), "CA")
t.Insert([]byte("1345"), "KY")
t.Insert([]byte("1346"), "US")
t.Insert([]byte("1347"), "US")
t.Insert([]byte("1351"), "US")
t.Insert([]byte("1352"), "US")
t.Insert([]byte("1353"), "US")
t.Insert([]byte("1354"), "CA")
t.Insert([]byte("1360"), "US")
t.Insert([]byte("1361"), "US")
t.Insert([]byte("1364"), "US")
t.Insert([]byte("1365"), "CA")
t.Insert([]byte("1367"), "CA")
t.Insert([]byte("1368"), "CA")
t.Insert([]byte("1369"), "US")
t.Insert([]byte("1380"), "US")
t.Insert([]byte("1382"), "CA")
t.Insert([]byte("1385"), "US")
t.Insert([]byte("1386"), "US")
t.Insert([]byte("1387"), "CA")
t.Insert([]byte("1401"), "US")
t.Insert([]byte("1402"), "US")
t.Insert([]byte("1403"), "CA")
t.Insert([]byte("1404"), "US")
t.Insert([]byte("1405"), "US")
t.Insert([]byte("1406"), "US")
t.Insert([]byte("1407"), "US")
t.Insert([]byte("1408"), "US")
t.Insert([]byte("1409"), "US")
t.Insert([]byte("1410"), "US")
t.Insert([]byte("1412"), "US")
t.Insert([]byte("1413"), "US")
t.Insert([]byte("1414"), "US")
t.Insert([]byte("1415"), "US")
t.Insert([]byte("1416"), "CA")
t.Insert([]byte("1417"), "US")
t.Insert([]byte("1418"), "CA")
t.Insert([]byte("1419"), "US")
t.Insert([]byte("1423"), "US")
t.Insert([]byte("1424"), "US")
t.Insert([]byte("1425"), "US")
t.Insert([]byte("1428"), "CA")
t.Insert([]byte("1430"), "US")
t.Insert([]byte("1431"), "CA")
t.Insert([]byte("1432"), "US")
t.Insert([]byte("1434"), "US")
t.Insert([]byte("1435"), "US")
t.Insert([]byte("1437"), "CA")
t.Insert([]byte("1438"), "CA")
t.Insert([]byte("1440"), "US")
t.Insert([]byte("1441"), "BM")
t.Insert([]byte("1442"), "US")
t.Insert([]byte("1443"), "US")
t.Insert([]byte("1447"), "US")
t.Insert([]byte("1450"), "CA")
t.Insert([]byte("1458"), "US")
t.Insert([]byte("1460"), "CA")
t.Insert([]byte("1463"), "US")
t.Insert([]byte("1464"), "US")
t.Insert([]byte("1468"), "CA")
t.Insert([]byte("1469"), "US")
t.Insert([]byte("1470"), "US")
t.Insert([]byte("1473"), "GD")
t.Insert([]byte("1474"), "CA")
t.Insert([]byte("1475"), "US")
t.Insert([]byte("1478"), "US")
t.Insert([]byte("1479"), "US")
t.Insert([]byte("1480"), "US")
t.Insert([]byte("1484"), "US")
t.Insert([]byte("1487"), "CA")
t.Insert([]byte("1501"), "US")
t.Insert([]byte("1502"), "US")
t.Insert([]byte("1503"), "US")
t.Insert([]byte("1504"), "US")
t.Insert([]byte("1505"), "US")
t.Insert([]byte("1506"), "CA")
t.Insert([]byte("1507"), "US")
t.Insert([]byte("1508"), "US")
t.Insert([]byte("1509"), "US")
t.Insert([]byte("1510"), "US")
t.Insert([]byte("1512"), "US")
t.Insert([]byte("1513"), "US")
t.Insert([]byte("1514"), "CA")
t.Insert([]byte("1515"), "US")
t.Insert([]byte("1516"), "US")
t.Insert([]byte("1517"), "US")
t.Insert([]byte("1518"), "US")
t.Insert([]byte("1519"), "CA")
t.Insert([]byte("1520"), "US")
t.Insert([]byte("1530"), "US")
t.Insert([]byte("1531"), "US")
t.Insert([]byte("1534"), "US")
t.Insert([]byte("1537"), "CA")
t.Insert([]byte("1539"), "US")
t.Insert([]byte("1540"), "US")
t.Insert([]byte("1541"), "US")
t.Insert([]byte("1548"), "CA")
t.Insert([]byte("1551"), "US")
t.Insert([]byte("1557"), "US")
t.Insert([]byte("1559"), "US")
t.Insert([]byte("1561"), "US")
t.Insert([]byte("1562"), "US")
t.Insert([]byte("1563"), "US")
t.Insert([]byte("1564"), "US")
t.Insert([]byte("1567"), "US")
t.Insert([]byte("1568"), "CA")
t.Insert([]byte("1570"), "US")
t.Insert([]byte("1571"), "US")
t.Insert([]byte("1573"), "US")
t.Insert([]byte("1574"), "US")
t.Insert([]byte("1575"), "US")
t.Insert([]byte("1579"), "CA")
t.Insert([]byte("1580"), "US")
t.Insert([]byte("1581"), "CA")
t.Insert([]byte("1582"), "US")
t.Insert([]byte("1584"), "CA")
t.Insert([]byte("1585"), "US")
t.Insert([]byte("1586"), "US")
t.Insert([]byte("1587"), "CA")
t.Insert([]byte("1600"), "CA")
t.Insert([]byte("1601"), "US")
t.Insert([]byte("1602"), "US")
t.Insert([]byte("1603"), "US")
t.Insert([]byte("1604"), "CA")
t.Insert([]byte("1605"), "US")
t.Insert([]byte("1606"), "US")
t.Insert([]byte("1607"), "US")
t.Insert([]byte("1608"), "US")
t.Insert([]byte("1609"), "US")
t.Insert([]byte("1610"), "US")
t.Insert([]byte("1612"), "US")
t.Insert([]byte("1613"), "CA")
t.Insert([]byte("1614"), "US")
t.Insert([]byte("1615"), "US")
t.Insert([]byte("1616"), "US")
t.Insert([]byte("1617"), "US")
t.Insert([]byte("1618"), "US")
t.Insert([]byte("1619"), "US")
t.Insert([]byte("1620"), "US")
t.Insert([]byte("1622"), "CA")
t.Insert([]byte("1623"), "US")
t.Insert([]byte("1626"), "US")
t.Insert([]byte("1627"), "US")
t.Insert([]byte("1628"), "US")
t.Insert([]byte("1629"), "US")
t.Insert([]byte("1630"), "US")
t.Insert([]byte("1631"), "US")
t.Insert([]byte("1636"), "US")
t.Insert([]byte("1639"), "CA")
t.Insert([]byte("1641"), "US")
t.Insert([]byte("1646"), "US")
t.Insert([]byte("1647"), "CA")
t.Insert([]byte("1649"), "TC")
t.Insert([]byte("1650"), "US")
t.Insert([]byte("1651"), "US")
t.Insert([]byte("1657"), "US")
t.Insert([]byte("1658"), "JM")
t.Insert([]byte("1659"), "US")
t.Insert([]byte("1660"), "US")
t.Insert([]byte("1661"), "US")
t.Insert([]byte("1662"), "US")
t.Insert([]byte("1664"), "MS")
t.Insert([]byte("1667"), "US")
t.Insert([]byte("1669"), "US")
t.Insert([]byte("1670"), "MP")
t.Insert([]byte("1671"), "US")
t.Insert([]byte("1672"), "CA")
t.Insert([]byte("1678"), "US")
t.Insert([]byte("1679"), "US")
t.Insert([]byte("1680"), "US")
t.Insert([]byte("1681"), "US")
t.Insert([]byte("1682"), "US")
t.Insert([]byte("1683"), "CA")
t.Insert([]byte("1684"), "US")
t.Insert([]byte("1689"), "US")
t.Insert([]byte("1701"), "US")
t.Insert([]byte("1702"), "US")
t.Insert([]byte("1703"), "US")
t.Insert([]byte("1704"), "US")
t.Insert([]byte("1705"), "CA")
t.Insert([]byte("1706"), "US")
t.Insert([]byte("1707"), "US")
t.Insert([]byte("1708"), "US")
t.Insert([]byte("1709"), "CA")
t.Insert([]byte("1710"), "US")
t.Insert([]byte("1712"), "US")
t.Insert([]byte("1713"), "US")
t.Insert([]byte("1714"), "US")
t.Insert([]byte("1715"), "US")
t.Insert([]byte("1716"), "US")
t.Insert([]byte("1717"), "US")
t.Insert([]byte("1718"), "US")
t.Insert([]byte("1719"), "US")
t.Insert([]byte("1720"), "US")
t.Insert([]byte("1721"), "SX")
t.Insert([]byte("1724"), "US")
t.Insert([]byte("1725"), "US")
t.Insert([]byte("1726"), "US")
t.Insert([]byte("1727"), "US")
t.Insert([]byte("1730"), "US")
t.Insert([]byte("1731"), "US")
t.Insert([]byte("1732"), "US")
t.Insert([]byte("1734"), "US")
t.Insert([]byte("1737"), "US")
t.Insert([]byte("1740"), "US")
t.Insert([]byte("1742"), "CA")
t.Insert([]byte("1743"), "US")
t.Insert([]byte("1747"), "US")
t.Insert([]byte("1753"), "CA")
t.Insert([]byte("1754"), "US")
t.Insert([]byte("1757"), "US")
t.Insert([]byte("1758"), "LC")
t.Insert([]byte("1760"), "US")
t.Insert([]byte("1762"), "US")
t.Insert([]byte("1763"), "US")
t.Insert([]byte("1764"), "US")
t.Insert([]byte("1765"), "US")
t.Insert([]byte("1767"), "DM")
t.Insert([]byte("1769"), "US")
t.Insert([]byte("1770"), "US")
t.Insert([]byte("1772"), "US")
t.Insert([]byte("1773"), "US")
t.Insert([]byte("1774"), "US")
t.Insert([]byte("1775"), "US")
t.Insert([]byte("1778"), "CA")
t.Insert([]byte("1779"), "US")
t.Insert([]byte("1780"), "CA")
t.Insert([]byte("1781"), "US")
t.Insert([]byte("1782"), "CA")
t.Insert([]byte("1784"), "VC")
t.Insert([]byte("1785"), "US")
t.Insert([]byte("1786"), "US")
t.Insert([]byte("1787"), "PR")
t.Insert([]byte("1801"), "US")
t.Insert([]byte("1802"), "US")
t.Insert([]byte("1803"), "US")
t.Insert([]byte("1804"), "US")
t.Insert([]byte("1805"), "US")
t.Insert([]byte("1806"), "US")
t.Insert([]byte("1807"), "CA")
t.Insert([]byte("1808"), "US")
t.Insert([]byte("1809"), "DO")
t.Insert([]byte("1810"), "US")
t.Insert([]byte("1812"), "US")
t.Insert([]byte("1813"), "US")
t.Insert([]byte("1814"), "US")
t.Insert([]byte("1815"), "US")
t.Insert([]byte("1816"), "US")
t.Insert([]byte("1817"), "US")
t.Insert([]byte("1818"), "US")
t.Insert([]byte("1819"), "CA")
t.Insert([]byte("1825"), "CA")
t.Insert([]byte("1828"), "US")
t.Insert([]byte("1829"), "DO")
t.Insert([]byte("1830"), "US")
t.Insert([]byte("1831"), "US")
t.Insert([]byte("1832"), "US")
t.Insert([]byte("1835"), "US")
t.Insert([]byte("1838"), "US")
t.Insert([]byte("1843"), "US")
t.Insert([]byte("1845"), "US")
t.Insert([]byte("1847"), "US")
t.Insert([]byte("1848"), "US")
t.Insert([]byte("1849"), "DO")
t.Insert([]byte("1850"), "US")
t.Insert([]byte("1851"), "CA")
t.Insert([]byte("1854"), "US")
t.Insert([]byte("1856"), "US")
t.Insert([]byte("1857"), "US")
t.Insert([]byte("1858"), "US")
t.Insert([]byte("1859"), "US")
t.Insert([]byte("1860"), "US")
t.Insert([]byte("1862"), "US")
t.Insert([]byte("1863"), "US")
t.Insert([]byte("1864"), "US")
t.Insert([]byte("1865"), "US")
t.Insert([]byte("1867"), "CA")
t.Insert([]byte("1868"), "TT")
t.Insert([]byte("1869"), "KN")
t.Insert([]byte("1870"), "US")
t.Insert([]byte("1871"), "CA")
t.Insert([]byte("1872"), "US")
t.Insert([]byte("1873"), "CA")
t.Insert([]byte("1876"), "JM")
t.Insert([]byte("1878"), "US")
t.Insert([]byte("1879"), "CA")
t.Insert([]byte("1901"), "US")
t.Insert([]byte("1902"), "CA")
t.Insert([]byte("1903"), "US")
t.Insert([]byte("1904"), "US")
t.Insert([]byte("1905"), "CA")
t.Insert([]byte("1906"), "US")
t.Insert([]byte("1907"), "US")
t.Insert([]byte("1908"), "US")
t.Insert([]byte("1909"), "US")
t.Insert([]byte("1910"), "US")
t.Insert([]byte("1912"), "US")
t.Insert([]byte("1913"), "US")
t.Insert([]byte("1914"), "US")
t.Insert([]byte("1915"), "US")
t.Insert([]byte("1916"), "US")
t.Insert([]byte("1917"), "US")
t.Insert([]byte("1918"), "US")
t.Insert([]byte("1919"), "US")
t.Insert([]byte("1920"), "US")
t.Insert([]byte("1925"), "US")
t.Insert([]byte("1928"), "US")
t.Insert([]byte("1929"), "US")
t.Insert([]byte("1930"), "US")
t.Insert([]byte("1931"), "US")
t.Insert([]byte("1934"), "US")
t.Insert([]byte("1935"), "US")
t.Insert([]byte("1936"), "US")
t.Insert([]byte("1937"), "US")
t.Insert([]byte("1938"), "US")
t.Insert([]byte("1939"), "PR")
t.Insert([]byte("1940"), "US")
t.Insert([]byte("1941"), "US")
t.Insert([]byte("1942"), "CA")
t.Insert([]byte("1947"), "US")
t.Insert([]byte("1949"), "US")
t.Insert([]byte("1951"), "US")
t.Insert([]byte("1952"), "US")
t.Insert([]byte("1954"), "US")
t.Insert([]byte("1956"), "US")
t.Insert([]byte("1959"), "US")
t.Insert([]byte("1970"), "US")
t.Insert([]byte("1971"), "US")
t.Insert([]byte("1972"), "US")
t.Insert([]byte("1973"), "US")
t.Insert([]byte("1975"), "US")
t.Insert([]byte("1978"), "US")
t.Insert([]byte("1979"), "US")
t.Insert([]byte("1980"), "US")
t.Insert([]byte("1984"), "US")
t.Insert([]byte("1985"), "US")
t.Insert([]byte("1986"), "US")
t.Insert([]byte("1989"), "US")
t.Insert([]byte("20"), "EG")
t.Insert([]byte("211"), "SS")
t.Insert([]byte("212"), "MA")
t.Insert([]byte("213"), "DZ")
t.Insert([]byte("216"), "TN")
t.Insert([]byte("218"), "LY")
t.Insert([]byte("220"), "GM")
t.Insert([]byte("221"), "SN")
t.Insert([]byte("222"), "MR")
t.Insert([]byte("223"), "ML")
t.Insert([]byte("224"), "GN")
t.Insert([]byte("225"), "CI")
t.Insert([]byte("226"), "BF")
t.Insert([]byte("227"), "NE")
t.Insert([]byte("228"), "TG")
t.Insert([]byte("229"), "BJ")
t.Insert([]byte("230"), "MU")
t.Insert([]byte("231"), "LR")
t.Insert([]byte("232"), "SL")
t.Insert([]byte("233"), "GH")
t.Insert([]byte("234"), "NG")
t.Insert([]byte("235"), "TD")
t.Insert([]byte("236"), "CF")
t.Insert([]byte("237"), "CM")
t.Insert([]byte("238"), "CV")
t.Insert([]byte("239"), "ST")
t.Insert([]byte("240"), "GQ")
t.Insert([]byte("241"), "GA")
t.Insert([]byte("242"), "CG")
t.Insert([]byte("243"), "CD")
t.Insert([]byte("244"), "AO")
t.Insert([]byte("245"), "GW")
t.Insert([]byte("246"), "DG")
t.Insert([]byte("247"), "SH")
t.Insert([]byte("248"), "SC")
t.Insert([]byte("249"), "SD")
t.Insert([]byte("250"), "RW")
t.Insert([]byte("251"), "ET")
t.Insert([]byte("252"), "SO")
t.Insert([]byte("253"), "DJ")
t.Insert([]byte("254"), "KE")
t.Insert([]byte("255"), "TZ")
t.Insert([]byte("256"), "UG")
t.Insert([]byte("257"), "BI")
t.Insert([]byte("258"), "MZ")
t.Insert([]byte("260"), "ZM")
t.Insert([]byte("261"), "MG")
t.Insert([]byte("262"), "RE")
t.Insert([]byte("263"), "ZW")
t.Insert([]byte("264"), "NA")
t.Insert([]byte("265"), "MW")
t.Insert([]byte("266"), "LS")
t.Insert([]byte("267"), "BW")
t.Insert([]byte("268"), "SZ")
t.Insert([]byte("269"), "KM")
t.Insert([]byte("27"), "ZA")
t.Insert([]byte("290"), "SH")
t.Insert([]byte("291"), "ER")
t.Insert([]byte("297"), "AW")
t.Insert([]byte("298"), "FO")
t.Insert([]byte("299"), "GL")
t.Insert([]byte("30"), "GR")
t.Insert([]byte("31"), "NL")
t.Insert([]byte("32"), "BE")
t.Insert([]byte("33"), "FR")
t.Insert([]byte("34"), "ES")
t.Insert([]byte("350"), "GI")
t.Insert([]byte("351"), "PT")
t.Insert([]byte("352"), "LU")
t.Insert([]byte("353"), "IE")
t.Insert([]byte("354"), "IS")
t.Insert([]byte("355"), "AL")
t.Insert([]byte("356"), "MT")
t.Insert([]byte("357"), "CY")
t.Insert([]byte("358"), "FI")
t.Insert([]byte("359"), "BG")
t.Insert([]byte("36"), "HU")
t.Insert([]byte("370"), "LT")
t.Insert([]byte("371"), "LV")
t.Insert([]byte("372"), "EE")
t.Insert([]byte("373"), "MD")
t.Insert([]byte("374"), "AM")
t.Insert([]byte("375"), "BY")
t.Insert([]byte("376"), "AD")
t.Insert([]byte("377"), "MC")
t.Insert([]byte("378"), "SM")
t.Insert([]byte("379"), "VA")
t.Insert([]byte("380"), "UA")
t.Insert([]byte("381"), "RS")
t.Insert([]byte("382"), "ME")
t.Insert([]byte("383"), "XK")
t.Insert([]byte("385"), "HR")
t.Insert([]byte("386"), "SI")
t.Insert([]byte("387"), "BA")
t.Insert([]byte("389"), "MK")
t.Insert([]byte("39"), "IT")
t.Insert([]byte("40"), "RO")
t.Insert([]byte("41"), "CH")
t.Insert([]byte("420"), "CZ")
t.Insert([]byte("421"), "SK")
t.Insert([]byte("423"), "LI")
t.Insert([]byte("43"), "AT")
t.Insert([]byte("44"), "GB")
t.Insert([]byte("45"), "DK")
t.Insert([]byte("46"), "SE")
t.Insert([]byte("47"), "NO")
t.Insert([]byte("48"), "PL")
t.Insert([]byte("49"), "DE")
t.Insert([]byte("500"), "FK")
t.Insert([]byte("501"), "BZ")
t.Insert([]byte("502"), "GT")
t.Insert([]byte("503"), "SV")
t.Insert([]byte("504"), "HN")
t.Insert([]byte("505"), "NI")
t.Insert([]byte("506"), "CR")
t.Insert([]byte("507"), "PA")
t.Insert([]byte("508"), "PM")
t.Insert([]byte("509"), "HT")
t.Insert([]byte("51"), "PE")
t.Insert([]byte("52"), "MX")
t.Insert([]byte("53"), "CU")
t.Insert([]byte("54"), "AR")
t.Insert([]byte("55"), "BR")
t.Insert([]byte("56"), "CL")
t.Insert([]byte("57"), "CO")
t.Insert([]byte("58"), "VE")
t.Insert([]byte("590"), "GP")
t.Insert([]byte("591"), "BO")
t.Insert([]byte("592"), "GY")
t.Insert([]byte("593"), "EC")
t.Insert([]byte("594"), "GF")
t.Insert([]byte("595"), "PY")
t.Insert([]byte("596"), "MQ")
t.Insert([]byte("597"), "SR")
t.Insert([]byte("598"), "UY")
t.Insert([]byte("599"), "CW")
t.Insert([]byte("60"), "MY")
t.Insert([]byte("61"), "AU")
t.Insert([]byte("62"), "ID")
t.Insert([]byte("63"), "PH")
t.Insert([]byte("64"), "NZ")
t.Insert([]byte("65"), "SG")
t.Insert([]byte("66"), "TH")
t.Insert([]byte("670"), "TL")
t.Insert([]byte("672"), "AQ")
t.Insert([]byte("673"), "BN")
t.Insert([]byte("674"), "NR")
t.Insert([]byte("675"), "PG")
t.Insert([]byte("676"), "TO")
t.Insert([]byte("677"), "SB")
t.Insert([]byte("678"), "VU")
t.Insert([]byte("679"), "FJ")
t.Insert([]byte("680"), "PW")
t.Insert([]byte("681"), "WF")
t.Insert([]byte("682"), "CK")
t.Insert([]byte("683"), "NU")
t.Insert([]byte("685"), "WS")
t.Insert([]byte("686"), "KI")
t.Insert([]byte("687"), "NC")
t.Insert([]byte("688"), "TV")
t.Insert([]byte("689"), "PF")
t.Insert([]byte("690"), "TK")
t.Insert([]byte("691"), "FM")
t.Insert([]byte("692"), "MH")
t.Insert([]byte("7"), "RU")
t.Insert([]byte("81"), "JP")
t.Insert([]byte("82"), "KR")
t.Insert([]byte("84"), "VN")
t.Insert([]byte("850"), "KP")
t.Insert([]byte("852"), "HK")
t.Insert([]byte("853"), "MO")
t.Insert([]byte("855"), "KH")
t.Insert([]byte("856"), "LA")
t.Insert([]byte("86"), "CN")
t.Insert([]byte("880"), "BD")
t.Insert([]byte("886"), "TW")
t.Insert([]byte("90"), "TR")
t.Insert([]byte("91"), "IN")
t.Insert([]byte("92"), "PK")
t.Insert([]byte("93"), "AF")
t.Insert([]byte("94"), "LK")
t.Insert([]byte("95"), "MM")
t.Insert([]byte("960"), "MV")
t.Insert([]byte("961"), "LB")
t.Insert([]byte("962"), "JO")
t.Insert([]byte("963"), "SY")
t.Insert([]byte("964"), "IQ")
t.Insert([]byte("965"), "KW")
t.Insert([]byte("966"), "SA")
t.Insert([]byte("967"), "YE")
t.Insert([]byte("968"), "OM")
t.Insert([]byte("971"), "AE")
t.Insert([]byte("972"), "IL")
t.Insert([]byte("973"), "BH")
t.Insert([]byte("974"), "QA")
t.Insert([]byte("975"), "BT")
t.Insert([]byte("976"), "MN")
t.Insert([]byte("977"), "NP")
t.Insert([]byte("98"), "IR")
t.Insert([]byte("992"), "TJ")
t.Insert([]byte("993"), "TM")
t.Insert([]byte("994"), "AZ")
t.Insert([]byte("995"), "GE")
t.Insert([]byte("996"), "KG")
t.Insert([]byte("998"), "UZ")
return t.Commit()
}

2912
e212.go Normal file

File diff suppressed because it is too large Load Diff

37
gen/e164.py Normal file
View File

@ -0,0 +1,37 @@
import phone_iso3166.e164
import io
import os
import sys
def generate(filename):
def transverse(node, path):
if isinstance(node, dict):
for k, v in node.items():
for i in transverse(v, path + str(k)):
yield i
else:
yield path, node
head = """// Code generated by gen/gen.py DO NOT EDIT.
// https://blog.golang.org/generate
package $GOPACKAGE
import iradix "github.com/hashicorp/go-immutable-radix"
func getE164() *iradix.Tree {
r := iradix.New()
t := r.Txn()
"""
head = head.replace(' ', "\t")
head = head.replace('$GOPACKAGE', os.environ['GOPACKAGE'])
with open(filename, 'w') as out:
out.write(head)
for prefix, country in transverse(phone_iso3166.e164.mapping, ''):
out.write(f"\tt.Insert([]byte(\"{prefix}\"), \"{country}\")\n")
out.write("\treturn t.Commit()\n")
out.write("}\n")
if __name__ == "__main__":
generate(sys.argv[1])

58
gen/e212.py Normal file
View File

@ -0,0 +1,58 @@
import phone_iso3166.e212
import phone_iso3166.e212_names
import io
import os
import sys
def generate(filename):
def transverse(node, path):
if isinstance(node, dict):
for k, v in node.items():
for i in transverse(v, path + str(k)):
yield i
else:
yield path, node
filehead = """// Code generated by gen/gen.py DO NOT EDIT.
package $GOPACKAGE
import iradix "github.com/hashicorp/go-immutable-radix"
type Operator struct {
Country string
Name string
}
type MncMap map[uint16]Operator
type MccMap map[uint16]MncMap
"""
filehead = filehead.replace(' ', "\t")
filehead = filehead.replace('$GOPACKAGE', os.environ['GOPACKAGE'])
with open(filename, 'w') as out:
out.write(filehead)
e212 = """
func getE212() *iradix.Tree {
r := iradix.New()
t := r.Txn()
"""
out.write(e212.replace(' ', "\t"))
for prefix, country in transverse(phone_iso3166.e212.networks, ''):
out.write(f"\tt.Insert([]byte(\"{prefix}\"), \"{country}\")\n")
out.write("\treturn t.Commit()\n")
out.write("}\n\n")
out.write("var OperatorMap = MccMap{\n")
for mcc, mncmap in phone_iso3166.e212_names.operators.items():
out.write(f"\t{mcc}: MncMap{{\n")
for mnc, oper in mncmap.items():
cc, name = oper
name = name.replace('"', '\\"')
out.write(f"\t\t{mnc}: {{\"{cc}\", \"{name}\"}},\n")
out.write(f"\t}},\n")
out.write("}\n")
if __name__ == "__main__":
generate(sys.argv[1])

1
gen/requirements.txt Normal file
View File

@ -0,0 +1 @@
phone-iso3166

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/onlinecity/go-phone-iso3166
go 1.12
require github.com/hashicorp/go-immutable-radix v1.1.0

6
go.sum Normal file
View File

@ -0,0 +1,6 @@
github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc=
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

62
lookup.go Normal file
View File

@ -0,0 +1,62 @@
package phoneiso3166
import (
"strconv"
iradix "github.com/hashicorp/go-immutable-radix"
)
//go:generate python3 gen/e164.py e164.go
//go:generate python3 gen/e212.py e212.go
type CountryRadix struct {
*iradix.Tree
}
type OperatorRadix struct {
*iradix.Tree
}
var E164 *CountryRadix
var E212 *OperatorRadix
func init() {
E164 = &CountryRadix{
getE164(),
}
E212 = &OperatorRadix{
getE212(),
}
}
func (r *CountryRadix) Lookup(msisdn uint64) string {
return r.LookupByteString([]byte(strconv.FormatUint(msisdn, 10)))
}
func (r *CountryRadix) LookupString(msisdn string) string {
return r.LookupByteString([]byte(msisdn))
}
func (r *CountryRadix) LookupByteString(msisdn []byte) string {
_, country, _ := r.Root().LongestPrefix(msisdn)
if country == nil {
return ""
}
return country.(string)
}
func (r *OperatorRadix) Lookup(mcc, mnc uint16) string {
c := strconv.FormatUint(uint64(mcc), 10)
n := strconv.FormatUint(uint64(mnc), 10)
_, country, _ := r.Root().LongestPrefix([]byte(c + n))
if country == nil {
return ""
}
return country.(string)
}
func NetworkName(mcc, mnc uint16) string {
if op, ok := OperatorMap[mcc][mnc]; ok {
return op.Name
}
return ""
}

167
lookup_test.go Normal file
View File

@ -0,0 +1,167 @@
package phoneiso3166
import (
"bytes"
"strconv"
"testing"
)
func TestCountry(t *testing.T) {
tests := []struct {
msisdn uint64
expect string
}{
{45, "DK"},
{4566118311, "DK"},
{38640118311, "SI"},
{38340118311, "XK"},
{37740118311, "MC"},
{1204, "CA"},
{12024561111, "US"}, // White house comment line
{14412921234, "BM"}, // Bermuda city hall
{0, ""},
}
for _, tt := range tests {
m := tt.msisdn
name := strconv.FormatUint(tt.msisdn, 10)
ex := tt.expect
t.Run(name, func(t *testing.T) {
res := E164.Lookup(m)
if res != ex {
t.Errorf(
"lookup(%d) returned %q, but expected %q",
m, res, ex,
)
}
})
}
}
const testNum uint64 = 4566118311
const testString = "4566118311"
func TestPrealloc(t *testing.T) {
var buf = make([]byte, 0, 16)
{
b := strconv.AppendUint(buf, testNum, 10)
if !bytes.Equal(b, []byte(testString)) {
t.Error("pre alloc fail")
t.Log(string(b))
}
}
{
b := strconv.AppendUint(buf, 4512345678, 10)
if !bytes.Equal(b, []byte("4512345678")) {
t.Error("pre alloc fail")
t.Log(string(b))
}
}
}
func BenchmarkE164Lookup(b *testing.B) {
for n := 0; n < b.N; n++ {
E164.Lookup(testNum)
}
}
// This option is interesting if you plan to lookup a lot of numbers
func BenchmarkE164LookupPrealloc(b *testing.B) {
var buf = make([]byte, 0, 16)
for n := 0; n < b.N; n++ {
E164.LookupByteString(
strconv.AppendUint(buf, testNum, 10),
)
}
}
func BenchmarkE164LookupBuffer(b *testing.B) {
var buf bytes.Buffer
for n := 0; n < b.N; n++ {
buf.Reset()
E164.LookupByteString(
strconv.AppendUint(buf.Bytes(), testNum, 10),
)
}
}
func BenchmarkE164LookupString(b *testing.B) {
for n := 0; n < b.N; n++ {
E164.LookupString(testString)
}
}
func BenchmarkE164LookupBytes(b *testing.B) {
m := []byte(testString)
for n := 0; n < b.N; n++ {
E164.LookupByteString(m)
}
}
func BenchmarkE164LookupNoExist(b *testing.B) {
for n := 0; n < b.N; n++ {
E164.Lookup(19820000000000)
}
}
func TestOperator(t *testing.T) {
tests := []struct {
mcc uint16
mnc uint16
expect string
}{
{238, 0, "DK"},
{340, 1, "GP"},
{340, 12, "MQ"},
{0, 0, ""},
}
for _, tt := range tests {
mcc := tt.mcc
mnc := tt.mnc
ex := tt.expect
m := strconv.FormatUint(uint64(tt.mcc), 10)
n := strconv.FormatUint(uint64(tt.mnc), 10)
t.Run(m+n, func(t *testing.T) {
res := E212.Lookup(mcc, mnc)
if res != ex {
t.Errorf(
"lookup(%d, %d) returned %q, but expected %q",
mcc, mnc, res, ex,
)
}
})
}
}
func BenchmarkE212Lookup(b *testing.B) {
for n := 0; n < b.N; n++ {
E212.Lookup(340, 12)
}
}
func TestOperatorName(t *testing.T) {
tests := []struct {
mcc uint16
mnc uint16
expect string
}{
{238, 1, "TDC A/S"},
{238, 0, ""},
{0, 0, ""},
}
for _, tt := range tests {
mcc := tt.mcc
mnc := tt.mnc
ex := tt.expect
m := strconv.FormatUint(uint64(tt.mcc), 10)
n := strconv.FormatUint(uint64(tt.mnc), 10)
t.Run(m+n, func(t *testing.T) {
res := NetworkName(mcc, mnc)
if res != ex {
t.Errorf(
"lookup(%d, %d) returned %q, but expected %q",
mcc, mnc, res, ex,
)
}
})
}
}