Skip to main content

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 by default (pass permute_base=0 for 0-based). Index 0 is invalid in 1-based mode and raises ValueError. Indices are relative to the current pointer position, and the pointer advances past the last referenced bit. 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. The pointer must stay within [0, array_length] after each command; a ValueError is raised if Backup moves before the start or Skip/Take/Permute moves past the end.

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 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 by default (bit 1 is the first bit); pass permute_base=0 for 0-based. Index 0 in 1-based mode raises ValueError
  • Permutation indices are relative to the current pointer position
  • 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",
    permute_base: int = 1,
) -> 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")
  • permute_base: Numbering base for permute indices, 0 or 1 (default: 1)

Returns:

  • Numpy array with same dtype, modified according to commands

Raises:

  • TypeError: array is not a numpy array
  • ValueError: Invalid remnant or permute_base argument, invalid command syntax, or a command that moves the pointer out of bounds

Note: Array values are not validated. Values other than 0 and 1 pass through t/s/r/p unchanged, but produce meaningless results with i/ri (which XOR each value with 1).

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

takeskip is licensed under the MIT License - see the LICENSE file for details

Metadata

Release files for takeskip 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for takeskip 0.3.0
File Size Uploaded
takeskip-0.3.0.tar.gz 45.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for takeskip 0.3.0
File Interpreter ABI Platform
takeskip-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 58.2 kB

Release files / takeskip-0.3.0.tar.gz

Download URL takeskip-0.3.0.tar.gz
Size 45.9 kB
Tags Source
SHA-256 checksum
How to use checksums
1d425156688e7dd028746a8f36c6642af76d15bdfa519d90d0cde288afd9b579
BLAKE2b-256 checksum
How to use checksums
eecada2dd05f1bb10c45aea3c802934fc40962e8b82f64e04ce099ae65994b7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / takeskip-0.3.0-py3-none-any.whl

Download URL takeskip-0.3.0-py3-none-any.whl
Size 12.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d98a285d8029737cb60859faefe033e245f30c8855bb98c242f8d89a47830e8f
BLAKE2b-256 checksum
How to use checksums
22fe3dfcb1525d1aa28ef372eb8cc0e0b9305c5cd7bac12fd708feebd4c3d5ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page