为什么这些泰语字符显示在长尾的网页上?

时间:2011-08-19 08:48:22

标签: unicode zalgo

ด้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้дด็็็็็้้้้้็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้

我发现了一些有趣的字符,就像我粘贴在上面只占用3个空格。但是,字符串的实际长度为380。

我在python中检查了字符串,字符串编码如下:

  

'\ xe0 \ XB8 \ X94 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ XD0 \ XB4 \ xe0 \ XB8 \ X94 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \的x87 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89 \ xe0 \ xb9 \ X89'

字符串似乎是三个泰国字符的组合:

ด \xe0\xb8\x94  THAI CHARACTER DO DEK

้  \xe0\xb9\x89  THAI CHARACTER MAI THO

็  \xe0\xb9\x87  THAI CHARACTER MAITAIKHU

我的问题是:

  1. 为什么这些角色的行为如此不同,这是一个错误吗?
  2. 如何在网站中避免它(可能有一些html过滤器)?
  3. 更新

    我用更多的浏览器测试了这些字符,而长尾只出现在windows平台上的chrome和firefox中。

    以下是我拍摄的截图:

    赢得7 ie8 win 7 ie8


    ubuntu firefox ubuntu firefox


    赢得7铬 win 7 chrome


    赢得7火狐 win 7 firefox


    因此,我猜这是一个与浏览器相关的错误。

4 个答案:

答案 0 :(得分:8)

有两个问题,一个在输出系统(字体渲染器)中,它不是泰语识别的,一个在输入系统中首先生成此文本。

如果你已完成作业,你会知道mai tho和maitaikhu(UniCode名称)是UniCode所指的非间距标记(NSM)。这意味着在显示此字形时,字体渲染器不应移动到下一个字符单元格。

为了避免上面看到的混乱,Thai API Consortium(TAPIC)制定了WTT 2.0标准,该标准描述了字体渲染算法在接收泰语字母顺序作为输入时应该如何处理泰语字母顺序以及输入方法的方式如果你试图输入这些字符,应该允许输入这些字符。

Standardization and Implementations of Thai Language Overview

libthai包括输入和输出方法。

thaicheck是一个小程序,可以检测字母序列问题并修复它们。

顺便说一句,你不能有de dek,mai tho和maitaikhu的序列(单词);输入序列是噪音。

请记住,某些编辑器已经破坏了输入方法,这些方法允许键入多个无法组合的NSM,但输出方法只会呈现合法的序列;结果是一个非法的输入字符串,在他的系统上对用户看起来没问题。

答案 1 :(得分:4)

你提到的代码都是UTF-8,这就是每个字符需要3个字节的原因。尊重Unicode codes是:

后两个属于Mark, Nonspacing类,并且Combine属性(Canonical_Combining_Class)设置为107,这意味着代码点在渲染时与前面的代码点组合

您的示例以单个字符开头,并在其上添加了许多非间距标记。

与此C#代码比较:

char DODEK = (char)0x0e14;
char MAITHO = (char)0x0e49;
char MAITAIKHU = (char)0x0e47;

string thai = new string(new char[] { DODEK, MAITHO, MAITAIKHU });
Console.WriteLine("number of code points: " + thai.Length);

var si = new System.Globalization.StringInfo(thai);
Console.WriteLine("number of text elements: " + si.LengthInTextElements);

输出:

number of code points: 3
number of text elements: 1

另见.Net StringInfo class

答案 2 :(得分:3)

你永远不应该将数百个unicode字符组合成一个单独的图形字符,尽管unicode格式在技术上允许它;你通常组合不超过2或3个字符。

在泰语中,你有元音和音调标记,它们显示在辅音字符上方(有时元音出现在下方,甚至是在辅音字符周围......)。 它有点像法语(é,è...)中的元音或德语的变音符号。泰国有两个以上这样的标志是不正常的(法语或德语不止一个)。这意味着您的输入是非法的泰语文本(可能是为了提供一些有趣的图形效果而编写的,如“ASCII艺术”)。根据浏览器的不同,我对这种非法文本的解释方式并不感到惊讶。

答案 3 :(得分:1)

您所发现的内容称为Combining Characters或称为Zalgo的普通民众。

它的工作原理是因为Unicode允许通过添加diacritic marks after character来组合字符。

任何使用Unicode的系统都可以使用这些字符。