首页 > 解决方案 > 以 utf-8 编码散列

问题描述

我想用哈希替换子字符串 - 所述子字符串包含非 ascii 字符,因此我尝试将其编码为 UTF-8。

result = re.sub(r'(Start:\s*)([^:]+)(:\s*)([^:]+)', lambda m: m.group(1) + m.group(2) + m.group(3) + hashlib.sha512(m.group(4).encode()).hexdigest(), line.encode('utf-8'))

我不确定为什么这不起作用,我想用 line.encode('utf-8'),整个字符串都被编码了。我还尝试将我的 m.groups 编码为 UTF-8,但我得到了相同的 UnicodeDecodeError。

[unicodedecodeerror:'ascii'编解码器无法解码位置序号不在范围内的字节(128)]

样本输入:

Start: myUsername: myÜsername:

我错过了什么?

编辑_

Traceback (most recent call last):
  File "C:/Users/Peter/Desktop/coding/filter.py", line 26, in <module>
    encodeline = line.encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 112: ordinal not in range(128)

标签: pythonunicodeutf-8ascii

解决方案


根据您的症状,您在 Python 2encode上运行。调用 Python 2str几乎总是荒谬的。

你有两个问题;一个你现在打的,一个如果你修复你当前的代码你会打的。

您的第一个问题已经line是(显然)UTF-8 编码字节str,而不是unicode,因此它使用 Python 的默认编码(ASCII;这不是我所知道的特定区域设置)encode隐式解码,它是一个罕见的 Python 2 安装使用其他任何东西),然后使用指定的编解码器(如果未指定,则使用默认值)重新编码。基本上,line已经是 UTF-8 编码,你告诉它再次编码为 UTF-8,但这是荒谬的,所以 Python 首先尝试作为 ASCII,并且在它甚至按照你的指示decode尝试之前就失败了。encode

这个问题的解决方案是根本encode line;它已经是 UTF-8 编码的,所以你已经是金色的了。

encode您的第二个问题(您还没有遇到,但您会遇到的)是您正在调用group(4)结果。但是当然,由于输入是 a str,所以组也是 a str,你会遇到同样的问题尝试encodea str; 由于该组来自原始 UTF-8 编码字节,因此它的非 ASCII 部分UnicodeDecodeError在编码之前的隐式解码步骤中导致 a。

原因:

import sys

reload(sys)
sys.setdefaultencoding('UTF8')

有效的是它(危险地)将隐式解码步骤更改为使用 UTF-8,因此您的所有encode调用现在都decode使用 UTF-8 而不是 ASCII 执行隐式解码;decodeandencode基本上是没有意义的,因为它所做的只是str在确认它是合法的 UTF-8 之后返回原件decode,否则它会充当昂贵的空操作。

要解决第二个问题,只需更改:

m.group(4).encode()

到:

m.group(4)

这使您的最终代码为:

result = re.sub(r'(Start:\s*)([^:]+)(:\s*)([^:]+)',
                lambda m: m.group(1) + m.group(2) + m.group(3) + hashlib.sha512(m.group(4)).hexdigest(),
                line)

或者,如果您想确认您的期望line实际上已经是 UTF-8 编码字节,请在该行上方re.sub添加以下内容:

try:
    line.decode('utf-8')
except Exception as e:
    sys.exit("line (of type {!r}) not decodable as UTF-8: {}".format(line.__class__.__name__, e))

如果给定的数据不是合法的 UTF-8,这将导致程序立即退出(并且还会让您知道是什么类型line,因此您可以确定它是否真的是stror unicode,因为str这意味着您选择了错误的编解码器,而unicode意味着您的输入不是预期的类型)。


推荐阅读