# `Meshcore.Util`
[🔗](https://github.com/nyannus/meshcore_ex/blob/v0.1.0/lib/meshcore/util.ex#L1)

Small binary/encoding helpers shared across the library.

## Destinations

The Python library distinguishes `bytes` and `str` destinations. Elixir
binaries are both, so `to_key/2` applies this rule: a binary made only of
hex digits and at least `2 * prefix_length` characters long is treated as a
**hex string**, anything else as **raw bytes**. A contact map (anything with
a `:public_key` hex string) is accepted as well.

# `destination`

```elixir
@type destination() ::
  binary() | %{:public_key =&gt; String.t(), optional(any()) =&gt; any()}
```

# `cstr`

```elixir
@spec cstr(binary()) :: String.t()
```

Like `utf8/1` but also removes every NUL character.

# `hex`

```elixir
@spec hex(binary()) :: String.t()
```

Lower-case hex encoding.

# `hex?`

```elixir
@spec hex?(binary()) :: boolean()
```

Returns `true` if `bin` is a non-empty, even-length string of hex digits.

# `now`

```elixir
@spec now() :: non_neg_integer()
```

Current Unix time in seconds.

# `random_u32`

```elixir
@spec random_u32() :: pos_integer()
```

Reads a random unsigned 32 bit integer in `1..0xFFFFFFFF`.

# `s`

```elixir
@spec s(integer(), pos_integer()) :: binary()
```

Little-endian signed integer encoding.

# `sha256`

```elixir
@spec sha256(iodata()) :: binary()
```

SHA-256 digest.

# `split_path_len`

```elixir
@spec split_path_len(0..255) :: {integer(), integer()}
```

Splits an encoded path-length byte into `{hash_mode, hop_count}`.

`255` means "flood" and yields `{-1, -1}`.

# `strip_nul`

```elixir
@spec strip_nul(binary()) :: binary()
```

Removes leading and trailing NUL bytes.

# `to_bytes`

```elixir
@spec to_bytes(binary() | {:hex, String.t()}) :: binary()
```

Normalises raw bytes: accepts a binary (taken verbatim) or `{:hex, string}`.

# `to_key`

```elixir
@spec to_key(destination(), pos_integer()) :: binary()
```

Resolves a destination (raw key, hex key or contact map) into `prefix_length`
raw key bytes.

Raises `ArgumentError` for malformed input (the equivalent of Python's
`ValueError`).

# `u`

```elixir
@spec u(integer(), pos_integer()) :: binary()
```

Little-endian unsigned integer encoding.

# `utf8`

```elixir
@spec utf8(binary()) :: String.t()
```

Decodes UTF-8, silently dropping invalid bytes (Python's
`decode("utf-8", "ignore")`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
