Byte array operations for binary protocol support.

Functions

crc32

fn (data: Bytes | Str | Vec): Int

Calculate CRC32 checksum (IEEE polynomial). Used by protocols like AWS Event Stream for integrity checks.

Example

crc32("hello")                  // 907060870
crc32(Bytes([72, 101, 108, 108, 111]))  // 907060870 (same)

// Verify message integrity
message-crc crc32(message-bytes)
eq(message-crc, expected-crc)

from-float

fn (value: Dec | Int, size: Int): Bytes
fn (value: Dec | Int, size: Int, endian: Str): Bytes

Encode a Dec or Int value as IEEE 754 float bytes. Size must be 4 (single precision) or 8 (double precision). Default is big-endian (network byte order).

Values that are not exactly representable as a binary float are rounded to the nearest representable value — the usual IEEE 754 behavior. Use Str encoding instead when a protocol offers a text format and you need exact decimals.

Example

from-float(1.5, 8)         // Bytes([63, 248, 0, 0, 0, 0, 0, 0])
from-float(0.25, 4)        // Bytes([62, 128, 0, 0])
from-float(2, 4, "le")     // Bytes([0, 0, 0, 64])

from-float

fn (value: Int | Dec, size: Int): Bytes
fn (value: Int | Dec, size: Int, endian: Str): Bytes

Encode a number as IEEE-754 bytes: size 4 (single) or 8 (double); endian is "be" (default) or "le".

from-int

fn (value: Int, size: Int): Bytes
fn (value: Int, size: Int, endian: Str): Bytes

Convert an integer to bytes with specified size (1-8 bytes). Default is big-endian (network byte order).

Example

// Big-endian (default)
from-int(256, 2)        // Bytes([1, 0])
from-int(16, 4)         // Bytes([0, 0, 0, 16])

// Little-endian
from-int(256, 2, "le")  // Bytes([0, 1])

index-of

fn (haystack: Bytes, needle: Bytes | Byte | Int): Int?
fn (haystack: Bytes, needle: Bytes | Byte | Int, from: Int): Int?

Find the first occurrence of a byte or byte sequence within bytes. Returns the index as Int, or null when not found.

The needle can be a single byte value (Int 0-255) or a Bytes sequence. An optional from index starts the search at an offset — useful for scanning consecutive null-terminated strings in binary protocols.

Example

data Bytes([82, 0, 65, 66, 0])

index-of(data, 0)                    // 1 (first null byte)
index-of(data, 0, 2)                 // 4 (next null byte from index 2)
index-of(data, Bytes([65, 66]))      // 2
index-of(data, 99)                   // null (not found)

to-float

fn (bytes: Bytes): Dec
fn (bytes: Bytes, endian: Str): Dec

Decode IEEE 754 float bytes to a Dec value. Accepts 4 bytes (single precision) or 8 bytes (double precision). Default is big-endian (network byte order).

Hot has no float type — the wire encoding is IEEE 754, but the decoded value is an exact Dec using the shortest decimal form that round-trips.

Example

to-float(Bytes([63, 248, 0, 0, 0, 0, 0, 0]))        // 1.5 (f64)
to-float(Bytes([62, 128, 0, 0]))                     // 0.25 (f32)
to-float(Bytes([0, 0, 128, 62]), "le")               // 0.25 (f32, little-endian)

to-float

fn (bytes: Bytes): Dec
fn (bytes: Bytes, endian: Str): Dec

Decode IEEE-754 bytes to a float. 4 bytes (single) or 8 bytes (double); endian is "be" (default) or "le".

Example

to-float(Bytes([64, 9, 33, 251, 84, 68, 45, 24]))  // 3.141592653589793

to-int

fn (bytes: Bytes): Int
fn (bytes: Bytes, endian: Str): Int

Convert bytes to a signed integer. Default is big-endian (network byte order). Supports 1-8 bytes.

Example

// Big-endian (default)
to-int(Bytes([0, 0, 0, 16]))     // 16
to-int(Bytes([0, 16]))           // 16

// Little-endian
to-int(Bytes([16, 0, 0, 0]), "le")  // 16

to-uint

fn (bytes: Bytes): Int
fn (bytes: Bytes, endian: Str): Int

Convert bytes to an unsigned integer. Default is big-endian. Supports 1-8 bytes. Values > i64::MAX will wrap to negative.

Example

// Unsigned interpretation
to-uint(Bytes([255, 255]))  // 65535 (not -1)

to-vec

fn (bytes: Bytes): Vec

Convert bytes to a vector of integers for easier manipulation.

Example

data Bytes([1, 2, 3])
to-vec(data)  // [1, 2, 3]

xor

fn (a: Bytes, b: Bytes): Bytes

XOR two equal-length byte sequences. Fails when lengths differ.

Used by authentication schemes like SCRAM, where the client proof is ClientKey XOR ClientSignature.

Example

a Bytes([10, 255, 0])
b Bytes([6, 15, 0])
xor(a, b)  // Bytes([12, 240, 0])