cybersecurity · beginner · ~10 min · safe pentest lab

Format a contactless-card UID as colon-hex

Bounded hex-string rendering with strict length validation.

Challenge

Format a contactless-card UID as colon-separated hex — the universal log format for NFC tools, so your logs diff against everyone else's.

Task

Implement int format_uid(const uint8_t *uid, size_t n, char *out, size_t cap) that renders uid as uppercase hex separated by colons, NUL-terminating, and returns the number of bytes written (excluding the NUL).

Input

  • uid, n: a fixture UID byte buffer and its length, baked into the harness. n must be 4, 7, or 10.
  • out, cap: the output buffer and its capacity.

Output

Returns int: the number of characters written (n * 3 - 1) on success, or -1 on failure.

Example

{0xAA, 0xBB, 0xCC, 0xDD}, n 4   ->   out = "AA:BB:CC:DD", returns 11
n = 5                            ->   -1

Edge cases

  • n other than 4, 7, or 10 returns -1.
  • Any NULL input, cap == 0, or cap too small (need n*3 bytes including the NUL) returns -1.

Rules

  • Uppercase hex; emit a : between bytes but not after the last (watch the off-by-one).

Why this matters

The colon-hex UID is the universal log format for NFC tools. Rendering it the same way means your logs diff against anyone else's.

Input format

A byte array of length 4, 7, or 10.

Output format

A NUL-terminated colon-hex string in out.

Constraints

Uppercase hex. Length must be 4, 7, or 10.

Starter code

#include <stdint.h>
#include <stddef.h>
int format_uid(const uint8_t *uid, size_t n, char *out, size_t cap) {
    /* TODO */
    (void)uid; (void)n; (void)out; (void)cap;
    return -1;
}

Common mistakes

Emitting : after the last byte (trailing separator). Using %02x (lowercase). Forgetting to validate n.

Edge cases to handle

Exact-fit cap. NULL inputs. Length 5 (invalid).

Complexity

O(n).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.