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

Posted

技术标签:

【中文标题】如何将字符串转换为二进制?【英文标题】:How to convert string to binary? 【发布时间】:2013-09-19 21:11:30 【问题描述】:

我需要一种在 python 中获取字符串二进制表示的方法。例如

st = "hello world"
toBinary(st)

有没有一些巧妙的方式来做这件事的模块?

【问题讨论】:

您希望输出具体是什么? “二进制”是指 0101010 类型还是 ordinal 中每个字符的数字(例如十六进制)? 假设您实际上是指二进制(零和一),您是否想要一个接一个地表示每个字符(每个字符 8 位)的二进制表示?例如h 是 ascii 值 104 在二进制中是 01101000 这个问题在***上已经回答过很多次了:***.com/questions/11599226/…***.com/questions/8553310/… Convert Binary to ASCII and vice versa (Python)的可能重复 【参考方案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'

【讨论】:

或者如果您希望每个二进制数为 1 个字节:' '.join(format(ord(i),'b').zfill(8) for i in st) 对于完整字节,您还可以使用' '.join('0:08b'.format(ord(x), 'b') for x in st),这比zfill(8) 解决方案快约35%(至少在我的机器上)。 如何转换超过一个字节的字符,例如β,例如,在我看来,11001110 10110010 在内部代表? 我知道这是很久以前发布的,但是非 ASCII 字符呢? Format Specification Mini-Language' '.join(':08b'.format(d) for d in bytearray('ß', 'utf-8')),输出:'11000011 10011111',尝试其他编码utf-16utf-32 非ASCII b>.【参考方案2】:

如果二进制是指bytes 类型,则可以使用字符串对象的encode method,使用传递的编码类型将字符串编码为字节对象。您只需要确保将正确的编码传递给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 的方式,您可以先将字符串转换为字节数组,然后在 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'

注意在python3中你需要为bytearray函数指定一个编码:

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

你也可以在python 2中使用binascii模块:

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

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

【讨论】:

这不仅更符合 Python 风格,而且对于多字节非 ASCII 字符串“更”正确。 只是要注意(至少对于当前版本3.7.4):(1)bytearray 需要一个编码(不仅仅是一个字符串)和(2)map(bin, ...) 将返回@ 987654339@ 对象。对于第一点,我按照@Tao 的建议使用例如bob.encoding('ascii')`。对于第二个点,使用join 方法,就像在@Kasramvd 的其他示例中一样,将显示所需的结果。 “hello world”.encode('ascii') 很完美【参考方案3】:

我们只需要对其进行编码。

'string'.encode('ascii')

【讨论】:

对于我 (v3.7.4),这将返回一个 bytes 对象(如果可用,每个字节的 ascii 表示形式),为了显示其二进制表示形式,我需要 bin ,例如与' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii'))) (注意0b 需要在每个字符的二进制表示的开头删除)。【参考方案4】:

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

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

(感谢 Ashwini Chaudhary 发布代码 sn-p。)

虽然上面的代码在 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 字符的 base-10 代码点。

冒号的右侧是格式说明符。 08 表示 宽度为 8, 0 被填充,并且 b 用作输出符号的符号 结果以 2 为底数(二进制)。

【讨论】:

请注意,您将覆盖str【参考方案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】:
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))

【讨论】:

您想用一些解释来扩充这个不可读的纯代码答案吗?这将有助于消除 *** 是免费代码编写服务的误解。如果您想提高可读性,请尝试此处提供的信息:***.com/editing-help

以上是关于如何将字符串转换为二进制?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 64 位二进制字符串转换为 ruby​​ 中的双浮点数?

如何将二进制整数转换为十六进制字符串?

C#如何将大的十六进制字符串转换为二进制

Erlang - 如何将 \u0000 字符转换为二进制?

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

如何将十六进制字符串转换为十进制值