如今软件中的大多数字符串都是 Unicode 字符串。这意味着您可以包含数学符号、表情符号等。字母“M”有许多不同的版本,例如:罗马字母 M (U+004D) 在语义上与罗马数字 Ⅿ (U+216F) 不同,但它们通常具有相同的视觉表示。 John Cook 在Unicode 隐写术上发表了一篇有趣的文章:您可以利用这种歧义在普通视图中隐藏消息。例如,如果您需要警告某人您处于危险之中,您可以发送带有罗马数字 M 的文本。普通人阅读文本不会注意到其中的差异。
像 Microsoft.com 这样的 URL 怎么样?如果将罗马字母替换为罗马数字,它仍然是同一个域吗?
这是。 URL 解析器需要对 URL 进行规范化,其中包括用罗马字母替换相似的字母(如果它们要符合 WHATWG URL 规范)。
但他们真的吗? URL 解析器真的会做这项艰苦的工作吗?让我们检查一下。
爪哇。我无法让标准 Java 库将主机返回给我。它只是返回一个空字符串。
字符串url = " https://microsoft.coⅯ " ; URI uri =新的URI ( url ) ; 字符串主机= uri 。获取主机( ) ;
C# . .NET 库似乎只是按原样返回带有罗马数字的域。
字符串url = " https://microsoft.coⅯ " ; Uri uri =新的Uri ( url ) ; 字符串主机= uri 。主持人;
PHP 。标准 PHP 解释器仅按原样返回域,并带有罗马数字
$url = " https://microsoft.coⅯ " ; $parsed_url = parse_url ( $url ) ; 如果( $ parsed_url === false ) { echo “无法解析URL。 ” ; }别的{ $host = $parsed_url [ 'host' ] ; }
去。 Go 也不进行规范化。
urlString : = " https://microsoft.coⅯ " parsedURL ,错误: = url 。解析( url字符串) 如果错了! =零{ FMt 。 Println ( "无法解析 URL: " , err ) 返回 } 主机: =解析的 URL 。主持人
Python 。您猜对了:没有标准化。它很高兴地返回罗马数字。
url = “ https://microsoft.coⅯ ” parsed_url = urllib 。解析. url解析( url ) 主机= parsed_url 。网络锁
JavaScript . JavaScript 正确地做到了这一点。它将把 https://microsoft.coⅯ 转换为 https://microsoft.com。
const url = " https://microsoft.coⅯ " ; const urlObj =新URL ( url ) ; const主机= urlObj 。主机名;
C++ 。 C++ 没有标准的 URL 解析器,但是如果使用ada URL 解析器,将会得到正确的结果。如果您使用的是 Node.js 运行环境,则底层解析器是 C++ ada URL 解析库。
自动url = ada :: parse ( " https://microsoft.coⅯ " ) ; if ( ! url ) { /* 失败 */ } std :: string_view host = url - > get_host ( ) ;
原文: https://lemire.me/blog/2025/01/02/how-does-your-url-parser-handle-unicode/