bytes() 和 b'' 的区别
Difference between bytes() and b''
我有以下 str
:
"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
这来自文件名:Расшифровка_RootKit.com_63k.txt
我的问题是无法将第一个 str
反转为第二个。我已经尝试了一些东西,使用 en/decode()
、bytes()
、etc 但我没有成功。
我注意到的一件事是 b'' 和 bytes() 有不同的输出:
path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))
print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode('utf8'))
结果:
РаÑÑиÑ
Ñовка_RootKit.com_63k.txt
Расшифровка_RootKit.com_63k.txt
所以我想知道b''
和bytes()
有什么区别;也许它会帮助我解决我的问题!
path
变量是一个字符串(不是字节)。
当您使用方法 bytes()
时,您正在将其解码为字节,这将 return b'\xc3\x90\xc2\xa0\xc3\x90\xc2\xb0\xc3\x91\xc2\x81\xc3\x91\xc2\x88\xc3\x90\xc2\xb8\xc3\x91\xc2\x84\xc3\x91\xc2\x80\xc3\x90\xc2\xbe\xc3\x90\xc2\xb2\xc3\x90\xc2\xba\xc3\x90\xc2\xb0_RootKit.com_63k.txt'
但是当您写 b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
时,您指的是 Расшифровка_RootKit.com_63k.txt
的字节值
b''
是一个前缀,它导致以下字符串被解释为 bytes
类型的对象。 bytes
函数接受一个字符串和 returns 一个 bytes
对象。
print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode
这行得通,因为您正在解码字节对象。
path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))
这没有按预期工作,因为您将 path
视为字符串,然后将其转换为字节对象,然后尝试解码输出的内容。
您可能想使用 latin1
的解决方案,首先滚动到该答案。如果您不小心复制了字节内容并粘贴为字符串,则此答案有效。
如果要将它们转换回字节,请使用以下代码:
In [22]: path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
In [23]: bytes(map(ord, path)).decode('utf-8')
Out[23]: 'Расшифровка_RootKit.com_63k.txt'
解释很简单,让我们使用字符串中的第一个字符:
In [40]: '\xd0'
Out[40]: 'Ð'
In [41]: b'\xd0'
Out[41]: b'\xd0'
如您所见,字符串将 \xd0
转换为编号为 0xd0
的 unicode 字符,而 bytes 只是将其解释为单个字节。
UTF-8 对 U+0080
和 U+07FF
之间的所有字符使用以下掩码:第一个字节为 110xxxxx
,第二个字节为 10xxxxxx
。这正是将字符串直接转换为字节时得到的结果:
In [43]: [bin(x) for x in '\xd0'.encode('utf-8')]
Out[43]: ['0b11000011', '0b10010000']
而实际的符号代码是00011
+ 010000
(串联,不是加法),即0xd0
:
In [44]: hex(int('00011010000', 2))
Out[44]: '0xd0'
要从字符中获取此数字,我们可以使用 ord
:
In [45]: hex(ord('\xd0'))
Out[45]: '0xd0'
然后将其应用于整个字符串并将其转换回字节:
In [46]: bytes(map(ord, path)).decode('utf-8')
Out[46]: 'Расшифровка_RootKit.com_63k.txt'
请注意,如果您的字符串字符由于某种原因不适合字节,上面的代码将引发错误:
In [47]: bytes([ord(chr(256))])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-49-5555e18dbece> in <module>
----> 1 bytes([ord(chr(256))])
ValueError: bytes must be in range(0, 256)
要转换您的字符串,只需使用 'latin1' 将其编码为字节,在字节和字符之间具有 1 对 1 的映射,并使用 'utf8':
进行解码
s = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
s.encode('latin1').decode('utf8')
# 'Расшифровка_RootKit.com_63k.txt'
我有以下 str
:
"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
这来自文件名:Расшифровка_RootKit.com_63k.txt
我的问题是无法将第一个 str
反转为第二个。我已经尝试了一些东西,使用 en/decode()
、bytes()
、etc 但我没有成功。
我注意到的一件事是 b'' 和 bytes() 有不同的输出:
path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))
print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode('utf8'))
结果:
РаÑÑиÑ
Ñовка_RootKit.com_63k.txt
Расшифровка_RootKit.com_63k.txt
所以我想知道b''
和bytes()
有什么区别;也许它会帮助我解决我的问题!
path
变量是一个字符串(不是字节)。
当您使用方法 bytes()
时,您正在将其解码为字节,这将 return b'\xc3\x90\xc2\xa0\xc3\x90\xc2\xb0\xc3\x91\xc2\x81\xc3\x91\xc2\x88\xc3\x90\xc2\xb8\xc3\x91\xc2\x84\xc3\x91\xc2\x80\xc3\x90\xc2\xbe\xc3\x90\xc2\xb2\xc3\x90\xc2\xba\xc3\x90\xc2\xb0_RootKit.com_63k.txt'
但是当您写 b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
时,您指的是 Расшифровка_RootKit.com_63k.txt
b''
是一个前缀,它导致以下字符串被解释为 bytes
类型的对象。 bytes
函数接受一个字符串和 returns 一个 bytes
对象。
print(b"\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt".decode
这行得通,因为您正在解码字节对象。
path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
bpath = bytes(path, "UTF-8")
print(bpath.decode("UTF-8"))
这没有按预期工作,因为您将 path
视为字符串,然后将其转换为字节对象,然后尝试解码输出的内容。
您可能想使用 latin1
的解决方案,首先滚动到该答案。如果您不小心复制了字节内容并粘贴为字符串,则此答案有效。
如果要将它们转换回字节,请使用以下代码:
In [22]: path = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
In [23]: bytes(map(ord, path)).decode('utf-8')
Out[23]: 'Расшифровка_RootKit.com_63k.txt'
解释很简单,让我们使用字符串中的第一个字符:
In [40]: '\xd0'
Out[40]: 'Ð'
In [41]: b'\xd0'
Out[41]: b'\xd0'
如您所见,字符串将 \xd0
转换为编号为 0xd0
的 unicode 字符,而 bytes 只是将其解释为单个字节。
UTF-8 对 U+0080
和 U+07FF
之间的所有字符使用以下掩码:第一个字节为 110xxxxx
,第二个字节为 10xxxxxx
。这正是将字符串直接转换为字节时得到的结果:
In [43]: [bin(x) for x in '\xd0'.encode('utf-8')]
Out[43]: ['0b11000011', '0b10010000']
而实际的符号代码是00011
+ 010000
(串联,不是加法),即0xd0
:
In [44]: hex(int('00011010000', 2))
Out[44]: '0xd0'
要从字符中获取此数字,我们可以使用 ord
:
In [45]: hex(ord('\xd0'))
Out[45]: '0xd0'
然后将其应用于整个字符串并将其转换回字节:
In [46]: bytes(map(ord, path)).decode('utf-8')
Out[46]: 'Расшифровка_RootKit.com_63k.txt'
请注意,如果您的字符串字符由于某种原因不适合字节,上面的代码将引发错误:
In [47]: bytes([ord(chr(256))])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-49-5555e18dbece> in <module>
----> 1 bytes([ord(chr(256))])
ValueError: bytes must be in range(0, 256)
要转换您的字符串,只需使用 'latin1' 将其编码为字节,在字节和字符之间具有 1 对 1 的映射,并使用 'utf8':
进行解码s = "\xd0\xa0\xd0\xb0\xd1\x81\xd1\x88\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xba\xd0\xb0_RootKit.com_63k.txt"
s.encode('latin1').decode('utf8')
# 'Расшифровка_RootKit.com_63k.txt'