cybersecurity · beginner · ~10 min · safe pentest lab

Format a contactless-card UID as colon-hex

Bounded hex-string rendering with strict length validation.

Challenge

Your job

Implement:

#include <stdint.h>
#include <stddef.h>
int format_uid(const uint8_t *uid, size_t n, char *out, size_t cap);

Render uid as uppercase hex separated by colons. Return the number of bytes written (excluding NUL).

Rules:

  • n must be 4, 7, or 10. Anything else → -1.
  • Output is n * 3 - 1 bytes plus 1 for the NUL.
  • Return -1 if any input is NULL, cap == 0, or cap is too small.

Examples

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

Hints

  1. (concept) Walk the bytes; for each, emit %02X; for all but the last byte, emit a :.
  2. (common bug) Off-by-one on the separator count.

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.