ASCII编码UTF-8的有效方法

时间:2010-04-02 14:59:01

标签: encoding utf-8 ascii punycode

我正在寻找一种简单有效的方法来存储ASCII-7中的UTF-8字符串。有效率我的意思是:

  • 输入中的所有ASCII字母数字字符应在输出中保持相同的ASCII字母数字字符
  • 结果字符串应尽可能短
  • 操作需要可以反转而不会丢失任何数据
  • 生成的ASCII字符串应不区分大小写
  • 输入长度应该没有限制
  • 应允许整个UTF-8范围

我的第一个想法是使用Punycode(IDNA),因为它符合前四个要求,但在最后两个要求失败。

有人可以推荐替代编码方案吗?如果有一些代码可供查看,那就更好了。

6 个答案:

答案 0 :(得分:4)

UTF-7,或稍微不那么透明,但更广泛,quoted-printable

  

输入中的所有ASCII字符应在输出中保留ASCII字符

(显然不完全可能,因为你至少需要一个字符作为逃脱。)

答案 1 :(得分:2)

由于ASCII涵盖了全部7位值,因此保留所有ASCII字符的编码方案长度为7位,并且无法对完整的Unicode范围进行编码。

编辑添加:

我想我现在明白你的要求了。您正在寻找一种在七位代码中编码UTF-8字符串的方法,其中,如果该编码字符串被解释为ASCII文本,那么字母字符的情况可以被任意修改,但是解码后的字符串将是与原始字节完全相同。

如果是这种情况,那么你最好的选择可能只是将原始的二进制表示编码为一串十六进制数字。我知道你正在寻找一个更紧凑的表示,但鉴于系统的其他限制,这是一个相当高的顺序,除非设计了一些自定义编码。

由于十六进制表示可以编码任意二进制值,因此可以通过在获取十六进制值之前压缩字符串来缩小字符串。

答案 2 :(得分:1)

如果你在谈论非标准方案 - MECE

答案 3 :(得分:0)

URL编码或数字字符引用是两种可能的选项。

答案 4 :(得分:0)

这取决于字符串中字符的分布。

Quoted-printable适用于大多数ASCII字符串,因为除了'='和控制字符之外没有开销。但是,非ASCII字符各占6-12个字节,因此如果您有很多这些字符,则需要考虑使用UTF-7或Base64。

答案 5 :(得分:0)

Punycode用于IDNA,但你可以在它施加的限制之外使用它

本身,Punycode不会失败你的最后2个要求:

>>> import sys
>>> _ = ("\U0010FFFF"*10000).encode("punycode")
>>> all(chr(c).encode("punycode") for c in range(sys.maxunicode))
True

(对于idna,python提供另一种同名编码)

显然,如果你没有为输入命名,那么编码后的字符串就不再是严格不区分大小写......但如果你只提供小写(或者如果你不关心解码的情况)你应该好好去