-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathisPassportNumber.js
More file actions
101 lines (96 loc) · 3.67 KB
/
isPassportNumber.js
File metadata and controls
101 lines (96 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import assertString from './util/assertString';
/**
* Reference:
* https://en.wikipedia.org/ -- Wikipedia
* https://docs.microsoft.com/en-us/microsoft-365/compliance/eu-passport-number -- EU Passport Number
* https://countrycode.org/ -- Country Codes
*/
const passportRegexByCountryCode = {
AM: /^[A-Z]{2}\d{7}$/, // ARMENIA
AR: /^[A-Z]{3}\d{6}$/, // ARGENTINA
AT: /^[A-Z]\d{7}$/, // AUSTRIA
AU: /^[A-Z]\d{7}$/, // AUSTRALIA
AZ: /^[A-Z]{1}\d{8}$/, // AZERBAIJAN
BE: /^[A-Z]{2}\d{6}$/, // BELGIUM
BG: /^\d{9}$/, // BULGARIA
BR: /^[A-Z]{2}\d{6}$/, // BRAZIL
BY: /^[A-Z]{2}\d{7}$/, // BELARUS
CA: /^[A-Z]{2}\d{6}$|^[A-Z]\d{6}[A-Z]{2}$/, // CANADA
CH: /^[A-Z]\d{7}$/, // SWITZERLAND
CN: /^G\d{8}$|^E(?![IO])[A-Z0-9]\d{7}$/, // CHINA [G=Ordinary, E=Electronic] followed by 8-digits, or E followed by any UPPERCASE letter (except I and O) followed by 7 digits
CY: /^[A-Z](\d{6}|\d{8})$/, // CYPRUS
CZ: /^\d{8}$/, // CZECH REPUBLIC
DE: /^[CFGHJKLMNPRTVWXYZ0-9]{9}$/, // GERMANY
DK: /^\d{9}$/, // DENMARK
DZ: /^\d{9}$/, // ALGERIA
EE: /^([A-Z]\d{7}|[A-Z]{2}\d{7})$/, // ESTONIA (K followed by 7-digits), e-passports have 2 UPPERCASE followed by 7 digits
ES: /^[A-Z0-9]{2}([A-Z0-9]?)\d{6}$/, // SPAIN
FI: /^[A-Z]{2}\d{7}$/, // FINLAND
FR: /^\d{2}[A-Z]{2}\d{5}$/, // FRANCE
GB: /^\d{9}$/, // UNITED KINGDOM
GR: /^[A-Z]{2}\d{7}$/, // GREECE
HR: /^\d{9}$/, // CROATIA
HU: /^[A-Z]{2}(\d{6}|\d{7})$/, // HUNGARY
IE: /^[A-Z0-9]{2}\d{7}$/, // IRELAND
IN: /^[A-Z]{1}-?\d{7}$/, // INDIA
ID: /^[A-C]\d{7}$/, // INDONESIA
IR: /^[A-Z]\d{8}$/, // IRAN
IS: /^(A)\d{7}$/, // ICELAND
IT: /^[A-Z0-9]{2}\d{7}$/, // ITALY
JM: /^[Aa]\d{7}$/, // JAMAICA
JP: /^[A-Z]{2}\d{7}$/, // JAPAN
KR: /^[MS]\d{8}$/, // SOUTH KOREA, REPUBLIC OF KOREA, [S=PS Passports, M=PM Passports]
KZ: /^[a-zA-Z]\d{7}$/, // KAZAKHSTAN
LI: /^[a-zA-Z]\d{5}$/, // LIECHTENSTEIN
LT: /^[A-Z0-9]{8}$/, // LITHUANIA
LU: /^[A-Z0-9]{8}$/, // LUXEMBURG
LV: /^[A-Z0-9]{2}\d{7}$/, // LATVIA
LY: /^[A-Z0-9]{8}$/, // LIBYA
MT: /^\d{7}$/, // MALTA
MZ: /^([A-Z]{2}\d{7})|(\d{2}[A-Z]{2}\d{5})$/, // MOZAMBIQUE
MY: /^[AHK]\d{8}$/, // MALAYSIA
MX: /^\d{10,11}$/, // MEXICO
NL: /^[A-Z]{2}[A-Z0-9]{6}\d$/, // NETHERLANDS
NZ: /^([Ll]([Aa]|[Dd]|[Ff]|[Hh])|[Ee]([Aa]|[Pp])|[Nn])\d{6}$/, // NEW ZEALAND
PH: /^([A-Z](\d{6}|\d{7}[A-Z]))|([A-Z]{2}(\d{6}|\d{7}))$/, // PHILIPPINES
PK: /^[A-Z]{2}\d{7}$/, // PAKISTAN
PL: /^[A-Z]{2}\d{7}$/, // POLAND
PT: /^[A-Z]\d{6}$/, // PORTUGAL
RO: /^\d{8,9}$/, // ROMANIA
RU: /^\d{9}$/, // RUSSIAN FEDERATION
SE: /^\d{8}$/, // SWEDEN
SL: /^(P)[A-Z]\d{7}$/, // SLOVENIA
SK: /^[0-9A-Z]\d{7}$/, // SLOVAKIA
TH: /^[A-Z]{1,2}\d{6,7}$/, // THAILAND
TR: /^[A-Z]\d{8}$/, // TURKEY
UA: /^[A-Z]{2}\d{6}$/, // UKRAINE
US: /^\d{9}$|^[A-Z]\d{8}$/, // UNITED STATES
ZA: /^[TAMD]\d{8}$/, // SOUTH AFRICA
};
export const locales = Object.keys(passportRegexByCountryCode);
/**
* Check if str is a valid passport number
* relative to provided ISO Country Code.
*
* @param {string} str
* @param {string} countryCode
* @return {boolean}
*/
export default function isPassportNumber(str, countryCode) {
assertString(str);
/** Remove All Whitespaces, Convert to UPPERCASE */
const normalizedStr = str.replace(/\s/g, '').toUpperCase();
if (countryCode === 'any') {
for (const key in passportRegexByCountryCode) {
if (passportRegexByCountryCode.hasOwnProperty(key)) {
const regex = passportRegexByCountryCode[key];
if (regex.test(normalizedStr)) {
return true;
}
}
}
return false;
}
return (countryCode.toUpperCase() in passportRegexByCountryCode) &&
passportRegexByCountryCode[countryCode].test(normalizedStr);
}