Bit Manipulation and Bitmasks: From Unix Permissions to Feature Flags
Bit manipulation is where number bases become practical: Unix permissions, feature flags, IP subnetting, and protocol fields all use bitmasks. Here's how AND, OR, XOR, and shifts work, with real examples from file permissions and flag systems.
By sadiqbd Β· June 9, 2026
Bitwise operations are where number bases become practically useful rather than theoretically interesting
The base converter shows you that 0xFF is 255 in decimal and 11111111 in binary. The bitwise operations take that knowledge and turn it into something you can use: checking whether a specific feature flag is enabled, combining multiple boolean settings into a single integer, or understanding why Unix file permissions look the way they do.
Bit manipulation is one of those techniques that seems obscure until you understand it β then you see it everywhere.
The bitwise operators
Six fundamental bitwise operators operate on the binary representation of integers:
AND (&): a bit is 1 only if the corresponding bits in both operands are 1.
1010 1100 (0xAC = 172)
& 0000 1111 (0x0F = 15, the "mask")
= 0000 1100 (0x0C = 12)
OR (|): a bit is 1 if either operand has a 1 in that position.
1010 1100
| 0000 1111
= 1010 1111 (0xAF = 175)
XOR (^): a bit is 1 if the bits in the two operands differ.
1010 1100
^ 0000 1111
= 1010 0011 (0xA3 = 163)
NOT (~): flips every bit (bitwise complement). Note: in most languages, ~n = -(n+1) due to two's complement.
~ 0000 1111 (0x0F = 15)
= 1111 0000 (as a signed 8-bit int: -16)
Left shift (<<): shifts bits left by n positions, filling with 0. Equivalent to multiplying by 2βΏ.
0000 1111 << 2 = 0011 1100 (15 Γ 4 = 60)
Right shift (>>): shifts bits right by n positions. For unsigned integers, fills with 0. For signed integers, behaviour is implementation-defined (arithmetic vs. logical shift).
0011 1100 >> 2 = 0000 1111 (60 Γ· 4 = 15)
Flags and bitmasks: the practical use case
A common pattern: instead of multiple boolean fields, use a single integer where each bit represents one flag.
# Define flags using bit positions (powers of 2)
READ = 1 # 0001
WRITE = 2 # 0010
EXECUTE = 4 # 0100
ADMIN = 8 # 1000
# Combine flags with OR
user_permissions = READ | WRITE # 0011 = 3
admin_permissions = READ | WRITE | EXECUTE | ADMIN # 1111 = 15
# Check if a specific flag is set with AND
def has_permission(permissions, flag):
return (permissions & flag) != 0
has_permission(user_permissions, READ) # True
has_permission(user_permissions, EXECUTE) # False
has_permission(user_permissions, WRITE) # True
# Set a flag with OR
user_permissions |= EXECUTE # Now: READ | WRITE | EXECUTE = 7
# Clear a flag with AND NOT
user_permissions &= ~EXECUTE # Remove EXECUTE: back to READ | WRITE = 3
# Toggle a flag with XOR
user_permissions ^= EXECUTE # If set, clear it; if clear, set it
Unix file permissions: live example of bitmasks
Unix file permissions are displayed as rwxrwxrwx or as an octal number like 755 or 644. These are bitmasks:
Owner Group Other
r w x r w x r w x
4 2 1 4 2 1 4 2 1
Permission 755 in octal = 111 101 101 in binary:
- Owner:
111= read (4) + write (2) + execute (1) = 7 βββ - Group:
101= read (4) + execute (1) = 5 βββ - Other:
101= read (4) + execute (1) = 5 βββ
Reading permissions:
mode = 0o755 # 493 in decimal
owner_read = (mode & 0o400) != 0 # True
owner_write = (mode & 0o200) != 0 # True
owner_execute = (mode & 0o100) != 0 # True
group_read = (mode & 0o040) != 0 # True
group_write = (mode & 0o020) != 0 # False
group_execute = (mode & 0o010) != 0 # True
The chmod command takes a bitmask: chmod 644 file sets -rw-r--r-- (owner read+write, group and others read-only).
IP subnetting: AND masking in networking
Subnet masks work through bitwise AND. To determine which subnet an IP address belongs to:
IP address: 192.168.1.100 = 11000000.10101000.00000001.01100100
Subnet mask: 255.255.255.0 = 11111111.11111111.11111111.00000000
AND operation: 192.168.1.0 = 11000000.10101000.00000001.00000000
The result is the network address β the base address of the subnet. Any IP address AND'd with the subnet mask that produces the same network address is in the same subnet.
Bit manipulation tricks
Check if n is a power of 2:
def is_power_of_two(n):
return n > 0 and (n & (n - 1)) == 0
# Powers of 2 have exactly one bit set: 8 = 1000, 8-1 = 0111
# 1000 & 0111 = 0000 β is a power of 2
Swap two integers without a temporary variable:
a ^= b
b ^= a
a ^= b
# XOR cancels itself out: a becomes b, b becomes a
Get the lowest set bit:
lowest_bit = n & (-n)
# -n in two's complement flips bits and adds 1
# The only bit that doesn't cancel is the lowest set bit
Count set bits (popcount):
def count_bits(n):
count = 0
while n:
count += n & 1
n >>= 1
return count
# Modern: bin(n).count('1') in Python
# Or: n.bit_count() in Python 3.10+
How to use the Number Base Converter on sadiqbd.com
- Enter a number in decimal, binary, octal, or hex
- Read the binary representation β this directly shows which bits are set
- Use for bitmask work: enter your flag value and verify the binary to confirm the right bits are set
- Verify permissions: enter an octal permission value (like 755) and read the binary representation
Frequently Asked Questions
Why does Python's ~15 give -16 instead of 240?
Python integers are arbitrary precision and two's complement. ~n = -(n+1) always. ~15 = -16. In a fixed-width context (uint8), ~0x0F = 0xF0 = 240. Use n ^ 0xFF to get the 8-bit complement, or specify the bit width explicitly.
What's the difference between >> and >>> in JavaScript?
>> is arithmetic right shift: preserves the sign bit. 0x80000000 >> 1 = 0xC0000000 (still negative). >>> is logical right shift: fills with zero. 0x80000000 >>> 1 = 0x40000000 (now positive). JavaScript's >>> is unique to JS; most other languages use separate signed/unsigned integer types instead.
Is the Number Base Converter free? Yes β completely free, no sign-up required.
Bitwise operations are the language of low-level code, system permissions, protocol design, and flag systems. Once the patterns are familiar, you can read a permission value, a flag field, or a protocol header at a glance.
Try the Number Base Converter free at sadiqbd.com β convert between binary, octal, decimal, and hex instantly, and see which bits are set in any value.