如何将字符串转换为二进制?
- 2025-01-20 09:06:00
- admin 原创
- 115
问题描述:
我需要一种方法来获取 python 中字符串的二进制表示形式。例如
st = "hello world"
toBinary(st)
是否有一个模块可以巧妙地实现这一目标?
解决方案 1:
像这样吗?
>>> 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'
解决方案 2:
如果您指的是二进制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
否则,如果您希望它们以零和一的形式(二进制表示)表示,作为更符合 Python 的方式,您可以先将字符串转换为字节数组,然后使用bin
其中的函数map
:
>>> 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'
请注意,在python3中需要为bytearray
函数指定编码:
>>> ' '.join(map(bin,bytearray(st,'utf8')))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'
您还可以binascii
在 Python 2 中使用模块:
>>> import binascii
>>> bin(int(binascii.hexlify(st),16))
'0b110100001100101011011000110110001101111001000000111011101101111011100100110110001100100'
hexlify
返回二进制数据的十六进制表示形式,然后您可以通过指定 16 作为其基数将其转换为 int,然后使用将其转换为二进制bin
。
解决方案 3:
我们只需要对其进行编码。
'string'.encode('ascii')
解决方案 4:
您可以使用内置函数访问字符串中字符的代码值ord()
。如果您随后需要将其格式化为二进制,则该string.format()
方法可以完成这项工作。
a = "test"
print(' '.join(format(ord(x), 'b') for x in a))
(感谢 Ashwini Chaudhary 发布该代码片段。)
虽然上述代码在 Python 3 中有效,但如果您假设使用除 UTF-8 以外的任何编码,情况就会变得更加复杂。在 Python 2 中,字符串是字节序列,默认情况下假设使用 ASCII 编码。在 Python 3 中,字符串被假设为 Unicode,并且有一个单独的bytes
类型,其行为更像 Python 2 字符串。如果您希望假设使用除 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 字符集中的字符,则差异将变得很重要。
解决方案 5:
在 Python 3.6 及以上版本中,您可以使用f-string来格式化结果。
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) 是实际对象,其值将被格式化并插入到输出中。使用 ord() 可为您提供单个 str 字符的十进制代码点。
冒号的右侧是格式说明符。08 表示宽度为 8,用 0 填充,b 用作符号,以 2 为基数(二进制)输出结果数字。
解决方案 6:
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 在转换为字节数组时效率更高,因为它进行低级函数调用,而不是手动将每个字符转换为整数,然后将该整数转换为其二进制值。
解决方案 7:
这是对现有答案的更新,这些答案过去使用过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>
解决方案 8:
''.join(format(i, 'b') for i in bytearray(str, encoding='utf-8'))
这没问题,因为现在很容易恢复回字符串,因为不会添加零来达到 8 位来形成一个字节,因此很容易恢复回字符串以避免删除添加的零的复杂性。
解决方案 9:
以下是ASCII 127(删除)各种编码的位长度比较。请注意UTF-8-SIG、UTF-16 和 UTF-32 中各自的 24、16 和 32 位字节顺序标记 (BOM) :
>>> for encoding in ('utf-8', 'utf-8-sig', 'utf-16', 'utf-16-le', 'utf-16-be', 'utf-32', 'utf-32-le', 'utf-32-be'): print(''.join(' '.join((f'{encoding:9}', f'{len(bs):2}', bs)) for bs in [''.join(f'{byte:08b}' for byte in 'x7f'.encode(encoding))]))
...
utf-8 8 01111111
utf-8-sig 32 11101111101110111011111101111111
utf-16 32 11111111111111100111111100000000
utf-16-le 16 0111111100000000
utf-16-be 16 0000000001111111
utf-32 64 1111111111111110000000000000000001111111000000000000000000000000
utf-32-le 32 01111111000000000000000000000000
utf-32-be 32 00000000000000000000000001111111
解决方案 10:
a = list(input("Enter a string : "))
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))