cybersecurity · intermediate · ~30 min
Combine character-class scanning with a numeric checksum.
Mask credit-card numbers in a log line — the PCI-DSS rule of thumb is: any run of 13-19 digits that passes the Luhn checksum is treated as a card number.
Implement void redact_cards(char *line) that mutates line in place, replacing every run of plain digits whose length is in [13, 19] AND that passes the Luhn checksum with the literal text [redacted].
The Luhn check:
line: a NUL-terminated, writable buffer. The grader passes a fixed line. Only runs of plain digits count — spaces or dashes break a run.No return value. line is rewritten in place with every matching card-number run replaced by [redacted].
"card 4532015112830366 in log" -> "card [redacted] in log" (Luhn-valid, 16 digits)
"old 1234567890123456 is invalid" -> "old 1234567890123456 is invalid" (Luhn-invalid)
"ten digits 1234567890 leave alone" -> unchanged (only 10 digits)
"long 12345678901234567890 leave alone" -> unchanged (20 digits, too long)
"two 4532015112830366 then 79927398713 ok" -> "two [redacted] then 79927398713 ok" (2nd run is 11 digits)
PCI-DSS compliance requires masking primary account numbers (PANs) in logs and exports. The pragmatic check is: any run of 13–19 digits that passes the Luhn checksum is treated as a card number and redacted.
A NUL-terminated, writable line with digit runs to scan.
No return value; line is mutated so every Luhn-valid 13-19 digit run becomes [redacted].
Only plain-digit runs of length 13-19 that pass Luhn are redacted; rewrite in place.
void redact_cards(char *line) { /* TODO */ }
Forgetting the length window (13..19). Doubling the wrong digit (it's every second from the right, not the left).
Digit run too short; too long; valid Luhn but not in window; multiple cards in one line.
O(strlen(line) * avg-digit-run-length).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.