在utf-8中编码哈希值

时间:2018-10-26 12:23:15

标签: python unicode utf-8 ascii

我想用一个哈希将一个子字符串归为一类-该子字符串包含非asasi字符,因此我尝试将其编码为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:

我想念什么?

EDIT _

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)

2 个答案:

答案 0 :(得分:1)

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

您有两个问题;一种是您现在要点击的,另一种是如果您修复了当前代码后就会点击的。

您的第一个问题是 line已经(显然是UTF-8编码字节)str ,而不是unicode ,因此encode使用Python的默认编码(ASCII;隐含地 decodes 进行解码)(;这不是我所知的语言环境,这是罕见的Python 2安装,它使用其他任何语言), >然后使用指定的编解码器(或未指定的默认编解码器)重新编码。基本上,line已经被UTF-8编码了,您让它再次将 编码为UTF-8,但这是没有意义的,因此Python尝试首先将decode用作ASCII,并且在它甚至尝试按照您的指示encode之前失败了。

此问题的解决方案是根本不encode line ;它已经是UTF-8编码的,所以您已经很黄金了。

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

原因:

import sys

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

的工作原理是(危险地)将隐式解码步骤更改为使用UTF-8,因此您所有的encode调用现在都使用UTF-8而不是ASCII执行隐式decodedecodeencode基本上是没有意义的,因为它所做的全部工作就是通过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是什么类型,因此您可以确定它是否确实为{{1} }或str,因为unicode表示您选择了错误的编解码器,而str表示您的输入不是预期的类型。

答案 1 :(得分:0)

我发现..在我眼中是一种解决方法。 虽然感觉不对,但确实可以。

import sys

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

我认为可以通过.encode('utf-8')

完成