Byte Insight
Byte Insight

Reputation: 1154

How to mask an int with bitfields

I have a series of 25 flags represented by Bitfields and a session integer which represents any flags set at this time. I want to mask the integer e.g. 268698112 and see what flags are set.

class Flags:
    flaga = 0x0001
    flagi = 0x0100
    flagp = 0x8000
    flagq = 0x010000
    flagv = 0x10000000

I have tried the following two lines but they only return zero.

test_a = session & flag_mask
test_b = (session >> flag_mask) & 1

I have looked at Extract bitfields from an int in Python and although I can see Bitstrings might be helpful I cannot see how to then add the integer into the mix without getting an error. For example I have tried:

bitstring.Bits(session) & bitstring.BitArray(flag_mask)
(bitstring.Bits(session) >> bitstring.BitArray(flag_mask)) & 1

but get:

Bitstrings must have the same length for and operator
< not supported between instances of "BitArray" and "int"

How can I extract true or false values from the session int for the given flags?

Upvotes: 2

Views: 322

Answers (1)

ivvija
ivvija

Reputation: 602

Docs for IntFlag and Flag

I know you have a solution, but still wanted to share how to use IntFlag for this. I used your example value of 268698112 (0b10000000001000000001000000000).

Create an IntFlag class with your flags:

from enum import IntFlag, KEEP

class SessionFlag(IntFlag, boundary=KEEP):
    flaga = 2**0  # rightmost bit
    flagi = 2**8  # 9th from right since zero based
    flagp = 2**15
    flagq = 2**16
    flagv = 2**28

To convert an int pass it to the constructor.
IntFlag does not discard undefined flags, but they are returned all as one int "remainder".

Remainder 262656 is 0b1000000001000000000, so two undefined flags.

>>> session = SessionFlag(268698112)
>>> session
<SessionFlag.flagv|262656: 268698112>

Get defined flags as list:

>>> list(session)
[<SessionFlag.flagv: 268435456>]

Check flags:

>>> SessionFlag.flagq in session
False
>>> SessionFlag.flagv in session
True
>>> SessionFlag(2**9) in session  # convert undefined flag for checking
True
>>> SessionFlag(2**13) in session  # convert undefined flag for checking
False

Upvotes: 2

Related Questions