首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测和修复不正确的字符编码

如何检测和修复不正确的字符编码
EN

Stack Overflow用户
提问于 2019-06-25 20:32:53
回答 4查看 4.8K关注 0票数 2

上游服务读取UTF-8字节流,假设它们是ISO-8859-1,将ISO-8859-1应用于UTF-8编码,并将它们发送给我的服务,标记为UTF-8。

上游服务超出了我的控制范围。他们可能会修复它,但它永远不会被修复。

我知道,我可以通过将UTF-8应用于ISO-8859-1编码来修复编码,然后将字节标记为UTF-8。但如果我的上游解决了他们的问题怎么办?

只有当我发现错误的编码时,才能检测到此问题并修复该编码吗?

我也不确定上游编码是ISO-8859-1。我认为上游是perl,所以编码是有意义的,当我应用ISO-8859-1编码时,我尝试过的每一个示例都是正确的。

当源将e4 9c 94 (✔)发送到我的上游时,我的上游就会向我发送c3 a2 c2 9c c2 94 (-)。

  • utf-8字符串作为字节:e4 9c 94
  • 字节e4 9c 94作为latin1字符串:â
  • utf-8字符串â作为字节: c3 a2 c2 9c c2 94

我可以使用upstream.encode('ISO-8859-1').force_encoding('UTF-8')修复它,但是一旦上游问题解决了,它就会中断。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-06-27 06:22:16

因为您知道它是如何损坏的,所以您可以尝试通过解码接收到的UTF-8字节,编码到latin1,然后再将其解码为UTF-8来解除它的损坏。只有你的损坏字符串,纯ASCII字符串,或非常不可能的拉丁-1字符串组合将成功解码两次。如果该解码失败,假设上游是固定的,并只是解码一次作为UTF-8.一个纯的ASCII字符串将正确地使用任何方法解码,因此也没有任何问题。有有效的UTF-8编码的序列,可以通过双解码,但它们不太可能发生在正常文本中。

下面是Python中的一个示例(您没有提到一种语言.):

代码语言:javascript
复制
# Assume bytes are latin1, but return encoded UTF-8.
def bad(b):
    return b.decode('latin1').encode('utf8')

# Assume bytes are UTF-8, and pass them along.
def good(b):
    return b

def decoder(b):
    try:
        return b.decode('utf8').encode('latin1').decode('utf8')
    except UnicodeError:
        return b.decode('utf8')

b = '✔'.encode('utf8')
print(decoder(bad(b)))
print(decoder(good(b)))

输出:

代码语言:javascript
复制
✔
✔
票数 3
EN

Stack Overflow用户

发布于 2019-06-27 06:39:21

裸ISO 8859-1几乎保证是无效的UTF-8.试图解码为ISO 8859-1,然后作为UTF-8,如果这产生无效的字节序列,返回到简单解码为UTF-8,应该适用于这种特殊情况。

更详细地说,UTF-8编码严格限制了哪些非ASCII字符序列是允许的.在ISO-8859-1中,允许的模式是非常不可能的,因为在这种编码中,它们表示类似于Ã这样的序列,后面跟着一个不可打印的控制字符或数学操作符,这在任何有效的文本中都不会出现。

票数 1
EN

Stack Overflow用户

发布于 2021-03-11 09:16:19

基于Mark Tolonen的回答,同样在Python 3中:

代码语言:javascript
复制
    def maybe_fix_encoding(utf8_string, possible_codec="cp1252"):
        """Attempts to fix mangled text caused by interpreting UTF8 as cp1252
        (or other codec: https://docs.python.org/3/library/codecs.html)"""
        try:
            return utf8_string.encode(possible_codec).decode('utf8')
        except UnicodeError:
            return utf8_string
代码语言:javascript
复制
>>> maybe_fix_encoding("some normal text and some scandinavian characters æ ø å Æ Ø Å")
'some normal text and some scandinavian characters æ ø å Æ Ø Å'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56761626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档