9 Commits

Author SHA1 Message Date
tate
50c1f3aa73 Update README.md 2021-11-29 14:03:02 +11:00
TateB
0f14f53ec4 updated to add morre homoglyphs + use english chars only 2021-11-29 13:40:18 +11:00
Vitaly Puzrin
7a61c5e20e 1.0.6 released 2020-05-18 08:06:29 +03:00
Vitaly Puzrin
87c8f30f3e dev deps bump 2020-05-18 08:04:21 +03:00
Vitaly Puzrin
9d6bc548cd Encode 2028 & 2029 chars in text form, close #7 2020-05-18 08:02:04 +03:00
Vitaly Puzrin
193738762a Mapping data update to v13.0.0 2020-05-18 07:30:45 +03:00
Vitaly Puzrin
af3e0a9b7c 1.0.5 released 2020-03-03 05:02:17 +03:00
Vitaly Puzrin
7ff0277276 Merge pull request #6 from turt2live/patch-1
Ship the TypeScript declarations too
2020-03-03 04:59:09 +03:00
Travis Ralston
d6ec78e7c1 Ship the TypeScript declarations too
TypeScript declarations were added, but unfortunately they didn't get put into the release because they weren't listed as a file.
2020-03-02 18:19:17 -07:00
8 changed files with 314 additions and 112 deletions

View File

@@ -1,3 +1,18 @@
1.0.6 / 2020-05-18
------------------
- Update mapping data to version 13.0.0
http://www.unicode.org/Public/security/latest/confusables.txt
- Encode `\u2028` & `\u2029` as text, #7.
- Dev deps bump.
1.0.5 / 2020-03-03
------------------
- Include missed TS definition into npm package.
1.0.4 / 2020-02-05 1.0.4 / 2020-02-05
------------------ ------------------

View File

@@ -6,7 +6,8 @@
> Replace all homoglyphs with base characters. Useful to detect similar strings. > Replace all homoglyphs with base characters. Useful to detect similar strings.
For example, to prohibit register similar looking nicknames at websites. For example, to prohibit register similar looking nicknames at websites.
Data source - [Recommended confusable mapping for IDN](http://www.unicode.org/Public/security/latest/confusables.txt), v12.1.0. Data source - [Recommended confusable mapping for IDN](http://www.unicode.org/Public/security/latest/confusables.txt), v13.0.0.
Similar letters array in addOther.js provided by [litruv](https://github.com/litruv) and [KillAllTheHippies](https://github.com/killallthehippies).
__Note!__ Text after transform is NOT intended be read by humans. For example, __Note!__ Text after transform is NOT intended be read by humans. For example,
`m` will be transformed to `r` + `n`. Goal is to compare 2 strings after `m` will be transformed to `r` + `n`. Goal is to compare 2 strings after
@@ -17,7 +18,7 @@ then transformed strings are equal.
## Install ## Install
```bash ```bash
npm install unhomoglyph --save npm i git+https://github.com/TateB/unhomoglyph.git
``` ```

44
addOther.js Normal file
View File

@@ -0,0 +1,44 @@
const fs = require('fs')
const path = require('path')
const savePath = path.join(__dirname, 'data.json')
var data = require('./data.json')
const similarLetters = [
{ eng: "a", alts: "₳АаДдӔӕА̊а̊А̄а̄ӒӓӐӑꙘꙙѦѧӘәa͏α𝓐𝓪𝐀🇦𝐚" },
{ eng: "b", alts: "฿БбВвЫыЪъЬь6Ҍҍb͏𝓑𝓫𝐁𝐛🇧" },
{ eng: "c", alts: "🇨₵Сс(ҪҫС́с́c͏¢𝓒𝓬𝐂𝐜" },
{ eng: "d", alts: "ĐԂԃ🇩Ԁԁd͏𝓓𝓭𝐃𝐝" },
{ eng: "e", alts: ЕеЁёЗ🇪зЭэЄ̈є̈Е̃е̃Е̄е̄Ё̄ё̄ӖӗЀѐԐԑЄєӠӡe͏𝓔𝓮𝐄𝐞" },
{ eng: "f", alts: "₣Ғғf͏𝓕🇫𝓯𝐅𝐟" },
{ eng: "g", alts: "₲Ԍԍg͏𝓖𝓰𝐆🇬𝐠" },
{ eng: "h", alts: "НⱧнӉӊҢңԨԩӇӈҺһԊԋ🇭h͏𝓗𝓱𝐇𝐡" },
{ eng: "i", alts: "l1ł|ӀӏЇїІіi͏ι𝓘𝓲🇮𝐈𝐢" },
{ eng: "j", alts: "Јјj͏Jנ𝓙𝓳𝐉𝐣🇯" },
{ eng: "k", alts: "КкҚқ₭ҜҝҞҟҠҡk͏𝓚𝓴𝐊🇰𝐤" },
{ eng: "l", alts: "l͏𝓛𝓵𝐋𝐥🇱" },
{ eng: "m", alts: "МмӍӎm͏𝓜𝓶𝐌𝐦🇲" },
{ eng: "n", alts: "ИиЙйЛлП₦пԤԥn͏𝓝𝓷𝐍𝐧🇳" },
{ eng: "o", alts: "ОоЮюФф0ӪØӫӦӧО̄о̄ꙔꙕѲѳѺѻꙪꙫꙨꙩꚚꚛӨө🇴o͏σ𝓞𝓸𝐎𝐨" },
{ eng: "p", alts: "РрР̌р̌Ҏҏp͏ρ𝓟𝓹𝐏🇵" },
{ eng: "q", alts: "g9q͏𝓠𝓺𝐐Q𝐪🇶" },
{ eng: "r", alts: гЯяԘԙԆԇԄԅr͏𝓡𝓻𝐑𝐫Ɽ🇷" },
{ eng: "s", alts: "5Ѕѕs͏𝓢𝓼𝐒𝐬🇸₴" },
{ eng: "t", alts: "ТтҬҭt͏𝓣𝓽𝐓𝐭₮🇹" },
{ eng: "u", alts: "vЦцꙠꙡu͏υ𝓤𝓾𝐔𝐮🇺Ʉ"},
{ eng: "v", alts: "ѶѷѴѵv͏ν𝓥𝓿𝐕𝐯🇻"},
{ eng: "w", alts: "ШшЩщꚆꚇѠѡԜԝw͏ω𝓦𝔀𝐖𝐰🇼₩" },
{ eng: "x", alts: "ХхҲҳӾӿӼӽx͏χ𝓧𝔁𝐗🇽𝐱" },
{ eng: "y", alts: "УуҮүЧчЦцӮӯӰӱЎўӲӳꚎꚏy͏🇾𝓨𝔂𝐘𝐲Ɏ" },
{ eng: "z", alts: "2ЗзЖжЗ́ж́z͏𝓩𝔃𝐙𝐳Ⱬ🇿" }
]
similarLetters.forEach((letter) => {
const alts = letter.alts.normalize('NFD').replace(/\p{Diacritic}/gu, "").replace(/[\u200B-\u200D\uFEFF\u034F]/g, '');
[...alts].forEach((alt) => {
data[alt.toLowerCase()] = letter.eng
})
})
fs.writeFileSync(savePath, JSON.stringify(data, null, 2))
console.log("Added alternatives")

339
data.json
View File

@@ -1,6 +1,10 @@
{ {
"0": "O", "0": "o",
"1": "l", "1": "i",
"2": "z",
"5": "s",
"6": "b",
"9": "q",
"֭": "֖", "֭": "֖",
"֮": "֘", "֮": "֘",
"֨": "֙", "֨": "֙",
@@ -665,7 +669,7 @@
"¯": "ˉ", "¯": "ˉ",
" ̄": "ˉ", " ̄": "ˉ",
"▔": "ˉ", "▔": "ˉ",
"ъ": "ˉb", "ъ": "b",
"ꙑ": "ˉbi", "ꙑ": "ˉbi",
"͵": "ˏ", "͵": "ˏ",
"˻": "˪", "˻": "˪",
@@ -841,6 +845,8 @@
"𐆠": "⳨", "𐆠": "⳨",
"♩": "𝅘𝅥", "♩": "𝅘𝅥",
"♪": "𝅘𝅥𝅮", "♪": "𝅘𝅥𝅮",
"⓪": "🄍",
"↺": "🄎",
"˙": "ॱ", "˙": "ॱ",
"ൎ": "ॱ", "ൎ": "ॱ",
"": "ー", "": "ー",
@@ -863,6 +869,7 @@
"ᅴ": "ー丨", "ᅴ": "ー丨",
"ㅢ": "ー丨", "ㅢ": "ー丨",
"ᆗ": "ー丨ᅮ", "ᆗ": "ー丨ᅮ",
"🄏": "$⃠",
"₤": "£", "₤": "£",
"〒": "₸", "〒": "₸",
"〶": "₸", "〶": "₸",
@@ -879,6 +886,7 @@
"𝟤": "2", "𝟤": "2",
"𝟮": "2", "𝟮": "2",
"𝟸": "2", "𝟸": "2",
"🯲": "2",
"": "2", "": "2",
"Ƨ": "2", "Ƨ": "2",
"Ϩ": "2", "Ϩ": "2",
@@ -921,6 +929,7 @@
"𝟥": "3", "𝟥": "3",
"𝟯": "3", "𝟯": "3",
"𝟹": "3", "𝟹": "3",
"🯳": "3",
"": "3", "": "3",
"Ȝ": "3", "Ȝ": "3",
"Ʒ": "3", "Ʒ": "3",
@@ -947,6 +956,7 @@
"𝟦": "4", "𝟦": "4",
"𝟰": "4", "𝟰": "4",
"𝟺": "4", "𝟺": "4",
"🯴": "4",
"": "4", "": "4",
"𑢯": "4", "𑢯": "4",
"۴": "٤", "۴": "٤",
@@ -963,6 +973,7 @@
"𝟧": "5", "𝟧": "5",
"𝟱": "5", "𝟱": "5",
"𝟻": "5", "𝟻": "5",
"🯵": "5",
"Ƽ": "5", "Ƽ": "5",
"𑢻": "5", "𑢻": "5",
"⑤": "➄", "⑤": "➄",
@@ -976,8 +987,9 @@
"𝟨": "6", "𝟨": "6",
"𝟲": "6", "𝟲": "6",
"𝟼": "6", "𝟼": "6",
"🯶": "6",
"": "6", "": "6",
"б": "6", "б": "b",
"": "6", "": "6",
"𑣕": "6", "𑣕": "6",
"۶": "٦", "۶": "٦",
@@ -994,6 +1006,7 @@
"𝟩": "7", "𝟩": "7",
"𝟳": "7", "𝟳": "7",
"𝟽": "7", "𝟽": "7",
"🯷": "7",
"𐓒": "7", "𐓒": "7",
"𑣆": "7", "𑣆": "7",
"⑦": "➆", "⑦": "➆",
@@ -1011,6 +1024,7 @@
"𝟪": "8", "𝟪": "8",
"𝟴": "8", "𝟴": "8",
"𝟾": "8", "𝟾": "8",
"🯸": "8",
"ȣ": "8", "ȣ": "8",
"Ȣ": "8", "Ȣ": "8",
"𐌚": "8", "𐌚": "8",
@@ -1030,6 +1044,7 @@
"𝟫": "9", "𝟫": "9",
"𝟵": "9", "𝟵": "9",
"𝟿": "9", "𝟿": "9",
"🯹": "9",
"": "9", "": "9",
"": "9", "": "9",
"𑣌": "9", "𑣌": "9",
@@ -1070,11 +1085,11 @@
"а": "a", "а": "a",
"ⷶ": "ͣ", "ⷶ": "ͣ",
"": "A", "": "A",
"𝐀": "A", "𝐀": "a",
"𝐴": "A", "𝐴": "A",
"𝑨": "A", "𝑨": "A",
"𝒜": "A", "𝒜": "A",
"𝓐": "A", "𝓐": "a",
"𝔄": "A", "𝔄": "A",
"𝔸": "A", "𝔸": "A",
"𝕬": "A", "𝕬": "A",
@@ -1106,7 +1121,7 @@
"ꜳ": "aa", "ꜳ": "aa",
"Ꜳ": "AA", "Ꜳ": "AA",
"æ": "ae", "æ": "ae",
"ӕ": "ae", "ӕ": "a",
"Æ": "AE", "Æ": "AE",
"Ӕ": "AE", "Ӕ": "AE",
"ꜵ": "ao", "ꜵ": "ao",
@@ -1146,10 +1161,10 @@
"": "b", "": "b",
"": "B", "": "B",
"": "B", "": "B",
"𝐁": "B", "𝐁": "b",
"𝐵": "B", "𝐵": "B",
"𝑩": "B", "𝑩": "B",
"𝓑": "B", "𝓑": "b",
"𝔅": "B", "𝔅": "B",
"𝔹": "B", "𝔹": "B",
"𝕭": "B", "𝕭": "B",
@@ -1178,7 +1193,7 @@
"Ƃ": "b̄", "Ƃ": "b̄",
"Б": "b̄", "Б": "b̄",
"ƀ": "b̵", "ƀ": "b̵",
"ҍ": "b̵", "ҍ": "b",
"Ҍ": "b̵", "Ҍ": "b̵",
"ѣ": "b̵", "ѣ": "b̵",
"Ѣ": "b̵", "Ѣ": "b̵",
@@ -1186,7 +1201,7 @@
"ᒁ": "ḃ·", "ᒁ": "ḃ·",
"ᒈ": "b'", "ᒈ": "b'",
"Ы": "bl", "Ы": "bl",
"в": "ʙ", "в": "b",
"ᏼ": "ʙ", "ᏼ": "ʙ",
"": "c", "": "c",
"": "c", "": "c",
@@ -1217,11 +1232,11 @@
"": "C", "": "C",
"": "C", "": "C",
"": "C", "": "C",
"𝐂": "C", "𝐂": "c",
"𝐶": "C", "𝐶": "C",
"𝑪": "C", "𝑪": "C",
"𝒞": "C", "𝒞": "C",
"𝓒": "C", "𝓒": "c",
"𝕮": "C", "𝕮": "C",
"𝖢": "C", "𝖢": "C",
"𝗖": "C", "𝗖": "C",
@@ -1237,16 +1252,18 @@
"𐌂": "C", "𐌂": "C",
"𐐕": "C", "𐐕": "C",
"𐔜": "C", "𐔜": "C",
"¢": "c̸", "¢": "c",
"ȼ": "c̸", "ȼ": "c̸",
"₡": "C⃫", "₡": "C⃫",
"🅮": "C⃠",
"ç": "c̦", "ç": "c̦",
"ҫ": "c̦", "ҫ": "c",
"Ç": "C̦", "Ç": "C̦",
"Ҫ": "C̦", "Ҫ": "C̦",
"Ƈ": "C'", "Ƈ": "C'",
"℅": "c/o", "℅": "c/o",
"℆": "c/u", "℆": "c/u",
"🅭": "㏄\t⃝",
"⋴": "ꞓ", "⋴": "ꞓ",
"ɛ": "ꞓ", "ɛ": "ꞓ",
"ε": "ꞓ", "ε": "ꞓ",
@@ -1262,8 +1279,8 @@
"𝞮": "ꞓ", "𝞮": "ꞓ",
"𝟄": "ꞓ", "𝟄": "ꞓ",
"ⲉ": "ꞓ", "ⲉ": "ꞓ",
"є": "", "є": "e",
"ԑ": "", "ԑ": "e",
"ꮛ": "ꞓ", "ꮛ": "ꞓ",
"𑣎": "ꞓ", "𑣎": "ꞓ",
"𐐩": "ꞓ", "𐐩": "ꞓ",
@@ -1294,11 +1311,11 @@
"": "d", "": "d",
"": "D", "": "D",
"": "D", "": "D",
"𝐃": "D", "𝐃": "d",
"𝐷": "D", "𝐷": "D",
"𝑫": "D", "𝑫": "D",
"𝒟": "D", "𝒟": "D",
"𝓓": "D", "𝓓": "d",
"𝔇": "D", "𝔇": "D",
"𝔻": "D", "𝔻": "D",
"𝕯": "D", "𝕯": "D",
@@ -1314,7 +1331,7 @@
"ɗ": "d̔", "ɗ": "d̔",
"ɖ": "d̨", "ɖ": "d̨",
"ƌ": "d̄", "ƌ": "d̄",
"đ": "d̵", "đ": "d",
"Đ": "D̵", "Đ": "D̵",
"Ð": "D̵", "Ð": "D̵",
"Ɖ": "D̵", "Ɖ": "D̵",
@@ -1364,10 +1381,10 @@
"": "E", "": "E",
"": "E", "": "E",
"": "E", "": "E",
"𝐄": "E", "𝐄": "e",
"𝐸": "E", "𝐸": "E",
"𝑬": "E", "𝑬": "E",
"𝓔": "E", "𝓔": "e",
"𝔈": "E", "𝔈": "E",
"𝔼": "E", "𝔼": "E",
"𝕰": "E", "𝕰": "E",
@@ -1391,12 +1408,12 @@
"𐊆": "E", "𐊆": "E",
"ě": "ĕ", "ě": "ĕ",
"Ě": "Ĕ", "Ě": "Ĕ",
"ɇ": "e̸", "ɇ": "e",
"Ɇ": "E̸", "Ɇ": "E̸",
"ҿ": "ę", "ҿ": "ę",
"ꭼ": "ᴇ", "ꭼ": "ᴇ",
"ə": "ǝ", "ə": "ǝ",
"ә": "ǝ", "ә": "a",
"∃": "Ǝ", "∃": "Ǝ",
"ⴺ": "Ǝ", "ⴺ": "Ǝ",
"ꓱ": "Ǝ", "ꓱ": "Ǝ",
@@ -1413,7 +1430,7 @@
"𐐁": "Ɛ", "𐐁": "Ɛ",
"ᶟ": "ᵋ", "ᶟ": "ᵋ",
"ᴈ": "ɜ", "ᴈ": "ɜ",
"з": "ɜ", "з": "z",
"ҙ": "ɜ̦", "ҙ": "ɜ̦",
"𐑂": "ɞ", "𐑂": "ɞ",
"ꞝ": "ʚ", "ꞝ": "ʚ",
@@ -1438,10 +1455,10 @@
"ք": "f", "ք": "f",
"𝈓": "F", "𝈓": "F",
"": "F", "": "F",
"𝐅": "F", "𝐅": "f",
"𝐹": "F", "𝐹": "F",
"𝑭": "F", "𝑭": "F",
"𝓕": "F", "𝓕": "f",
"𝔉": "F", "𝔉": "F",
"𝔽": "F", "𝔽": "F",
"𝕱": "F", "𝕱": "F",
@@ -1492,11 +1509,11 @@
"": "g", "": "g",
"ƍ": "g", "ƍ": "g",
"ց": "g", "ց": "g",
"𝐆": "G", "𝐆": "g",
"𝐺": "G", "𝐺": "G",
"𝑮": "G", "𝑮": "G",
"𝒢": "G", "𝒢": "G",
"𝓖": "G", "𝓖": "g",
"𝔊": "G", "𝔊": "G",
"𝔾": "G", "𝔾": "G",
"𝕲": "G", "𝕲": "G",
@@ -1517,7 +1534,7 @@
"ǥ": "g̵", "ǥ": "g̵",
"Ǥ": "G̵", "Ǥ": "G̵",
"Ɠ": "G'", "Ɠ": "G'",
"ԍ": "ɢ", "ԍ": "g",
"ꮐ": "ɢ", "ꮐ": "ɢ",
"ᏻ": "ɢ", "ᏻ": "ɢ",
"": "h", "": "h",
@@ -1541,10 +1558,10 @@
"": "H", "": "H",
"": "H", "": "H",
"": "H", "": "H",
"𝐇": "H", "𝐇": "h",
"𝐻": "H", "𝐻": "H",
"𝑯": "H", "𝑯": "H",
"𝓗": "H", "𝓗": "h",
"𝕳": "H", "𝕳": "H",
"𝖧": "H", "𝖧": "H",
"𝗛": "H", "𝗛": "H",
@@ -1575,11 +1592,11 @@
"Ħ": "H̵", "Ħ": "H̵",
"Ӊ": "H̦", "Ӊ": "H̦",
"Ӈ": "H̦", "Ӈ": "H̦",
"н": "ʜ", "н": "h",
"ꮋ": "ʜ", "ꮋ": "ʜ",
"ң": "ʜ̩", "ң": "h",
"ӊ": "ʜ̦", "ӊ": "h",
"ӈ": "ʜ̦", "ӈ": "h",
"Ԋ": "Ƕ", "Ԋ": "Ƕ",
"ꮀ": "ⱶ", "ꮀ": "ⱶ",
"Ͱ": "Ⱶ", "Ͱ": "Ⱶ",
@@ -1654,11 +1671,11 @@
"ϳ": "j", "ϳ": "j",
"ј": "j", "ј": "j",
"": "J", "": "J",
"𝐉": "J", "𝐉": "j",
"𝐽": "J", "𝐽": "J",
"𝑱": "J", "𝑱": "J",
"𝒥": "J", "𝒥": "J",
"𝓙": "J", "𝓙": "j",
"𝔍": "J", "𝔍": "J",
"𝕁": "J", "𝕁": "J",
"𝕵": "J", "𝕵": "J",
@@ -1694,11 +1711,11 @@
"𝚔": "k", "𝚔": "k",
"": "K", "": "K",
"": "K", "": "K",
"𝐊": "K", "𝐊": "k",
"𝐾": "K", "𝐾": "K",
"𝑲": "K", "𝑲": "K",
"𝒦": "K", "𝒦": "K",
"𝓚": "K", "𝓚": "k",
"𝔎": "K", "𝔎": "K",
"𝕂": "K", "𝕂": "K",
"𝕶": "K", "𝕶": "K",
@@ -1722,12 +1739,12 @@
"ƙ": "k̔", "ƙ": "k̔",
"Ⱪ": "K̩", "Ⱪ": "K̩",
"Қ": "K̩", "Қ": "K̩",
"₭": "", "₭": "k",
"Ꝁ": "K̵", "Ꝁ": "K̵",
"Ҟ": "K̵", "Ҟ": "K̵",
"Ƙ": "K'", "Ƙ": "K'",
"׀": "l", "׀": "l",
"|": "l", "|": "i",
"": "l", "": "l",
"": "l", "": "l",
"": "l", "": "l",
@@ -1740,15 +1757,16 @@
"𝟣": "l", "𝟣": "l",
"𝟭": "l", "𝟭": "l",
"𝟷": "l", "𝟷": "l",
"🯱": "l",
"I": "l", "I": "l",
"": "l", "": "l",
"": "l", "": "l",
"": "l", "": "l",
"": "l", "": "l",
"𝐈": "l", "𝐈": "i",
"𝐼": "l", "𝐼": "l",
"𝑰": "l", "𝑰": "l",
"𝓘": "l", "𝓘": "i",
"𝕀": "l", "𝕀": "l",
"𝕴": "l", "𝕴": "l",
"𝖨": "l", "𝖨": "l",
@@ -1800,10 +1818,10 @@
"𝈪": "L", "𝈪": "L",
"": "L", "": "L",
"": "L", "": "L",
"𝐋": "L", "𝐋": "l",
"𝐿": "L", "𝐿": "L",
"𝑳": "L", "𝑳": "L",
"𝓛": "L", "𝓛": "l",
"𝔏": "L", "𝔏": "L",
"𝕃": "L", "𝕃": "L",
"𝕷": "L", "𝕷": "L",
@@ -1823,7 +1841,7 @@
"𐔦": "L", "𐔦": "L",
"ﴼ": "l̋", "ﴼ": "l̋",
"ﴽ": "l̋", "ﴽ": "l̋",
"ł": "", "ł": "i",
"Ł": "L̸", "Ł": "L̸",
"ɭ": "l̨", "ɭ": "l̨",
"Ɨ": "l̵", "Ɨ": "l̵",
@@ -1907,10 +1925,10 @@
"": "M", "": "M",
"": "M", "": "M",
"": "M", "": "M",
"𝐌": "M", "𝐌": "m",
"𝑀": "M", "𝑀": "M",
"𝑴": "M", "𝑴": "M",
"𝓜": "M", "𝓜": "m",
"𝔐": "M", "𝔐": "M",
"𝕄": "M", "𝕄": "M",
"𝕸": "M", "𝕸": "M",
@@ -1954,11 +1972,11 @@
"ռ": "n", "ռ": "n",
"": "N", "": "N",
"": "N", "": "N",
"𝐍": "N", "𝐍": "n",
"𝑁": "N", "𝑁": "N",
"𝑵": "N", "𝑵": "N",
"𝒩": "N", "𝒩": "N",
"𝓝": "N", "𝓝": "n",
"𝔑": "N", "𝔑": "N",
"𝕹": "N", "𝕹": "N",
"𝖭": "N", "𝖭": "N",
@@ -1991,7 +2009,7 @@
"NJ": "NJ", "NJ": "NJ",
"№": "No", "№": "No",
"ͷ": "ᴎ", "ͷ": "ᴎ",
"и": "", "и": "n",
"𐑍": "ᴎ", "𐑍": "ᴎ",
"ņ": "ɲ", "ņ": "ɲ",
"": "o", "": "o",
@@ -2080,12 +2098,13 @@
"𝟢": "O", "𝟢": "O",
"𝟬": "O", "𝟬": "O",
"𝟶": "O", "𝟶": "O",
"🯰": "O",
"": "O", "": "O",
"𝐎": "O", "𝐎": "o",
"𝑂": "O", "𝑂": "O",
"𝑶": "O", "𝑶": "O",
"𝒪": "O", "𝒪": "O",
"𝓞": "O", "𝓞": "o",
"𝔒": "O", "𝔒": "O",
"𝕆": "O", "𝕆": "O",
"𝕺": "O", "𝕺": "O",
@@ -2119,15 +2138,15 @@
"Ǒ": "Ŏ", "Ǒ": "Ŏ",
"ۿ": "ô", "ۿ": "ô",
"Ő": "Ö", "Ő": "Ö",
"ø": "o̸", "ø": "o",
"ꬾ": "o̸", "ꬾ": "o̸",
"Ø": "O̸", "Ø": "O̸",
"ⵁ": "O̸", "ⵁ": "O̸",
"Ǿ": "Ó̸", "Ǿ": "Ó̸",
"ɵ": "o̵", "ɵ": "o̵",
"ꝋ": "o̵", "ꝋ": "o̵",
"ө": "o̵", "ө": "o",
"ѳ": "o̵", "ѳ": "o",
"ꮎ": "o̵", "ꮎ": "o̵",
"ꮻ": "o̵", "ꮻ": "o̵",
"⊖": "O̵", "⊖": "O̵",
@@ -2241,11 +2260,11 @@
"р": "p", "р": "p",
"": "P", "": "P",
"": "P", "": "P",
"𝐏": "P", "𝐏": "p",
"𝑃": "P", "𝑃": "P",
"𝑷": "P", "𝑷": "P",
"𝒫": "P", "𝒫": "P",
"𝓟": "P", "𝓟": "p",
"𝔓": "P", "𝔓": "P",
"𝕻": "P", "𝕻": "P",
"𝖯": "P", "𝖯": "P",
@@ -2284,7 +2303,7 @@
"𝞿": "ɸ", "𝞿": "ɸ",
"𝟇": "ɸ", "𝟇": "ɸ",
"ⲫ": "ɸ", "ⲫ": "ɸ",
"ф": "ɸ", "ф": "o",
"𝐪": "q", "𝐪": "q",
"𝑞": "q", "𝑞": "q",
"𝒒": "q", "𝒒": "q",
@@ -2302,11 +2321,11 @@
"գ": "q", "գ": "q",
"զ": "q", "զ": "q",
"": "Q", "": "Q",
"𝐐": "Q", "𝐐": "q",
"𝑄": "Q", "𝑄": "Q",
"𝑸": "Q", "𝑸": "Q",
"𝒬": "Q", "𝒬": "Q",
"𝓠": "Q", "𝓠": "q",
"𝔔": "Q", "𝔔": "Q",
"𝕼": "Q", "𝕼": "Q",
"𝖰": "Q", "𝖰": "Q",
@@ -2332,10 +2351,10 @@
"𝞳": "ĸ", "𝞳": "ĸ",
"𝟆": "ĸ", "𝟆": "ĸ",
"ⲕ": "ĸ", "ⲕ": "ĸ",
"к": "ĸ", "к": "k",
"ꮶ": "ĸ", "ꮶ": "ĸ",
"қ": "ĸ̩", "қ": "k",
"ҟ": "ĸ̵", "ҟ": "k",
"𝐫": "r", "𝐫": "r",
"𝑟": "r", "𝑟": "r",
"𝒓": "r", "𝒓": "r",
@@ -2359,10 +2378,10 @@
"": "R", "": "R",
"": "R", "": "R",
"": "R", "": "R",
"𝐑": "R", "𝐑": "r",
"𝑅": "R", "𝑅": "R",
"𝑹": "R", "𝑹": "R",
"𝓡": "R", "𝓡": "r",
"𝕽": "R", "𝕽": "R",
"𝖱": "R", "𝖱": "R",
"𝗥": "R", "𝗥": "R",
@@ -2376,20 +2395,20 @@
"": "R", "": "R",
"": "R", "": "R",
"𖼵": "R", "𖼵": "R",
"ɽ": "r̨", "ɽ": "r",
"ɼ": "r̩", "ɼ": "r̩",
"ɍ": "r̵", "ɍ": "r̵",
"ғ": "", "ғ": "f",
"ᵲ": "r̴", "ᵲ": "r̴",
"ґ": "r'", "ґ": "r'",
"𑣣": "rn", "𑣣": "rn",
"m": "rn", "m": "m",
"ⅿ": "rn", "ⅿ": "rn",
"𝐦": "rn", "𝐦": "m",
"𝑚": "rn", "𝑚": "rn",
"𝒎": "rn", "𝒎": "rn",
"𝓂": "rn", "𝓂": "rn",
"𝓶": "rn", "𝓶": "m",
"𝔪": "rn", "𝔪": "rn",
"𝕞": "rn", "𝕞": "rn",
"𝖒": "rn", "𝖒": "rn",
@@ -2399,13 +2418,13 @@
"𝙢": "rn", "𝙢": "rn",
"𝚖": "rn", "𝚖": "rn",
"𑜀": "rn", "𑜀": "rn",
"₥": "rn̸", "₥": "m",
"ɱ": "rn̦", "ɱ": "rn̦",
"ᵯ": "rn̴", "ᵯ": "rn̴",
"₨": "Rs", "₨": "Rs",
"ꭱ": "ʀ", "ꭱ": "ʀ",
"ꮢ": "ʀ", "ꮢ": "ʀ",
"я": "", "я": "r",
"ᵳ": "ɾ̴", "ᵳ": "ɾ̴",
"℩": "ɿ", "℩": "ɿ",
"": "s", "": "s",
@@ -2429,11 +2448,11 @@
"𑣁": "s", "𑣁": "s",
"𐑈": "s", "𐑈": "s",
"": "S", "": "S",
"𝐒": "S", "𝐒": "s",
"𝑆": "S", "𝑆": "S",
"𝑺": "S", "𝑺": "S",
"𝒮": "S", "𝒮": "S",
"𝓢": "S", "𝓢": "s",
"𝔖": "S", "𝔖": "S",
"𝕊": "S", "𝕊": "S",
"𝕾": "S", "𝕾": "S",
@@ -2494,11 +2513,11 @@
"": "T", "": "T",
"🝨": "T", "🝨": "T",
"": "T", "": "T",
"𝐓": "T", "𝐓": "t",
"𝑇": "T", "𝑇": "T",
"𝑻": "T", "𝑻": "T",
"𝒯": "T", "𝒯": "T",
"𝓣": "T", "𝓣": "t",
"𝔗": "T", "𝔗": "T",
"𝕋": "T", "𝕋": "T",
"𝕿": "T", "𝕿": "T",
@@ -2528,7 +2547,7 @@
"Ț": "Ţ", "Ț": "Ţ",
"Ʈ": "T̨", "Ʈ": "T̨",
"Ҭ": "T̩", "Ҭ": "T̩",
"₮": "T⃫", "₮": "t",
"ŧ": "t̵", "ŧ": "t̵",
"Ŧ": "T̵", "Ŧ": "T̵",
"ᵵ": "t̴", "ᵵ": "t̴",
@@ -2546,9 +2565,9 @@
"𝝉": "ᴛ", "𝝉": "ᴛ",
"𝞃": "ᴛ", "𝞃": "ᴛ",
"𝞽": "ᴛ", "𝞽": "ᴛ",
"т": "", "т": "t",
"ꭲ": "ᴛ", "ꭲ": "ᴛ",
"ҭ": "ᴛ̩", "ҭ": "t",
"ţ": "ƫ", "ţ": "ƫ",
"ț": "ƫ", "ț": "ƫ",
"Ꮏ": "ƫ", "Ꮏ": "ƫ",
@@ -2581,11 +2600,11 @@
"𑣘": "u", "𑣘": "u",
"": "U", "": "U",
"": "U", "": "U",
"𝐔": "U", "𝐔": "u",
"𝑈": "U", "𝑈": "U",
"𝑼": "U", "𝑼": "U",
"𝒰": "U", "𝒰": "U",
"𝓤": "U", "𝓤": "u",
"𝔘": "U", "𝔘": "U",
"𝕌": "U", "𝕌": "U",
"𝖀": "U", "𝖀": "U",
@@ -2651,11 +2670,11 @@
"٧": "V", "٧": "V",
"۷": "V", "۷": "V",
"": "V", "": "V",
"𝐕": "V", "𝐕": "v",
"𝑉": "V", "𝑉": "V",
"𝑽": "V", "𝑽": "V",
"𝒱": "V", "𝒱": "V",
"𝓥": "V", "𝓥": "v",
"𝔙": "V", "𝔙": "V",
"𝕍": "V", "𝕍": "V",
"𝖁": "V", "𝖁": "V",
@@ -2727,11 +2746,11 @@
"": "w", "": "w",
"𑣯": "W", "𑣯": "W",
"𑣦": "W", "𑣦": "W",
"𝐖": "W", "𝐖": "w",
"𝑊": "W", "𝑊": "W",
"𝑾": "W", "𝑾": "W",
"𝒲": "W", "𝒲": "W",
"𝓦": "W", "𝓦": "w",
"𝔚": "W", "𝔚": "W",
"𝕎": "W", "𝕎": "W",
"𝖂": "W", "𝖂": "W",
@@ -2746,12 +2765,12 @@
"": "W", "": "W",
"ѽ": "w҆҇", "ѽ": "w҆҇",
"𑓅": "ẇ", "𑓅": "ẇ",
"₩": "", "₩": "w",
"ꝡ": "w̦", "ꝡ": "w̦",
"ᴍ": "ʍ", "ᴍ": "ʍ",
"м": "ʍ", "м": "m",
"ꮇ": "ʍ", "ꮇ": "ʍ",
"ӎ": "ʍ̦", "ӎ": "m",
"": "x", "": "x",
"×": "x", "×": "x",
"": "x", "": "x",
@@ -2782,11 +2801,11 @@
"𑣬": "X", "𑣬": "X",
"": "X", "": "X",
"": "X", "": "X",
"𝐗": "X", "𝐗": "x",
"𝑋": "X", "𝑋": "X",
"𝑿": "X", "𝑿": "X",
"𝒳": "X", "𝒳": "X",
"𝓧": "X", "𝓧": "x",
"𝔛": "X", "𝔛": "X",
"𝕏": "X", "𝕏": "X",
"𝖃": "X", "𝖃": "X",
@@ -2849,11 +2868,11 @@
"": "y", "": "y",
"𑣜": "y", "𑣜": "y",
"": "Y", "": "Y",
"𝐘": "Y", "𝐘": "y",
"𝑌": "Y", "𝑌": "Y",
"𝒀": "Y", "𝒀": "Y",
"𝒴": "Y", "𝒴": "Y",
"𝓨": "Y", "𝓨": "y",
"𝔜": "Y", "𝔜": "Y",
"𝕐": "Y", "𝕐": "Y",
"𝖄": "Y", "𝖄": "Y",
@@ -2879,7 +2898,7 @@
"𑢤": "Y", "𑢤": "Y",
"𐊲": "Y", "𐊲": "Y",
"ƴ": "y̔", "ƴ": "y̔",
"ɏ": "y̵", "ɏ": "y",
"ұ": "y̵", "ұ": "y̵",
"¥": "Y̵", "¥": "Y̵",
"Ɏ": "Y̵", "Ɏ": "Y̵",
@@ -2887,7 +2906,7 @@
"ʒ": "ȝ", "ʒ": "ȝ",
"ꝫ": "ȝ", "ꝫ": "ȝ",
"ⳍ": "ȝ", "ⳍ": "ȝ",
"ӡ": "ȝ", "ӡ": "e",
"ჳ": "ȝ", "ჳ": "ȝ",
"𝐳": "z", "𝐳": "z",
"𝑧": "z", "𝑧": "z",
@@ -2910,11 +2929,11 @@
"": "Z", "": "Z",
"": "Z", "": "Z",
"": "Z", "": "Z",
"𝐙": "Z", "𝐙": "z",
"𝑍": "Z", "𝑍": "Z",
"𝒁": "Z", "𝒁": "Z",
"𝒵": "Z", "𝒵": "Z",
"𝓩": "Z", "𝓩": "z",
"𝖅": "Z", "𝖅": "Z",
"𝖹": "Z", "𝖹": "Z",
"𝗭": "Z", "𝗭": "Z",
@@ -2943,10 +2962,10 @@
"⁹": "ꝰ", "⁹": "ꝰ",
"ᴤ": "ƨ", "ᴤ": "ƨ",
"ϩ": "ƨ", "ϩ": "ƨ",
"ꙅ": "ƨ", "ꙅ": "s",
"ь": "ƅ", "ь": "b",
"ꮟ": "ƅ", "ꮟ": "ƅ",
"ы": "ƅi", "ы": "b",
"ꭾ": "ɂ", "ꭾ": "ɂ",
"ˤ": "ˁ", "ˤ": "ˁ",
"ꛍ": "ʡ", "ꛍ": "ʡ",
@@ -3030,7 +3049,7 @@
"𝞹": "π", "𝞹": "π",
"𝟉": "π", "𝟉": "π",
"ᴨ": "π", "ᴨ": "π",
"п": "π", "п": "n",
"∏": "Π", "∏": "Π",
"ℿ": "Π", "ℿ": "Π",
"𝚷": "Π", "𝚷": "Π",
@@ -5444,7 +5463,6 @@
"脧": "朘", "脧": "朘",
"望": "望", "望": "望",
"望": "望", "望": "望",
"朡": "朡",
"幐": "㬺", "幐": "㬺",
"䐠": "㬻", "䐠": "㬻",
"𣎓": "𣎓", "𣎓": "𣎓",
@@ -5869,6 +5887,7 @@
"脃": "脃", "脃": "脃",
"脾": "脾", "脾": "脾",
"䐋": "䐋", "䐋": "䐋",
"朡": "朡",
"𦞧": "𦞧", "𦞧": "𦞧",
"𦞵": "𦞵", "𦞵": "𦞵",
"朦": "䑃", "朦": "䑃",
@@ -6294,5 +6313,117 @@
"龜": "龜", "龜": "龜",
"⿔": "龜", "⿔": "龜",
"⻳": "龟", "⻳": "龟",
"⿕": "龠" "⿕": "龠",
"₳": "a",
"д": "a",
"ꙙ": "a",
"ѧ": "a",
"a": "a",
"🇦": "a",
"฿": "b",
"b": "b",
"": "b",
"🇧": "b",
"🇨": "c",
"₵": "c",
"(": "c",
"c": "c",
"ԃ": "d",
"🇩": "d",
"d": "d",
"": "d",
"∂": "d",
"🇪": "e",
"э": "e",
"e": "e",
"₣": "f",
"f": "f",
"": "f",
"🇫": "f",
"₲": "g",
"g": "q",
"🇬": "g",
"ⱨ": "h",
"ԩ": "h",
"ԋ": "h",
"🇭": "h",
"h": "h",
"l": "l",
"i": "i",
"🇮": "i",
"j": "j",
"נ": "j",
"🇯": "j",
"ҝ": "k",
"ҡ": "k",
"k": "k",
"": "k",
"🇰": "k",
"ⱡ": "l",
"🇱": "l",
"": "m",
"🇲": "m",
"л": "n",
"₦": "n",
"ԥ": "n",
"n": "n",
"": "n",
"🇳": "n",
"ю": "o",
"ꙕ": "o",
"ѻ": "o",
"ꙫ": "o",
"ꙩ": "o",
"ꚛ": "o",
"🇴": "o",
"o": "o",
"ҏ": "p",
"p": "p",
"₱": "p",
"🇵": "p",
"q": "q",
"": "q",
"🇶": "q",
"ԙ": "r",
"ԇ": "r",
"ԅ": "r",
"r": "r",
"": "r",
"🇷": "r",
"s": "s",
"🇸": "s",
"₴": "s",
"t": "t",
"": "t",
"🇹": "t",
"v": "v",
"ц": "y",
"ꙡ": "u",
"u": "u",
"": "u",
"🇺": "u",
"ʉ": "u",
"🇻": "v",
"ш": "w",
"щ": "w",
"ꚇ": "w",
"w": "w",
"": "w",
"ω": "w",
"🇼": "w",
"ҳ": "x",
"ӿ": "x",
"ӽ": "x",
"x": "x",
"χ": "x",
"🇽": "x",
"ч": "y",
"ꚏ": "y",
"y": "y",
"🇾": "y",
"ж": "z",
"z": "z",
"": "z",
"ⱬ": "z",
"🇿": "z"
} }

View File

@@ -14,7 +14,7 @@ function replace_fn(match) {
} }
function unhomoglyph(str) { function unhomoglyph(str) {
return str.replace(REPLACE_RE, replace_fn); return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, "").replace(/[\u200B-\u200D\uFEFF\u034F]/g, '').replace(REPLACE_RE, replace_fn).toLowerCase();
} }
module.exports = unhomoglyph; module.exports = unhomoglyph;

View File

@@ -1,6 +1,6 @@
{ {
"name": "unhomoglyph", "name": "unhomoglyph",
"version": "1.0.4", "version": "1.0.6",
"description": "Replace all homoglyphs with base characters.", "description": "Replace all homoglyphs with base characters.",
"keywords": [ "keywords": [
"homoglyph", "homoglyph",
@@ -10,7 +10,8 @@
"license": "MIT", "license": "MIT",
"files": [ "files": [
"index.js", "index.js",
"data.json" "data.json",
"index.d.ts"
], ],
"scripts": { "scripts": {
"lint": "eslint .", "lint": "eslint .",
@@ -18,7 +19,7 @@
"update": "node update.js && npm test" "update": "node update.js && npm test"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^6.6.0", "eslint": "^7.0.0",
"mocha": "^6.2.2" "mocha": "^7.1.2"
} }
} }

View File

@@ -26,4 +26,8 @@ describe('unhomoglyph', function () {
assert.strictEqual(unhomoglyph('1abcаа'), 'labcaa'); assert.strictEqual(unhomoglyph('1abcаа'), 'labcaa');
}); });
it('2028 & 2029 should be ok after replace in updater', function () {
assert.strictEqual(data['\u2028'], ' ');
assert.strictEqual(data['\u2029'], ' ');
});
}); });

View File

@@ -37,8 +37,14 @@ function save(str) {
result[src] = dst; result[src] = dst;
}); });
let output = JSON.stringify(result, null, ' ')
// Workaround for ES9 <=> ES10 inconsistency
// https://github.com/nodeca/unhomoglyph/issues/7
// https://github.com/facebook/hermes/issues/235#issuecomment-623606572
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
fs.writeFileSync(SAVE_PATH, JSON.stringify(result, null, ' ')); fs.writeFileSync(SAVE_PATH, output);
console.log('Done!'); console.log('Done!');
} }