Python3将Unicode String转换为int表示

Eme*_*ald 7 python string unicode int python-3.x

众所周知,计算机使用数字.我正在输入此文本,服务器会输出一个数字,当您想要读取它时,您将从服务器获取文本.

我怎么能独自完成这个?

我想用我自己的算法加密一些东西,我的算法可以很好地处理整数,但现在我想加密一个字符串,我不知道如何将Unicode字符串转换为整数,反之亦然.

我正在使用Python 3.有没有人知道我的问题的优雅解决方案?

Mar*_*ers 13

我想你正在寻找这个ord()功能:

>>> ord('a')
97
>>> ord('\u00c2')
192
Run Code Online (Sandbox Code Playgroud)

这将为您提供Unicode代码点的整数.

要转换整个字符集,请使用列表解析:

>>> [ord(c) for c in 'Hello World!']
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]
Run Code Online (Sandbox Code Playgroud)

它的反面是chr()函数:

>>> chr(97)
'a'
>>> chr(193)
'Á'
Run Code Online (Sandbox Code Playgroud)

请注意,在加密最终解密文本时,通常将文本编码为具有字符编码的二进制表示.Unicode文本可以使用不同的编码进行编码,具有不同的优点和缺点.这些天最常用的Unicode文本UTF-8编码,但其他编码存在.

在Python 3中,二进制数据在bytes对象中表示,并使用该str.encode()方法将文本编码为字节,然后使用bytes.decode()以下命令返回:

>>> 'Hello World!'.encode('utf8')
b'Hello World!'
>>> b'Hello World!'.decode('utf8')
'Hello World!'
Run Code Online (Sandbox Code Playgroud)

bytes 值实际上只是序列,如列表,元组和字符串,但由0-255的整数组成:

>>> list('Hello World!'.encode('utf8'))
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]
Run Code Online (Sandbox Code Playgroud)

就个人而言,在加密时,您希望对结果字节进行编码和加密.

如果这一切看起来势不可挡或难以理解,那么这些关于Unicode和字符编码的文章可能会有所帮助:


pep*_*epr 12

将Unicode字符串转换为数字的常用方法是将其转换为字节序列.Unicode字符是纯抽象的,每个字符都有自己的编号; 但是,有更多方法可以将数字转换为字节流.可能最通用的方法是将字符串编码为UTF-8编码.您可以选择多种方法从中获取整数.这是一个(我从Ivella借来了很好的字符串 - 我希望里面没有坏词:):

Python 3.2.1 (default, Jul 10 2011, 20:02:51) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> s = "Hello, World, ?????, ??????, ???, ??"
>>> b = s.encode('utf-8')
>>> b
b'Hello, World, \xd8\xb9\xd8\xa7\xd9\x84\xd9\x8e\xd9\x85, \xde\x8b\xde\xaa\xde\x82\xde\xa8\xde\x94\xde\xac, \xe0\xa4\x9c\xe0\xa4\x97\xe0\xa4\xa4, \xe4\xb8\x96\xe7\x95\x8c'
Run Code Online (Sandbox Code Playgroud)

现在我们有字节序列,其中数字从128到255的那些显示为十六进制编码的转义序列.让我们将所有字节转换为十六进制代码作为字节串.

>>> import binascii
>>> h = binascii.hexlify(b)
>>> h
b'48656c6c6f2c20576f726c642c20d8b9d8a7d984d98ed9852c20de8bdeaade82dea8de94deac2c20e0a49ce0a497e0a4a42c20e4b896e7958c'
Run Code Online (Sandbox Code Playgroud)

我们可以将它看作是以十六进制表示法编写的大数字(如文本).将int允许我们把它转换为抽象的数字-印刷时-更通常转换为十进制格式.

>>> i = int(h, 16)
>>> i
52620351230730152682202055464811384749235956796562762198329268116226267262806875102376740945811764490696968801603738907493997296927348108
Run Code Online (Sandbox Code Playgroud)

现在,您可以将其存储为数字,对其进行加密(尽管加密较早的字节序列更常见),然后将其转换回整数.请注意,没有多少语言(可能没有数据库)能够处理大整数.

让我们回到原来的字符串.首先将其转换为十六进制表示(字符串).

>>> h2 = hex(i)
>>> h2
'0x48656c6c6f2c20576f726c642c20d8b9d8a7d984d98ed9852c20de8bdeaade82dea8de94deac2c20e0a49ce0a497e0a4a42c20e4b896e7958c'
>>> h3 = h2[2:]   # remove the 0x from the beginning
>>> h3
'48656c6c6f2c20576f726c642c20d8b9d8a7d984d98ed9852c20de8bdeaade82dea8de94deac2c20e0a49ce0a497e0a4a42c20e4b896e7958c'
>>> type(h3)
<class 'str'>
Run Code Online (Sandbox Code Playgroud)

我们不得不删除0x它,因为它只是说其余的是代表数字的十六进制字符.请注意,h3str类型.正如我们在Python 3中所见(参见顶部),str意味着Unicode字符串.下一步是将六进制数字对转换回字节.我们来试试吧unhexlify():

>>> binascii.unhexlify(h3)
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    binascii.unhexlify(h3)
TypeError: 'str' does not support the buffer interface
Run Code Online (Sandbox Code Playgroud)

哎呀!它只接受字节串​​.然后,将Unicode中的每个hexa数字编码为bytestring中的hexa数字.要走的路是编码; 但是,编码为ASCII是微不足道的.

>>> b2 = h3.encode('ascii')  # character by character; subset of ascii only
>>> b2
b'48656c6c6f2c20576f726c642c20d8b9d8a7d984d98ed9852c20de8bdeaade82dea8de94deac2c20e0a49ce0a497e0a4a42c20e4b896e7958c'
>>> b3 = binascii.unhexlify(b2)
>>> b3
b'Hello, World, \xd8\xb9\xd8\xa7\xd9\x84\xd9\x8e\xd9\x85, \xde\x8b\xde\xaa\xde\x82\xde\xa8\xde\x94\xde\xac, \xe0\xa4\x9c\xe0\xa4\x97\xe0\xa4\xa4, \xe4\xb8\x96\xe7\x95\x8c'
Run Code Online (Sandbox Code Playgroud)

现在我们有类似于第一个之后的字节串.encode('utf-8').让我们使用逆操作 - 从UTF-8解码.我们应该得到与我们开始时相同的Unicode字符串.

>>> s2 = b3.decode('utf-8')
>>> s2
'Hello, World, ?????, ??????, ???, ??'
>>> s == s2   # is the original equal to the result?
True
Run Code Online (Sandbox Code Playgroud)

:)


etu*_*rdu 6

从python的文档:

binascii模块包含了一些方法,以二进制和各种ASCII编码的二进制表示法之间的转换.

例如,您可以使用binascii.hexlify获取二进制字符串 "LOL" 的十六进制表示形式,并通过int内置函数将其转换为整数:

>>> binascii.hexlify(b"LOL")
b'4c4f4c'
>>> int(binascii.hexlify(b"LOL"), 16)
5001036
Run Code Online (Sandbox Code Playgroud)

由于您需要将此应用于unicode字符串,因此首先需要将它们编码为二进制字符串.您可以将此方法str.encode用于此目的:

>>> int(binascii.hexlify("fi?a?o".encode("utf-8")), 16)
7379646744164087151
Run Code Online (Sandbox Code Playgroud)

而已.

反之亦然,您需要反转每一步.首先以十六进制表示形式将整数转换为二进制字符串(您可以使用format(int, "x")然后对其进行编码),在ascii中转动十六进制binascii.unhexlify,最后解码为utf-8:

>>> binascii.unhexlify(format(7379646744164087151, "x").encode("utf-8")).decode("utf-8")
'fi?a?o'
Run Code Online (Sandbox Code Playgroud)

这是一个逐步的解释,如果你真的将使用这个设施,以功能的形式安排它们是一个好主意.