我试图用Python 3解决一个可伪造的东西。为此,我需要打印一些不在ASCII范围内的字符。
Python 3正在将这些字符转换为某种奇怪的Unicode。
例如,如果我在Python 3中打印"\xff"
,则会得到以下信息:
root@kali:~# python3 -c 'print("\xff")' | xxd
00000000: c3bf 0a ...
\xff
被转换为\xc3\xbf
但是在Python 2中,它可以按预期工作,就像这样:
root@kali:~# python -c 'print("\xff")' | xxd
00000000: ff0a ..
那么如何在Python 3中像这样打印呢?
答案 0 :(得分:2)
在Python 2中,str
和bytes
是同一件事,因此当您编写'\xff'
时,结果包含实际的字节0xFF
。
在Python 3中,str
更接近Python 2的unicode
对象,并且不是bytes
的别名。 \xff
不再是一个插入字节的请求,而是一个要插入Unicode字符(其代码可以用8位表示)的请求。该字符串将使用您的默认编码(可能是UTF-8)进行打印,其中字符0xFF被编码为字节\xc3\xbf
。当\x
出现在字符串中时,基本上是\u
的单字节版本。不过,它仍然出现在bytes
中。
现在寻求解决方案。如果您只想要一些字节,请
b'\xff'
与Python 2中的工作原理相同。您可以将这些字节写入二进制文件,但是之后就不能直接打印,因为您打印的所有内容都会转换为str
。打印的问题是所有内容都以文本模式进行编码。幸运的是,sys.stdout
具有buffer
属性,可让您直接输出bytes
:
sys.stdout.buffer.write(b'\xff\n')
仅当您不将sys.stdout
替换为没有buffer
的东西时,此方法才有效。
答案 1 :(得分:1)
在Python 2中,print '\xff'
将字节字符串直接写到终端,这样您就得到了打印的字节。
在Python 3中,print('\xff')
使用默认编码将Unicode字符U + 00FF编码到终端上……在您的情况下为UTF-8。
要在Python 3中直接将字节输出到终端,您不能使用print
,但是可以使用以下代码跳过编码并写入字节字符串:
python3 -c "import sys; sys.stdout.buffer.write(b'\xff')"