Python3转换Unicode字符串到int表示[关闭]

问题描述 投票:7回答:5

大家都知道,计算机工程与数字。现在我打字本文中,服务器提出了一些出来吧,当你想读它,你会从服务器获取文本。

我该怎么做我自己?

我要加密与我自己的算法的东西,我的算法正常工作与整数,但现在我要加密字符串,我不知道如何将Unicode字符串转换为整数,反之亦然。

我使用Python 3,是否有任何人谁知道我的问题一个优雅的解决方案?

python string unicode python-3.x int
5个回答
12
投票

您正在寻找ord() function,我认为:

>>> ord('a')
97
>>> ord('\u00c2')
192

这给你的Unicode的码点的整数。

要转换整个字符集合使用列表理解:

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

它的倒数即是chr() function

>>> chr(97)
'a'
>>> chr(193)
'Á'

请注意,当您加密解密结束的文字,你通常编码文本与character encoding二进制表示。 Unicode文本可以用不同的优点和缺点不同的编码进行编码。这些天最常用的编码Unicode文本UTF-8,但其他人存在。

在Python 3,二进制数据在bytes object中,您可编码的文字与str.encode() method字节,使用bytes.decode()回去:

>>> 'Hello World!'.encode('utf8')
b'Hello World!'
>>> b'Hello World!'.decode('utf8')
'Hello World!'

bytes值实际上只是序列,如列表和元组和字符串,而是从0-255包括整数的:

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

就个人而言,加密时,要编码和加密生成的字节。

如果这一切似乎势不可挡或难以遵循,也许对Unicode和字符编码这些文章可以帮忙:


11
投票

将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'

现在,我们有其中具有从128到255的数目的那些显示为十六进制编码的转义序列的字节序列。让我们所有的字节转换成他们hexcodes作为字节字符串。

>>> import binascii
>>> h = binascii.hexlify(b)
>>> h
b'48656c6c6f2c20576f726c642c20d8b9d8a7d984d98ed9852c20de8bdeaade82dea8de94deac2c20e0a49ce0a497e0a4a42c20e4b896e7958c'

我们可以把它看成在十六进制的书面(文字)一个巨大的数字。该int使我们能够将其转换为抽象的数字 - 印刷时 - 更通常转换为十进制格式。

>>> i = int(h, 16)
>>> i
52620351230730152682202055464811384749235956796562762198329268116226267262806875102376740945811764490696968801603738907493997296927348108

现在,你可以将它存储为一个数字,它加密(虽然它是比较平常字节更早的序列加密),后来将其转换回整数。当心,没有很多的语言(也可能没有数据库),它们能够与大整数工作。

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

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

我们不得不删除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

哎呀!它仅接受字节串​​。然后,以Unicode每个六标记编码于字节串六标号。要走的路是编码;然而,编码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'

现在,我们也有类似的字节字符串作为第一个.encode('utf-8')后。让我们用反向操作 - 从解码UTF-8。我们应该让我们开始用相同的Unicode字符串。

>>> s2 = b3.decode('utf-8')
>>> s2
'Hello, World, عالَم, ދުނިޔެ, जगत, 世界'
>>> s == s2   # is the original equal to the result?
True

:)


6
投票

从python的文档:

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

例如,你可以使用binascii.hexlify获得二进制串的“LOL”的十六进制表示,并把它变成通过int内置函数整数:

>>> binascii.hexlify(b"LOL")
b'4c4f4c'
>>> int(binascii.hexlify(b"LOL"), 16)
5001036

因为你需要这适用于unicode字符串,你需要首先将其编码为二进制字符串。您可以使用该方法str.encode用于此目的:

>>> int(binascii.hexlify("fiŝaĵo".encode("utf-8")), 16)
7379646744164087151

而已。

对于反之亦然,你需要扭转的每一步。首先把整数的十六进制表示的二进制字符串(你可以用format(int, "x")去,然后对其进行编码),转十六进制与ASCII binascii.unhexlify最后解码为UTF-8:

>>> binascii.unhexlify(format(7379646744164087151, "x").encode("utf-8")).decode("utf-8")
'fiŝaĵo'

这是一个一步一步的解释,如果你真的将使用该设施将在功能形式安排他们一个好主意。


1
投票

建立由马亭皮特斯给出的解决方案,可以让你的字符串数量庞大,有什么Python 3中可以处理得很好,因为它是整数类型是任意大的(即不是“电脑是如何工作的”,看到我对你的问题的评论) 。

鉴于字符数字代码清单:

>>> a = [ord(c) for c in 'Hello World!']
>>> print(a)
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]

而且知道,维基百科的页面上Unicode,最大的Unicode字符数是10FFFF(十六进制),你可以这样做:

def numfy(s):
    number = 0
    for e in [ord(c) for c in s]:
        number = (number * 0x110000) + e
    return number

def denumfy(number):
    l = []
    while(number != 0):
        l.append(chr(number % 0x110000))
        number = number // 0x110000
    return ''.join(reversed(l))

从而:

>>> a = numfy("Hello, World, عالَم, ދުނިޔެ, जगत, 世界")
>>> a
31611336900126021[...]08666956
>>> denumfy(a)
'Hello, World, عالَم, ދުނިޔެ, जगत, 世界'

凡本0x110000(从10FFFF + 1)是不同的预见Unicode字符的数目(1114112,十进制)。如果您确信您只使用英文字母,您可以在这里使用128,如果你使用的是带有口音一些拉丁语,它是安全的使用256无论哪种方式你的电话号码就会小很多,但是这将是无法代表每一个Unicode字符。


-1
投票

这将每个字符的数...

s="hello \u2020"
print [ord(c) for c in s]
© www.soinside.com 2019 - 2024. All rights reserved.