Skip to main content

Do bit manipulations with take/skip commands

Project description

TakeSkip

A Python library for declarative bit manipulation using an intuitive command syntax.

Overview

TakeSkip provides a domain-specific language for selecting, rearranging, and manipulating bits in binary arrays. Instead of writing complex indexing logic, you can express operations using simple commands like t8s4r8 (take 8 bits, skip 4, reverse 8).

Installation

pip install takeskip

Basic Usage

import numpy as np
from takeskip import takeskip

# Create a binary array (8 bits)
bits = np.array([1, 0, 1, 1, 0, 0, 1, 0], dtype=np.uint8)

# Skip first 2 bits, take next 4
result = takeskip("s2t4", bits)
print(result)  # [1, 1, 0, 0]

# Take 4 bits, reverse next 4
result = takeskip("t4r4", bits)
print(result)  # [1, 0, 1, 1, 0, 1, 0, 0]

Command Reference

Basic Operations

Command Description Example
t<n> Take n bits t8 - take 8 bits
s<n> Skip n bits s4 - skip 4 bits
r<n> Reverse n bits r8 - reverse 8 bits
i<n> Invert n bits (0↔1) i4 - invert 4 bits
ri<n> Reverse and invert n bits ri8 - reverse then invert 8 bits
b<n> Backup pointer n positions b4 - move back 4 positions

Padding Operations

Command Description Example
z<n> Insert n zeros z4 - add 4 zeros
n<n> Insert n ones n4 - add 4 ones
d<binary> Insert literal binary data d101 - add bits 1,0,1

Permutation

Command Description Example
p<indices> Permute using 1-based indices p1,3,5 - select bits 1, 3, 5
p<range> Permute using ranges p1-4 - select bits 1 through 4
p<mixed> Mix indices and ranges p1-4,8,6-5 - complex permutation

Note: Permutation indices are 1-based for user convenience. Ranges are inclusive.

Grouping and Repetition

# Repeat a sequence
bits = np.array([1, 0] * 8, dtype=np.uint8)
result = takeskip("(t4s4)3", bits)  # Repeat "take 4, skip 4" three times

# Group complex operations
result = takeskip("(t2r2s1)4", bits)  # Repeat grouped operations

Advanced Examples

Nibble Swap (swap 4-bit chunks)

bits = np.array([1, 1, 1, 1, 0, 0, 0, 0], dtype=np.uint8)
result = takeskip("s4t4b8t4", bits)  # [0, 0, 0, 0, 1, 1, 1, 1]

Extract Every Other Bit

bits = np.array([1, 0, 1, 0, 1, 0, 1, 0], dtype=np.uint8)
result = takeskip("(t1s1)4", bits)  # [1, 1, 1, 1]

Deinterleave Nibbles

bits = np.array([1, 0, 1, 0, 1, 0, 1, 0], dtype=np.uint8)
result = takeskip("(t1s1)4 b8 (s1t1)4", bits)  # [1, 1, 1, 1, 0, 0, 0, 0]

Complex Permutation

bits = np.array([1, 0, 1, 1, 0, 0, 1, 0], dtype=np.uint8)
# Take bits at positions 1,2,3,4 then 8,7,6,5 (1-based)
result = takeskip("p1-4,8-5", bits)  # [1, 0, 1, 1, 0, 1, 0, 0]

Interleave Pattern with Padding

bits = np.array([1, 1, 1, 1, 0, 0, 0, 0], dtype=np.uint8)
result = takeskip("(t1z1)4", bits)
# [1, 0, 1, 0, 1, 0, 1, 0] - interleaved with zeros

Remnant Handling

Control what happens to remaining bits after commands execute:

bits = np.array([1, 0, 1, 1, 0, 0, 1, 0], dtype=np.uint8)

# Default: discard remaining bits
result = takeskip("t4", bits, remnant="remove")  # [1, 0, 1, 1]

# Keep remaining bits
result = takeskip("t4", bits, remnant="keep")  # [1, 0, 1, 1, 0, 0, 1, 0]

# Pad with zeros to original length
result = takeskip("t4", bits, remnant="pad")  # [1, 0, 1, 1, 0, 0, 0, 0]

Multi-dimensional Arrays

TakeSkip operates on the last axis of multi-dimensional arrays:

# 2D array: 3 rows of 8 bits each
bits = np.array([
    [1, 0, 1, 1, 0, 0, 1, 0],
    [0, 1, 0, 1, 1, 1, 0, 1],
    [1, 1, 0, 0, 1, 0, 1, 1],
], dtype=np.uint8)

result = takeskip("s2t4", bits)
# [[1, 1, 0, 0],
#  [0, 1, 1, 1],
#  [0, 0, 1, 0]]

Use Cases

  • Data packing/unpacking: Extract fields from packed binary formats
  • Protocol parsing: Parse binary protocols with field alignment
  • Bit manipulation: Rearrange bits in encryption/encoding operations

Command Chaining

Commands are executed left-to-right with a maintained pointer:

bits = np.array([1, 0, 1, 1, 0, 0, 1, 0], dtype=np.uint8)

# Pointer starts at 0
# t2: take bits 0-1 -> [1,0], pointer now at 2
# s2: skip bits 2-3, pointer now at 4  
# t4: take bits 4-7 -> [0,0,1,0], pointer now at 8
result = takeskip("t2s2t4", bits)  # [1, 0, 0, 0, 1, 0]

Syntax Notes

  • Commands are case-insensitive: T4, t4, and T4 are equivalent
  • Whitespace is ignored: t4 s2 r8 = t4s2r8
  • Parentheses create groups: (t8s8)4 repeats the sequence 4 times
  • Permutation uses 1-based indexing (bit 1 is the first bit)
  • Ranges in permutation are inclusive: 1-4 includes bits 1, 2, 3, and 4

API Documentation

Main Function

def takeskip(
    command: str,
    array: npt.NDArray[np.uint8],
    *,
    remnant: Literal["remove", "keep", "pad"] = "remove",
) -> np.ndarray

Parameters:

  • command: Command string expressing the operation
  • array: Target numpy array (dtype=uint8, values 0 or 1)
  • remnant: How to handle remaining bits ("remove", "keep", or "pad")

Returns:

  • Numpy array with same dtype, modified according to commands

Raises:

  • ValueError: Invalid remnant argument or command syntax error

Contributing

When adding new commands:

  1. Define command class in commands.py inheriting from Command
  2. Add grammar rule in takeskip.lark
  3. Add transformer method in parser.py
  4. Update documentation

License

[Your license here]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

takeskip-0.1.0b1.tar.gz (37.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

takeskip-0.1.0b1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file takeskip-0.1.0b1.tar.gz.

File metadata

  • Download URL: takeskip-0.1.0b1.tar.gz
  • Upload date:
  • Size: 37.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.24

File hashes

Hashes for takeskip-0.1.0b1.tar.gz
Algorithm Hash digest
SHA256 1e0ad0ee1b85633fba917c7c8fcd7784ef38965ee7eae77d8043fca254adb52b
MD5 0d70b2c0f4b23b2be6b7cd998a9cc3ed
BLAKE2b-256 3ff0be01e666ccf78da0678fb8b406cbb34f3d565db353b8a699e20e8b38e1d2

See more details on using hashes here.

File details

Details for the file takeskip-0.1.0b1-py3-none-any.whl.

File metadata

  • Download URL: takeskip-0.1.0b1-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.24

File hashes

Hashes for takeskip-0.1.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 a5918f6f3438aed460b5c450b92ef354fb8f6111de4c6d78af06b44c811de589
MD5 5d1fc4c555aee5c23ec6b3fc63a31116
BLAKE2b-256 9bad31b0578028703428e62582059df0698c156b45c5b3455faa96b7719ec0dd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page