cybersecurity · beginner · ~20 min
Per-byte allow-list encoding — the RFC 3986 unreserved set.
Percent-encode a string for safe inclusion in a URL, leaving only the RFC 3986 "unreserved" bytes untouched.
Implement int url_encode(const char *in, char *out, int cap). For each byte of in:
[A-Za-z0-9-._~] (the unreserved set), copy it as-is;%XX, where XX is the byte's value as uppercase hex.Always NUL-terminate out.
in: a NUL-terminated string the grader provides.out: the destination buffer.cap: the size of out in bytes.Returns the number of bytes written, excluding the terminating NUL. Returns -1 if the encoded result (plus its NUL) would not fit in cap.
url_encode("hello", out, 128) -> 5, out = "hello"
url_encode("a b", out, 128) -> 5, out = "a%20b"
url_encode("a&b=c", out, 128) -> 9, out = "a%26b%3Dc"
url_encode("~_-.", out, 128) -> 4, out = "~_-." (all unreserved)
url_encode("", out, 128) -> 0, out = ""
url_encode("hello", out, 3) -> -1 (won't fit)
~ is unreserved (do not encode it).cap too small (including cap == 0): return -1.Every byte that crosses an HTTP URL boundary must be %XX-encoded if it's not in the safe set. Doing it correctly is the most basic step in any URL builder.
A NUL-terminated string in, a destination buffer out, and its size cap.
Bytes written excluding the NUL; -1 if the result would not fit. out is NUL-terminated.
Uppercase hex; encode everything except the unreserved set [A-Za-z0-9-._~].
int url_encode(const char *in, char *out, int cap) { /* TODO */ (void)in; (void)out; (void)cap; return -1; }
Encoding ~ (it's in the safe set). Lowercase hex (some validators reject).
Empty input. All-safe input. All-unsafe input. cap=0.
O(n).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.