unicode - 源应该发送什么字符串来消除他们正在使用的字节编码的歧义?

标签 unicode encoding decoding

我将字节流解码为 un​​icode 字符,而不知道大约一百个发送者中每个人使用的编码。

许多发件人在技术上并不精明,无法告诉我他们正在使用什么编码。这将取决于他们用来生成数据的工具链的偶然性。

目前,发件人都是基于英国/英语的,使用各种操作系统。

我可以要求所有发件人向我发送一个特定的字符串,以明确地表明每个发件人正在使用什么编码吗?

我知道有些库使用启发式方法来猜测编码 - 我也会追查它,作为运行时后备,但首先我想尝试确定正在使用的编码,如果我可以。

(不认为这相关,但我正在使用 Python 工作)

最佳答案

这个问题的完整答案取决于很多因素,例如各种上游系统使用的编码范围,以及您的用户遵守在文本字段中输入魔术字符序列的说明的程度,以及熟练程度如何他们将使用晦涩的键盘组合来输入神奇的字符序列。

有一些非常简单的字符序列,只有某些用户才能输入。只有使用西里尔字母键盘和编码的用户会发现很容易键入“Ильи́ч”(Ilyich),因此您只需区分支持西里尔字母的编码,例如 UTF-8、UTF-16、iso8859_5 和 koi8_r。同样,您可以想出日语、中文和韩语字符序列来区分日语、简体中文、繁体中文和韩语系统的用户。

但是让我们关注西欧计算机系统的用户以及 ISO-8859-15、Mac_Roman、UTF-8、UTF-16LE 和 UTF-16BE 等常见编码。一个非常简单的测试是让用户输入欧元字符“€”、U+20AC,然后查看生成的字节序列:

  • byte ['\xa4'] 表示 iso-8859-15 编码
  • bytes ['\xe2', '\x82', '\xac'] 表示 utf-8 编码
  • 字节['\x00', '\xac']表示utf-16be编码
  • bytes ['\xac', '\x00'] 表示 utf-16le 编码
  • byte ['\x80'] 表示 cp1252(“Windows ANSI”)编码
  • byte ['\xdb']表示macroman编码
  • iso-8859-1 根本无法代表欧元字符。 iso-8859-15 是 iso-8859-1 的支持欧元的后继版本。
  • 美国用户可能不知道如何键入欧元字符。 (好吧,这太尖酸刻薄了。3% 的人会知道。)

您应该检查这些字节序列中的每一个(解释为任何可能的编码)不是用户可能自己键入的字符序列。例如,iso-8859-15 欧元符号的“\xa4”也可以是“¤”的 iso-8859-1 或 cp1252 或 UTF-16le 编码、“§”的 Macroman 编码或第一个字节数千个 UTF-16 字符中的任意一个,例如 U+A4xx Yi 音节或 U+01A4 拉丁小写字母 OI。它不是 UTF-8 序列的有效第一个字节。如果您的某些用户用 Yi 提交文本,您可能会遇到问题。

Python 3.x documentation, 7.2.3. Standard Encodings列出了 Python 标准库可以轻松处理的字符编码。以下程序可让您了解如何通过各种编码将测试字符序列编码为字节:

>>> for e in ['iso-8859-1','iso-8859-15', 'utf-8', 'utf-16be', 'utf-16le', \
... 'cp1252', 'macroman']:
...     print e, list( euro.encode(e, 'backslashreplace'))

因此,作为一种权宜之计、令人满意的技巧,如果编码存在任何问题,请考虑告诉用户键入“€”作为文本字段的第一个字符。然后您的系统应该将上述任何字节序列解释为编码线索,并丢弃它们。如果用户想要以欧元字符开始文本内容,则他们以“€€”开始字段;第一个被吞掉了,第二个仍然是文本的一部分。

关于unicode - 源应该发送什么字符串来消除他们正在使用的字节编码的歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12059957/

相关文章:

javascript - 如何解码 Minecraft 原理图 (nbt) 文件中的数据(即 block 状态)字节?

css - 如何在网站中添加马拉雅拉姆语 unicode 字体

python - 如何检查字符串中的 unicode 或转义序列?

mysql - PHPMyAdmin 不导入 unicode

validation - 验证假名输入

encoding - Flask 无法渲染变音符号

encoding - 为什么 ASCII 和 ISO-8859-1 编码没有成为历史?

encoding - 序言中的谓词编码

iOS 中的 FFmpeg、videotoolbox 和 avplayer

c++ - DirectShow 通用媒体解码器