表面一套背地一套的不止“阴阳合同”,最近,娱乐圈又出现了新的“阴阳话题”。


【资料图】

几天前,#易烊千玺决定放弃入职国话#话题冲上微博热搜,但是随后有网友发现,明明是一模一样的字,自己手动打出来的和上热搜的竟然不是同一个话题。

你是不是也被这段话搞懵了?

别怀疑,这不是“李逵”和“李鬼”的差别,在微博的默认字体下这两个话题一模一样,根本无法用肉眼辨认。但是在安卓系统下把默认字体换掉之后,就能看出热搜话题的“入”字不对劲。也有网友称,把两个“入”复制在新华字典APP里,热搜话题的“入”查不到,手动打出的则能正常查到。

为什么会出现这种情况?

用python读取字符代码之后,可以看到热搜里的“入”并不是中文常用字里的“入”(U+5165),因此未被字体库收录,连宋体、楷体、黑体等常见字体都没有收录这个字符,无论字体怎么变化,它永远停留在微软雅黑字体上。它也不是此前大家猜测的日文字,它的真身是康熙字典里的偏旁“入”(U+2F0A)

上图为康熙字典偏旁“入”,下图为汉字“入”|Unicode官方

阴阳话题瞒天过海、一套系统里有两个长相一致的真假“入”字……这些事在互联网的历史上其实不新鲜,用长相相似的字符骗用户上钩本身就是骗子们的压箱底技能。

防不胜防的高仿账号

难以区分的不只有“⼊(U+2F0A)”和“入(U+5165)”。打开Unicode官网,单在康熙部首的部分,容易和汉字混淆的字符就有一整页。

除此之外,还有很多存在于不同编码区的形近字。比如韩国地区的一些多音字,在编码时与原有的字集是分开的,Unicode甚至推出了一个中日韩兼容表意文字来囊括这些特例。

看上去和中文是同一个字,其实编码完全不同 | Wikipedia

这个编码方式兼顾了各种语言使用者的习惯,但带来的问题也显而易见:在电脑眼里,只要编码不同,系统就会认为是两个完全不一样的字,而在人类使用者看来,这些字符的外观完全相同。

这么大的漏洞,骗子当然不会白白放过。一种名叫同形异义词攻击(IDN homograph attack)的网络攻击方法因此而生。早期的骗子通过用0代替O、用1代替l之类的手法来迷惑用户,而升级版的Unicode同型字符换用则直接让人“瞎眼”。

比如,B站上其实有两个“老师好我叫何同学”,其中假何同学的名字中,“老师好”的“老(U+F934)”使用的是中日韩兼容表意文字中的编码

左:老(U+8001)师好我叫何同学,右:老(U+F934)师好我叫何同学。B站上的“真假”何同学,这堪称像素级的高仿号,人眼怎么可能认出来啊!| Bilibili

不只汉字遇到了这种问题,字母世界里的高仿骗子更离谱。

2017年,一款高仿App出现在谷歌官方的应用商店里。它直接伪装成了知名聊天软件WhatsApp(相当于美国微信)。开发者在软件名后面添加了一个不可见的Unicode字符,让它看起来和正规软件没有区别。这个操作直接骗过了100多万的用户,让它成为了最“成功”的恶意软件之一。

网址也逃不过“有人模仿我的脸”。随着国际化域名开放使用Unicode,你看到的“英文”也可能不是英文了!比如www.аррӏе.com这个网址,如果你复制到浏览器里,浏览器会告诉你……

这个看起来和苹果官方网站一模一样的网址,是计算机爱好者Xudong Zheng申请的。网址中的а(U+0430)不是英文字母,而是西里尔字母,只要点进去就会进入Xudong Zheng的“钓鱼网站”。类似的同形异义词攻击也常被用在垃圾邮件和病毒文件里

“罪魁祸首”Unicode

然而,这么“不科学”的Unicode,已经是人类现阶段最通用、最好的字符解决方案

要让计算机理解人类的语言文字,就需要建立人类与计算机之间相互理解的桥梁,也就是说需要一种将字符转换为数字的编码方式。

上世纪60年代,在计算机诞生之初,美国人采用了一种编码来表示英语以及各种符号。该编码只有一个字节,能表示256(2^8)个字符(8个二进制数),虽然只定义了128个字符,但已经足够涵盖大小写英文字母和一些常用符号,这就是大名鼎鼎的ASCII编码。

1972年之前使用的ASCII编码表,当时的电脑只认得这些字|wikipedia

然而随着计算机技术的发展,单纯的英文字符逐渐不够用了。汉语、法语、日语等各种语言的需求增加,每种新语言都需要新的字符。于是每个国家也都纷纷着手创建自己的编码方案,比如我国的GB 2312、GBK。

不同的国家和地区各自使用不同编码的结果,就是计算机每次都要安装不同的解码软件,一旦出现解码错误,用户就只能看到一堆乱码。

一些让人头大的乱码,网上冲浪够久总能见到

这时候,一些国际组织开始拟定统一的字符编码方案,为每种语言中的每个字符设定唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求,Unicode就是这么诞生的。在这种语言环境下,不需要再对文件进行单独解码,同屏里可以显示任何语言的内容。

Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。将字符转换为数字、字符编码可以简单理解为,将每个字符分配给一个数字,例如:a = 65,A = 97。如果这个编码是统一的,那全世界所有的计算机就都可以认识这些字符。

我们已经给每个字符分配了一个唯一的编码,那么如何使计算机认识这个编码呢?由于计算机只懂得0、1这样的二进制,最简单的方式就是直接将编码转换成2进制,例如:It’s 果壳的Unicode编码如下:

其对应的二进制为:

1991年Unicode发布之初,一共只支持7161个字符,虽然已经比128个ASCII编码多了不少,但仍然不足以满足全球用户的需求。在接下来的几十年里Unicode不断迭代,支持的语言更多,数量也激增至14万个,其中不仅有缅甸文、藏文这样经常被我们拿来做表情包的字符,甚至还包括麻将、易经卦象、多米诺骨牌牌面这样的非语言符号。

在添加Unicode时,需要秉承“统一性(Unification)”的准入原则,即把不同语言的同一书写系统(scripts)中相同的字符统一起来,因此中日韩文中相同的汉字的编码是一致的。但与此同时,丰富的语言中也包含着大量的形近字,比如西里尔字母中的一些字符就和英文字母高度相似,真的没什么好方法辨认,只能查看代码。

西里尔字母表|wikipedia

借我借我一双慧眼吧

虽然那英借来的慧眼不一定能帮上什么忙,但我们还是能用一些别的方法看破真相。

对于用Unicode浑水摸鱼的“冒牌”网站,各家浏览器已经开始将网址转换为统一的Ponycode代码进行显示了。而且对于这种高仿网站,浏览器自身也有了相应的比对和审核方法,并及时提醒用户可能存在的风险。

浏览器会将Unicode字符转换为统一的编码,在一定程度上抵抗钓鱼网站

对于高仿账号和页面上显示的文字,通过改变字体也可以快速找到猫腻。Unicode本身并不代表任何字体,最终文字的显示效果和系统的呈现方式有很大关系。因此,有些字体只会显示Unicode中的部分字符,那些没有适配的文字就会显得很不一样。

字体改为楷体时,第二个老字明显不一样了

不过换字体这一招也不是百试百灵。目前有很多网站为了统一风格,会在代码中指定显示的字体,不受用户改变自己系统字体的影响。所以遇到可疑的情况,最根本的方法还是得把文字复制下来,查询Unicode编码

用python3可以很简单地查到一个字符的Unicode编码,如下面的代码所示:

这段代码可以通过四个步骤来进行:

希望大家面对所谓的“阴阳热搜”不再困惑,在Unicode骗局面前用技术工具保护自己!

参考文献

[1]https://en.wikipedia.org/wiki/IDN_homograph_attackhttps://ieeexplore.ieee.org/document/8376

[2]https://medium.com/@wanxiao1994/unicode%E7%AD%89%E4%BB%B7%E6%80%A7%E4%B8%8E%E6%AD%A3%E8%A7%84%E5%8C%96-2eb50b343bc1

[3]https://www.unicode.org/reports/tr36/

[4]https://www.sohu.com/a/202557787_114760

[5]https://support.mailessentials.gfi.com/hc/en-us/articles/360015112900-Receiving-spam-in-unicode-character-sethttps://dl.acm.org/doi/10.1145/1299015.1299020

[6]https://www.xudongz.com/blog/2017/idn-phishing/

推荐内容