cybersecurity · beginner · ~12 min · safe pentest lab

Count unique non-empty subdomains in a wordlist

Linear-time deduplication against a fixed-capacity seen-set in pure C.

Challenge

Count the unique non-empty subdomains in a wordlist — deduplicating recon wordlists is the linear-scan-plus-small-table pattern in pure C.

Task

Implement int count_unique_domains(const char *list) that returns the number of distinct non-empty entries, compared case-insensitively.

Input

  • list: a NUL-terminated, \n-separated string of subdomain labels baked into the harness.

Output

Returns int: the number of unique non-empty entries, 0 if list == NULL, or -1 if there are more than 256 distinct entries.

Example

"www\napi\nwww\nmail\n"   ->   3
"www\nWWW\n"               ->   1   (case-insensitive)
"\n\n\n"                  ->   0
NULL                        ->   0

Edge cases

  • Empty lines are ignored.
  • More than 256 distinct entries returns -1.
  • Input need not end in \n; stop at the NUL.

Rules

  • Cap distinct entries at 256; each label is at most 63 chars.
  • Tokenise on \n, lowercase each token, and linear-scan a fixed seen-table.

Why this matters

Recon pipelines start by deduplicating wordlists. Writing the deduper in C teaches the linear-scan + small-table pattern.

Input format

A NUL-terminated string of \n-separated subdomain labels.

Output format

Unique count (0..256), or -1 if the cap is exceeded.

Constraints

Cap distinct entries at 256. Per-entry label <= 63 chars.

Starter code

int count_unique_domains(const char *list) {
    /* TODO */
    (void)list;
    return 0;
}

Common mistakes

Forgetting trailing-NL-less input. Allowing empty lines through. Reading past NUL.

Edge cases to handle

Cap at exactly 256. Case variation. Single line without newline.

Complexity

O(input_len * unique_count). Bounded by 256 unique × 64 bytes.

Background lessons

Up next

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