如何将字符串转换为二进制?

我需要一种方法来获得 python 中字符串的二进制表示。

st = "hello world"
toBinary(st)

有没有一个模块可以用某种巧妙的方法来做到这一点?

508754 次浏览

可以使用 ord()内置函数访问字符串中字符的代码值。如果您随后需要将其格式化为二进制文件,那么 string.format()方法将完成这项工作。

a = "test"
print(' '.join(format(ord(x), 'b') for x in a))

(感谢 Ashwini Chaudhary 发布的代码片段。)

虽然上面的代码在 Python3中可以工作,但是如果假设使用 UTF-8以外的任何编码,那么问题就会变得更加复杂。在 Python2中,字符串是字节序列,默认情况下采用 ASCII 编码。在 Python3中,字符串被假定为 Unicode,还有一个单独的 bytes类型,它的作用更像 Python2字符串。如果希望假设除 UTF-8之外的任何编码,则需要指定编码。

那么,在 Python 3中,您可以这样做:

a = "test"
a_bytes = bytes(a, "ascii")
print(' '.join(["{0:b}".format(x) for x in a_bytes]))

UTF-8和 ascii 编码之间的差异对于简单的字母数字字符串来说并不明显,但是如果您处理的文本包含 ascii 字符集以外的字符,那么这种差异将变得非常重要。

像这样吗?

>>> st = "hello world"
>>> ' '.join(format(ord(x), 'b') for x in st)
'1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100'


#using `bytearray`
>>> ' '.join(format(x, 'b') for x in bytearray(st, 'utf-8'))
'1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100'

如果您所说的二进制指的是 bytes类型,那么您可以只使用字符串对象的 encode方法,该字符串对象使用传递的编码类型将您的字符串编码为字节对象。您只需要确保向 encode函数传递正确的编码即可。

In [9]: "hello world".encode('ascii')
Out[9]: b'hello world'


In [10]: byte_obj = "hello world".encode('ascii')


In [11]: byte_obj
Out[11]: b'hello world'


In [12]: byte_obj[0]
Out[12]: 104

否则,如果您希望它们以0和1的形式——二进制表示——作为一种更简洁的方式,您可以首先将字符串转换为字节数组,然后在 map中使用 bin函数:

>>> st = "hello world"
>>> map(bin,bytearray(st))
['0b1101000', '0b1100101', '0b1101100', '0b1101100', '0b1101111', '0b100000', '0b1110111', '0b1101111', '0b1110010', '0b1101100', '0b1100100']
 

或者你也可以加入:

>>> ' '.join(map(bin,bytearray(st)))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'

请注意,在 蟒蛇3中,您需要为 bytearray函数指定一个编码:

>>> ' '.join(map(bin,bytearray(st,'utf8')))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'

您还可以在 python2中使用 binascii模块:

>>> import binascii
>>> bin(int(binascii.hexlify(st),16))
'0b110100001100101011011000110110001101111001000000111011101101111011100100110110001100100'

hexlify返回二进制数据的十六进制表示,然后您可以通过指定16作为基数将其转换为 int,然后使用 bin将其转换为二进制数据。

这是对使用 bytearray()的现有答案的更新,不能再这样工作了:

>>> st = "hello world"
>>> map(bin, bytearray(st))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding

因为,正如上面的链接所解释的,如果源是一个字符串,你还必须提供编码:

>>> map(bin, bytearray(st, encoding='utf-8'))
<map object at 0x7f14dfb1ff28>
def method_a(sample_string):
binary = ' '.join(format(ord(x), 'b') for x in sample_string)


def method_b(sample_string):
binary = ' '.join(map(bin,bytearray(sample_string,encoding='utf-8')))




if __name__ == '__main__':


from timeit import timeit


sample_string = 'Convert this ascii strong to binary.'


print(
timeit(f'method_a("{sample_string}")',setup='from __main__ import method_a'),
timeit(f'method_b("{sample_string}")',setup='from __main__ import method_b')
)


# 9.564299999998184 2.943955828988692

Method _ b 在转换为字节数组方面效率更高,因为它进行低级函数调用,而不是手动将每个字符转换为一个整数,然后将该整数转换为其二进制值。

我们只需要把它加密。

'string'.encode('ascii')

在 Python 3.6及以上版本中,可以使用 F 弦格式化结果。

str = "hello world"
print(" ".join(f"{ord(i):08b}" for i in str))


01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
  • 冒号的左侧 ord (i)是实际的对象,其值为 将被格式化并插入到输出中 单个 str 字符的 base-10代码点。

  • 冒号的右边是格式说明符。08表示 宽度8,0填充,并且 b 作为输出 生成的数字以2为基数(二进制)。

a = list(input("Enter a string\t: "))
def fun(a):
c =' '.join(['0'*(8-len(bin(ord(i))[2:]))+(bin(ord(i))[2:]) for i in a])
return c
print(fun(a))
''.join(format(i, 'b') for i in bytearray(str, encoding='utf-8'))

这个工作正常,因为现在可以很容易地将字符串恢复为 no 零将被添加到达8位形成一个字节,因此容易 恢复为字符串,以避免删除添加的零的复杂性。