{"id":31799979,"url":"https://github.com/janlelis/unicode-confusable","last_synced_at":"2025-10-10T22:57:29.777Z","repository":{"id":59158571,"uuid":"53736650","full_name":"janlelis/unicode-confusable","owner":"janlelis","description":"Unicode::Confusable.confusable? \"ℜսᖯʏ\", \"Ruby\"","archived":false,"fork":false,"pushed_at":"2025-09-09T14:46:00.000Z","size":302,"stargazers_count":75,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-10T00:36:03.181Z","etag":null,"topics":["confusables","ruby","script-confusable","unicode","unicode-data"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/janlelis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-12T14:48:21.000Z","updated_at":"2025-09-09T14:46:03.000Z","dependencies_parsed_at":"2024-06-20T21:48:59.302Z","dependency_job_id":"0c7c1152-0e6d-45ff-93c9-91882943fab4","html_url":"https://github.com/janlelis/unicode-confusable","commit_stats":{"total_commits":76,"total_committers":2,"mean_commits":38.0,"dds":0.4605263157894737,"last_synced_commit":"fbd012a77494d75e4fdf31d1ccb355120f9f27fa"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/janlelis/unicode-confusable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Funicode-confusable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Funicode-confusable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Funicode-confusable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Funicode-confusable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janlelis","download_url":"https://codeload.github.com/janlelis/unicode-confusable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlelis%2Funicode-confusable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005447,"owners_count":26083902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["confusables","ruby","script-confusable","unicode","unicode-data"],"created_at":"2025-10-10T22:57:28.724Z","updated_at":"2025-10-10T22:57:29.769Z","avatar_url":"https://github.com/janlelis.png","language":"Ruby","readme":"# Unicode::Confusable [![[version]](https://badge.fury.io/rb/unicode-confusable.svg)](https://badge.fury.io/rb/unicode-confusable)  [![[ci]](https://github.com/janlelis/unicode-confusable/workflows/Test/badge.svg)](https://github.com/janlelis/unicode-confusable/actions?query=workflow%3ATest)\n\nCompares two strings if they are visually confusable as described in [Unicode® Technical Standard #39](https://www.unicode.org/reports/tr39/#Confusable_Detection): Both strings get transformed into a skeleton format before comparing them. The skeleton is generated by normalizing the string ([NFD](http://unicode.org/reports/tr15/#Norm_Forms)), removing ignorable characters, replacing [confusable characters](https://unicode.org/Public/security/16.0.0/confusables.txt), and normalizing the string again.\n\nUnicode version: **17.0.0** (September 2025)\n\n\\* The Unicode normalization [depends on your Ruby version](https://idiosyncratic-ruby.com/73-unicode-version-mapping.html)\n\nPlease note: The TR39 standard now includes detection of confusables based on bidi formatting (i.e. right-to-left text). This is currently not supported by this gen.\n\nSupported Rubies: **3.x** (might stil work: **2.x**)\n\n## Usage\n\n### Confusable?\n\n```ruby\nrequire \"unicode/confusable\"\n\nUnicode::Confusable.confusable? \"a\", \"b\" # =\u003e false\nUnicode::Confusable.confusable? \"C\", \"С\" # =\u003e true\nUnicode::Confusable.confusable? \"ℜ𝘂ᖯʏ\", \"Ruby\" # =\u003e true\nUnicode::Confusable.confusable? \"Michael\", \"Michae1\" # =\u003e true\nUnicode::Confusable.confusable? \"⁇\", \"?\" # =\u003e false\nUnicode::Confusable.confusable? \"⁇\", \"??\" # =\u003e true\n```\n\n### Skeleton\n\n```ruby\nUnicode::Confusable.skeleton \"ℜ𝘂ᖯʏ\" # =\u003e \"Ruby\"\n```\n\n**Please note:** The skeleton is an intermediate representation, not meant for any other use than testing confusability, [according to the standard](https://www.unicode.org/reports/tr39/#Confusable_Detection).\n\n### List\n\nList all characters that map to the confusable exemplar given:\n\n```ruby\nUnicode::Confusable.list(\"o\", false)\n# =\u003e [\"ం\", \"ಂ\", \"ം\", \"ං\", \"०\", \"০\", \"੦\", \"૦\", \"୦\", \"௦\", \"౦\", \"൦\", \"๐\", \"໐\", \"၀\", \"០\", \"𑓐\", \"٥\", \"۵\", \"ｏ\", \"ℴ\", \"𝐨\", \"𝑜\", \"𝒐\", \"𝓸\", \"𝔬\", \"𝕠\", \"𝖔\", \"𝗈\", \"𝗼\", \"𝘰\", \"𝙤\", \"𝚘\", \"ᴏ\", \"ᴑ\", \"ꬽ\", \"ο\", \"𝛐\", \"𝜊\", \"𝝄\", \"𝝾\", \"𝞸\", \"σ\", \"𝛔\", \"𝜎\", \"𝝈\", \"𝞂\", \"𝞼\", \"ⲟ\", \"ϭ\", \"о\", \"ჿ\", \"օ\", \"ס\", \"ه\", \"𞸤\", \"𞹤\", \"𞺄\", \"ﻫ\", \"ﻬ\", \"ﻪ\", \"ﻩ\", \"ھ\", \"ﮬ\", \"ﮭ\", \"ﮫ\", \"ﮪ\", \"ہ\", \"ﮨ\", \"ﮩ\", \"ﮧ\", \"ﮦ\", \"ە\", \"ഠ\", \"ဝ\", \"𐓪\", \"𑣈\", \"𑣗\", \"𐐬\"]\n```\n\nIf you omit the second parameter, it will also show confusables, where the given character is just a part of:\n\n```ruby\nUnicode::Confusable.list(\"o\")\n# =\u003e [\"⒪\", \"ꜵ\", \"℅\", \"ᴔ\", \"ꭁ\", \"ꭂ\", \"ﷲ\", \"№\", \"ం\", \"ಂ\", \"ം\", \"ං\", \"०\", \"০\", \"੦\", \"૦\", \"୦\", \"௦\", \"౦\", \"൦\", \"๐\", \"໐\", \"၀\", \"០\", \"𑓐\", \"٥\", \"۵\", \"ｏ\", \"ℴ\", \"𝐨\", \"𝑜\", \"𝒐\", \"𝓸\", \"𝔬\", \"𝕠\", \"𝖔\", \"𝗈\", \"𝗼\", \"𝘰\", \"𝙤\", \"𝚘\", \"ᴏ\", \"ᴑ\", \"ꬽ\", \"ο\", \"𝛐\", \"𝜊\", \"𝝄\", \"𝝾\", \"𝞸\", \"σ\", \"𝛔\", \"𝜎\", \"𝝈\", \"𝞂\", \"𝞼\", \"ⲟ\", \"ϭ\", \"о\", \"ჿ\", \"օ\", \"ס\", \"ه\", \"𞸤\", \"𞹤\", \"𞺄\", \"ﻫ\", \"ﻬ\", \"ﻪ\", \"ﻩ\", \"ھ\", \"ﮬ\", \"ﮭ\", \"ﮫ\", \"ﮪ\", \"ہ\", \"ﮨ\", \"ﮩ\", \"ﮧ\", \"ﮦ\", \"ە\", \"ഠ\", \"ဝ\", \"𐓪\", \"𑣈\", \"𑣗\", \"𐐬\", \"ۿ\", \"ø\", \"ꬾ\", \"ɵ\", \"ꝋ\", \"ⲑ\", \"ө\", \"ѳ\", \"ꮎ\", \"ꮻ\", \"ꭴ\", \"ﳙ\", \"ơ\", \"œ\", \"ɶ\", \"∞\", \"ꝏ\", \"ꚙ\", \"ﳗ\", \"ﱑ\", \"ﳘ\", \"ﱒ\", \"ﶓ\", \"ﶔ\", \"ﱓ\", \"ﱔ\", \"ൟ\", \"თ\", \"တ\", \"ꭣ\", \"ﲠ\", \"ﳢ\", \"ﲥ\", \"ﳤ\", \"ﷻ\", \"ﴱ\", \"ﳨ\", \"ﴲ\", \"ﳪ\", \"ﷺ\", \"ﷷ\", \"ﳍ\", \"ﳖ\", \"ﳯ\", \"ﳞ\", \"ﳱ\", \"ﳦ\", \"ﲛ\", \"ﳠ\", \"ﯭ\", \"ﯬ\"]\n```\n\n## No Bidi-Confusable Check\n\nTesting for bidirectional confusables is currently not supported.\n\n## Single-script / Mixed-script / Whole-script\n\nTR 39 also describes mechanisms for further categorization of confusables. This is currently not part of this gem, however the [unicode-scripts gem](https://github.com/janlelis/unicode-scripts) does include mixed-script detection, which you can use for this purpose.\n\nSee [unicode-x](https://github.com/janlelis/unicode-x) for more Unicode related micro libraries.\n\n## MIT License\n\n- Copyright (C) 2016-2025 Jan Lelis \u003chttps://janlelis.com\u003e. Released under the MIT license.\n- Unicode data: https://www.unicode.org/copyright.html#Exhibit1\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlelis%2Funicode-confusable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanlelis%2Funicode-confusable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlelis%2Funicode-confusable/lists"}