在Python中将0和1的字符串转换为字节

时间:2013-04-24 23:20:10

标签: python string binary byte bit

我有一个二进制整数的字符串表示,我需要具有精确位结构的字节,以通过套接字发送。

例如如果我有一个长度为16的字符串:0000111100001010那么我需要2个字节的相同位结构。在这种情况下,第一个字节的int值应为15,第二个字节应为10。它们是否可以ascii格式打印并不重要。我怎么得到它?

我尝试了以下方法,它以0xf0xa的形式创建字节。但这个大小为6个字节而不是2个。

def getByte(s):
  if(len(s) != 8):
    return
  b = b'0'
  for c in s:
    b = (int(b) | int(c)) & 0x0000ff #This makes b an integer
    b = b << 1
  b = b >> 1 #because of 1 extra shift
  b = hex(b).encode('utf-8') #how else can I get back to byte from int?

  return(b) 

此方法采用长度为8的字符串,并打算提供相同内部位结构的字节,但失败。 (我需要strtol中与C类似的内容。)

请帮忙吗?

2 个答案:

答案 0 :(得分:6)

首先,如果您将位字符串作为文字值,只需将其设为base-2 int literal,而不是字符串文字:

value = 0b0000111100001010

如果您有非文字位字符串,并且您需要做的就是将它们解析为整数,那么,正如martineau在评论中所说,内置的int构造函数就是您所需要的,如martineau说,因为它需要base作为可选的第二个参数:

value = int('0000111100001010', 2)

如果您需要使用位字符串做任何奇特的事情,您可能希望使用第三方模块,如bitarraybitstring,这样可以创建可被视为字符串的对象1和0,布尔序列,整数等:

value = bitstring.BitArray(bin='0000111100001010')

一旦你有一个整数,你可以用struct将它打包成2个字节,正如martineau在评论中所解释的那样:

my_bytes = struct.pack('!H', value)

!表示“network-endian”。如果您想要little-endian或native-endian(或big-endian,当然与network-endian相同,但可能是描述某些上下文的更有意义的方式),请参阅Byte Order, Size, and AlignmentH表示将其打包为C unsigned short - 即两个字节。


但如果您使用的是第三方模块,它可能会更简单。例如,如果您有前一个示例中的bitstring.BitArray

my_bytes = value.tobytes()

答案 1 :(得分:4)

转换二进制字符串数据的简单方法就是使用内置的int()函数,并告诉它数字是基数为2的二进制而不是默认的基数10十进制格式:

int('0000111100001010', 2)

这将返回一个整数值。要将其转换为字节字符串,可以使用pack()模式中的struct函数,并使用格式将数据参数称为short(2字节)无符号整数字符串'H'

struct.pack('!H', int('0000111100001010', 2))

由于你想通过网络套接字发送它,我还添加了一个'!'前缀,表示返回的字节应该是“网络”或大端字节顺序而不是本机格式你的电脑(可能不同)。

请注意,为示例返回的字符串为'\x0f\n'。最后的'\n'是因为字节值0x0a碰巧是一个ASCII换行符,所以当Python显示包含一个字符串的repr()时,它就是这样表示的(这是Python交互式控制台在每个表达式后自动执行的操作。)