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])