Удалить все символы из строки, чьи порядковые номера выходят за пределы допустимого диапазона

Каков хороший способ удалить все символы, выходящие за пределы диапазона: ordinal(128) из строки в python?

Я использую hashlib.sha256 в python 2.7. Я получаю исключение:

UnicodeEncodeError: кодек 'ascii' не может кодировать символ u'‎' в позиции 13: порядковый номер не в диапазоне (128)

Я предполагаю, что это означает, что какой-то странный символ попал в строку, которую я пытаюсь хэшировать.

Спасибо!


person Chris Dutrow    schedule 06.06.2012    source источник
comment
Вы должны просто использовать UTF8, а не ASCII   -  person SLaks    schedule 07.06.2012
comment
Это пример неправильного обращения с юникодом.   -  person Steven Rumbalski    schedule 07.06.2012


Ответы (3)


new_safe_str = some_string.encode('ascii','ignore') 

я думаю сработает

или вы могли бы сделать понимание списка

"".join([ch for ch in orig_string if ord(ch)<= 128])

[править] однако, как говорили другие, может быть лучше выяснить, как обращаться с юникодом в целом... если только вам действительно не нужно, чтобы он был закодирован как ascii по какой-то причине

person Joran Beasley    schedule 06.06.2012
comment
Это принятый ответ, потому что он единственный, который подойдет для моего варианта использования. Было бы неплохо заранее знать, что хеш-функция нуждается в дополнительном микроуправлении для правильной работы, но теперь, когда несколько миллионов записей в базе данных имеют вторичные ключи, использующие текущий метод хэширования, я не в состоянии изменить его. - person Chris Dutrow; 07.06.2012

Вместо того, чтобы удалять эти символы, было бы лучше использовать кодировку, от которой hashlib не задохнется, например, utf-8:

>>> data = u'\u200e'
>>> hashlib.sha256(data.encode('utf-8')).hexdigest()
'e76d0bc0e98b2ad56c38eebda51da277a591043c9bc3f5c5e42cd167abc7393e'
person Andrew Clark    schedule 06.06.2012

Это пример того, как изменения в python3 сделают улучшение или, по крайней мере, создадут более четкое сообщение об ошибке.

Python2

>>> import hashlib
>>> funky_string=u"You owe me £100"
>>> hashlib.sha256(funky_string)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 11: ordinal not in range(128)
>>> hashlib.sha256(funky_string.encode("utf-8")).hexdigest()
'81ebd729153b49aea50f4f510972441b350a802fea19d67da4792b025ab6e68e'
>>> 

Python3

>>> import hashlib
>>> funky_string="You owe me £100"
>>> hashlib.sha256(funky_string)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Unicode-objects must be encoded before hashing
>>> hashlib.sha256(funky_string.encode("utf-8")).hexdigest()
'81ebd729153b49aea50f4f510972441b350a802fea19d67da4792b025ab6e68e'
>>> 

Настоящая проблема заключается в том, что sha256 принимает последовательность байтов, о которой python2 не имеет четкого представления. Я бы предложил использовать .encode("utf-8").

person Nick Craig-Wood    schedule 06.06.2012