簡體   English   中英

Python - 從 8 個布爾字節值生成和 int,反之亦然

[英]Python - making and int from 8 boolean byte values and vice versa

我有 8 個 bool 變量,我想將它們“合並”成一個字節。

有沒有一種簡單/首選的方法來做到這一點?

反過來,如何將一個字節解碼為 8 個單獨的布爾值?

例子:

>>> byte_to_number([False, True, True, True, True, False, True, True])

123

>>> number_to_byte(123)

[False, True, True, True, True, False, True, True]

您可以使用列表理解來遍歷列表中的每個項目,然后使用int()將二進制值轉換為整數。

>>> a = [False, True, True, True, True, False, True, True]
>>> int("".join(["01"[i] for i in a]), 2)
123
>>> 
import math

def bools_to_int(bits):
    value = 0
    for i, bit in enumerate(bits):
        value |= bit << (len(bits) - i - 1)
    return value
    
def int_to_bools(value):
    bits = []
    n = math.ceil(math.log2(value))
    for i in range(n):
        bits.append(value >> (n - i - 1) & 1 == 1)
    return bits
    
print(bools_to_int([False, True, True, True, True, False, True, True]))
# Outputs 123

print(int_to_bools(123))
# Outputs [True, True, True, True, False, True, True]

如果需要前導數字,還可以向int_to_bools添加填充參數:

def int_to_bools(value, pad=-1):
    bits = []
    n = max(pad, math.ceil(math.log2(value)))
    for i in range(n):
        bits.append(value >> (n - i - 1) & 1 == 1)
    return bits

print(int_to_bools(123, pad=8))
# Outputs [False, True, True, True, True, False, True, True]

如果要控制位的解析方式,還可以向這兩個函數添加字節序參數:

import math

def bools_to_int(bits, big_endian=True):
    value = 0
    for i, bit in enumerate(bits):
        shift = (len(bits) - i - 1) if big_endian else i 
        value |= bit << shift
    return value
    
def int_to_bools(value, pad=-1, big_endian=True):
    bits = []
    n = max(pad, math.ceil(math.log2(value)))
    for i in range(n):
        shift = (n - i - 1) if big_endian else i
        bits.append(value >> shift & 1 == 1)
    return bits
    
print(bools_to_int([False, True, True, True, True, False, True, True], big_endian=True))
# Outputs 123, parse as 01111011

print(bools_to_int([False, True, True, True, True, False, True, True], big_endian=False))
# Outputs 222, parse as 11011110

您可以使用直接的按位運算符更輕松地完成此操作

def byte_to_number(bools):
    return ((1 if bools[0] else 0) << 0) | \
           ((1 if bools[1] else 0) << 1) | \
           ((1 if bools[2] else 0) << 2) | \
           ((1 if bools[3] else 0) << 3) | \
           ((1 if bools[4] else 0) << 4) | \
           ((1 if bools[5] else 0) << 5) | \
           ((1 if bools[6] else 0) << 6) | \
           ((1 if bools[7] else 0) << 7)

def number_to_byte(num):
    return [bool((num >> i) & 1) for i in range(8)]

這始終假設您只想要一個 8 位數字,避免任意長度的循環。

對於相反的 endian 順序,只需要反轉范圍:

def number_to_byte(num):
    return [bool((num >> i) & 1) for i in reversed(range(8))]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM