Python 用utf-8编码散列

Python 用utf-8编码散列,python,unicode,utf-8,ascii,Python,Unicode,Utf 8,Ascii,我想用一个散列来替换一个子字符串——所说的子字符串包含非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.enc

我想用一个散列来替换一个子字符串——所说的子字符串包含非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)
回溯(最近一次呼叫最后一次):
文件“C:/Users/Peter/Desktop/coding/filter.py”,第26行,在
encodeline=line.encode('utf-8')
UnicodeDecodeError:“ascii”编解码器无法解码位置112处的字节0xc3:序号不在范围内(128)

我发现。。在我看来,这是一个解决办法。 虽然感觉不对劲,但它确实起作用了

import sys

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

我认为可以使用.encode('utf-8')

根据您的症状,您正在运行Python 2。在Python2
str
上调用
encode
几乎总是毫无意义的

你有两个问题;一个是您现在正在点击的,另一个是如果您修复当前代码,您将点击的

您的第一个问题是
已经是一个
str
(显然)UTF-8编码字节
,而不是
unicode
,因此
编码
使用Python的默认编码(ASCII;据我所知,这不是特定于语言环境的,而且很少有Python 2安装使用其他任何东西),然后使用指定的编解码器(如果未指定,则使用默认编解码器)重新编码。基本上,
已经进行了UTF-8编码,您让它再次编码为UTF-8,但这是毫无意义的,因此Python尝试先将解码为ASCII,但在它尝试按照您的指示进行编码之前失败了

这个问题的解决办法就是根本不进行
编码
;它已经是UTF-8编码的,所以你已经是金色的了

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

原因是:

import sys

reload(sys)
sys.setdefaultencoding('UTF8')
工作原理是(危险地)将隐式解码步骤更改为使用UTF-8,因此所有
encode
调用现在都使用UTF-8而不是ASCII执行隐式
decode
decode
encode
基本上是毫无意义的,因为它所做的只是在通过
decode
对其进行解码以确认其合法的UTF-8之后返回原始的
str
,否则将成为昂贵的禁止操作

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

m.group(4).encode()
致:

最后的代码如下:

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
是什么类型,因此您可以确定它是
str
还是
unicode
,因为
str
意味着您选择了错误的编解码器,而
unicode
意味着您的输入不是预期的类型).

您能发布您提到的错误的示例输入和堆栈跟踪吗?(通常,您的问题似乎不是)。您是对的,对不起-我输入了更多信息这是Python 2还是Python 3代码?我强烈怀疑您的问题是您正在运行Python 2,并试图对
编码
a
str
(这在很大程度上是一件毫无意义的事情)。完整的回溯和a将是有帮助的。最后,可以肯定的是,将行拆分为每行只进行一次
encode
,例如
encodedline=line.encode('utf-8')
,然后替换
line.encode('utf-8'))
re.sub
encodedline
中,这样你就不能混淆哪个
encode
是问题所在。我正在运行python 2.7-有没有办法解决这个问题,或者我应该使用“黑客”?和平使者:黑客是个坏主意(
setdefaultencoding
在出于某种原因调用后从
sys
中删除;更改默认中间运行可能会导致各种库出现各种问题,这些库可能缓存了编码或其中的编码结果,并突然发现事情的运行方式与启动时不同)。我强烈怀疑您的代码将通过删除该行中对
encode
的所有调用来工作;您已经有了UTF-8编码数据,因此尝试
encode
再次是您问题的根源。请参阅。这只是一个黑客行为,但不是真正的解决方案。但是我们无法帮助您了解更多关于字符串等的信息
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))