Card Range Obfuscation is the hardest "just brute force it" question in Stripe's OA history—short prompt, dense rules, byte-level hidden tests. The business context is real: BINs (Bank Identification Numbers) partition card-brand ranges, and any unmapped gap can be probed by fraudsters via card-number enumeration. Stripe needs gaps filled with "unknown" brand. This article breaks down the full solution, complexity, and the hidden-test traps that catch most candidates.
Stripe OA Overview (This Problem)
| Dimension | Detail |
|---|---|
| Platform | HackerRank for Work |
| Duration | 90 minutes |
| Questions | 1 problem, 4 parts |
| Difficulty | LeetCode Medium, very boundary-heavy |
| Pass threshold | 12/16 hidden tests |
| Frequency | Multiple appearances 2024-2026, variants vary BIN length (6/8) |
Problem Statement
Stripe's card payment API returns BIN-range → brand mappings.
Key concepts:
- BIN: 6-digit (sometimes 8-digit) card prefix
- Card number length: 8-19 digits
- Full BIN range: all 16-digit card numbers starting with the BIN
- Example: BIN=424242 →
4242420000000000 ~ 4242429999999999
- Example: BIN=424242 →
- Interval: a subrange tagged with a brand:
(start, end, brand)
Input:
- A BIN (integer)
- A list of
(start, end, brand)triples
Output:
- A sorted, non-overlapping, fully-covering list of intervals
- Original intervals keep their brand
- Gaps are filled with
"unknown"
Example
BIN = 424242
intervals = [
(4242420000000000, 4242421000000000, "VISA"),
(4242423000000000, 4242425000000000, "MASTERCARD"),
]
Expected output:
[
(4242420000000000, 4242421000000000, "VISA"),
(4242421000000001, 4242422999999999, "unknown"),
(4242423000000000, 4242425000000000, "MASTERCARD"),
(4242425000000001, 4242429999999999, "unknown"),
]
Approach
Classic interval merge + gap fill. Stripe's hidden tests scale up to 1e5 intervals, so O(n log n) is required.
Step 1: Compute the global BIN range
span = 10 ** (16 - len(str(BIN)))
bin_start = BIN * span
bin_end = bin_start + span - 1
BIN length can be 6 or 8—don't hard-code 10**10 or 10**12. This is the Part-3 trap.
Step 2: Sort intervals by start
Step 3: Scan intervals, inserting "unknown" on gaps
- Track
cursor, initiallybin_start - For each
(s, e, brand):- If
s > cursor: append(cursor, s-1, "unknown") - Append
(s, e, brand) - Set
cursor = e + 1
- If
- After the loop: if
cursor <= bin_end, append(cursor, bin_end, "unknown")
Step 4: Handle overlapping intervals (Part 4)
Stripe's Part 4 introduces overlaps. Two acceptable strategies:
- Reject (some versions accept this)
- Last-writer wins (the expected behavior in Part 4): split overlapping intervals so the later brand owns the overlapped segment
Complete Python Solution
from typing import List, Tuple
Interval = Tuple[int, int, str]
def fill_card_ranges(bin_value: int, intervals: List[Interval]) -> List[Interval]:
bin_str = str(bin_value)
span = 10 ** (16 - len(bin_str))
bin_start = bin_value * span
bin_end = bin_start + span - 1
sorted_intervals = sorted(intervals, key=lambda x: (x[0], x[1]))
result: List[Interval] = []
cursor = bin_start
for s, e, brand in sorted_intervals:
s = max(s, bin_start)
e = min(e, bin_end)
if s > e:
continue
if s > cursor:
result.append((cursor, s - 1, "unknown"))
elif s < cursor:
s = cursor
if s > e:
continue
result.append((s, e, brand))
cursor = e + 1
if cursor <= bin_end:
result.append((cursor, bin_end, "unknown"))
return result
Time: O(n log n) (sort-dominated)
Space: O(n)
4 Hidden-Test Traps
Trap 1: BIN length is not fixed
Part 3 hands you an 8-digit BIN. Hard-coding 10**10 fails every time. Always derive span from len(str(bin_value)).
Trap 2: Input intervals can extend past the BIN range
Inputs sometimes have start < bin_start or end > bin_end. Clip them with max/min.
Trap 3: Adjacent intervals (off by 1, not 0)
If interval A ends at x and B starts at x+1, there's no gap—don't insert "unknown". The trick is cursor = e + 1 (not e), so adjacent intervals naturally skip gap insertion.
Trap 4: Empty input / BIN entirely uncovered
When intervals = [], output one (bin_start, bin_end, "unknown") segment. Easy to forget the post-loop cursor <= bin_end branch.
Complexity Walkthrough
With n input intervals:
- Sort: O(n log n)
- Scan: O(n)
- Worst-case output size: 2n + 1 (one unknown between every pair of intervals plus head/tail)
Total: O(n log n) time, O(n) space.
Stripe Rubric: Maximizing Score Across 4 Parts
| Part | Content | Weight | Key |
|---|---|---|---|
| Part 1 | Single BIN + non-overlapping sorted input | 20% | Correct splitting |
| Part 2 | Unsorted input + gap filling | 30% | Sort by start |
| Part 3 | Variable BIN length + out-of-range input | 30% | Dynamic span + clipping |
| Part 4 | Overlapping intervals | 20% | Last-writer-wins or reject |
Strategy: nail Parts 1+2 first (50%). Part 3 is the BIN-length adaptation. Skipping Part 4 still lands ~80% of total points.
FAQ
Is Card Range Obfuscation still seen in 2026 OAs?
Yes. In Q1-Q2 2026 alone, at least 6 candidates reported hitting this problem or a variant: merging same-brand contiguous ranges, or hidden tests that scale input size to 1e5.
Why does Stripe love interval problems?
Stripe's core domain (payments, subscriptions, refunds) is full of time-interval and amount-interval merging. The OA philosophy is "this is the kind of code you'll actually write here."
How do I distinguish a BIN of length 6 vs 8?
The problem statement tells you, but your code should derive it via len(str(bin_value)). Hidden tests deliberately switch BIN length to expose hardcoded constants.
Closed or half-open intervals?
Stripe uses closed intervals [start, end]. If you switch to half-open [start, end), every cursor calculation needs a +1 adjustment, and the chance of off-by-one bugs rises dramatically. Stay closed.
Is Java faster than Python here?
No. Python's sorted handles 1e5 items in well under 100ms. Grading is language-agnostic, and Python may even edge ahead on the readability axis.
Preparing for the Stripe OA?
oavoservice covers Stripe's full historical OA bank with real-time assistance: BIN Range, Brace Expansion, Subscription Notification, Shipping Cost, and more—each with hidden-case post-mortems. Our coaches include former Stripe Risk engineers who understand Stripe's grading bias toward readability + boundary handling.
Add WeChat Coding0201 to book Stripe OA coaching.
#Stripe #StripeOA #BIN #CardRange #PaymentSystem #OARealQuestions
Contact
Email: [email protected]
Telegram: @OAVOProxy