← 返回博客列表 Stripe OA 真题深度复盘:Card Range Obfuscation(BIN 区间填补)完整解法|2026
Stripe

Stripe OA 真题深度复盘:Card Range Obfuscation(BIN 区间填补)完整解法|2026

2026-05-14

Stripe OA 历年题里最难"无脑暴力"通过的就是 BIN Range / Card Range Obfuscation——题面短、规则多、隐藏测试卡到字节级。题目背后是真实的卡号反欺诈业务:BIN(Bank Identification Number)划分卡品牌区间,若区间存在空隙,欺诈者会用"穷举卡号"试出有效卡。Stripe 需要把空隙补全为"未知品牌",避免被试卡。本文拆解这道题的完整解法、复杂度与隐藏测试常踩坑点。

Stripe OA 概览(含本题)

维度 详情
平台 HackerRank for Work
时长 90 分钟
题量 1 道大题(4 个 Part)
难度 LeetCode Medium,边界 case 极多
通过线 12/16 隐藏测试
出现频率 2024-2026 多次出现,含变体(含 BIN 长度 6/8)

题目描述

Stripe 卡支付 API 会返回BIN 区间与品牌的映射

关键概念

输入

输出

示例

BIN = 424242
intervals = [
  (4242420000000000, 4242421000000000, "VISA"),
  (4242423000000000, 4242425000000000, "MASTERCARD"),
]

期望输出:

[
  (4242420000000000, 4242421000000000, "VISA"),
  (4242421000000001, 4242422999999999, "unknown"),
  (4242423000000000, 4242425000000000, "MASTERCARD"),
  (4242425000000001, 4242429999999999, "unknown"),
]

解题思路

这是经典的区间合并 + 空隙填补。Stripe 在 HackerRank 上的隐藏测试给到 1e5 区间数量,必须 O(n log n)。

Step 1:计算 BIN 区间的全局边界

bin_start = BIN * 10**(16 - len(str(BIN)))
bin_end   = bin_start + 10**(16 - len(str(BIN))) - 1

注意 BIN 长度可能是 6 或 8,所以不要硬编码 10**1010**12——这是隐藏 case Part 3 必扣分点。

Step 2:按 start 排序输入区间

Step 3:扫描区间,遇到空隙就插入 "unknown"

Step 4:处理重叠区间(隐藏 case Part 4)

Stripe 在第 4 个 Part 会给重叠区间。两种策略:

  1. 报错(部分版本接受)
  2. 后到优先(part 4 期望写法):用区间分裂的方式,保留后到 brand 在重叠段的覆盖

Python 完整解法

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

时间复杂度:O(n log n),排序主导
空间复杂度:O(n),输出列表

4 个隐藏测试陷阱

陷阱 1:BIN 长度不固定

题目 Part 3 会给 8 位 BIN,对应 8 位前缀 + 8 位空间。如果硬编码 10**10 一律失败。len(str(bin_value)) 动态推断 span

陷阱 2:输入区间包含 BIN 区间外部分

输入有时给 start < bin_startend > bin_end,需要用 max/min 截断到 BIN 范围内。

陷阱 3:相邻区间紧贴(差 1 不是 0)

如果 interval A 结束于 x,interval B 从 x+1 开始,没有空隙——不要插入 "unknown" 段。Stripe 的边界用 cursor = e + 1 而非 cursor = e,是为了让"紧贴"刚好不触发空隙逻辑。

陷阱 4:空输入 / BIN 完全无品牌覆盖

输入 intervals = [] 时,必须输出单条(bin_start, bin_end, "unknown")。容易忘记最后一段 cursor <= bin_end 的判断。

复杂度证明

设输入有 n 个区间:

故总时间 O(n log n),空间 O(n)。

Stripe 评分体系:4 个 Part 如何拿满分

Part 内容 分值 关键
Part 1 单 BIN + 无重叠 + 排序输入 20% 正确 split
Part 2 无序输入 + 空隙填补 30% sorted 写法
Part 3 BIN 长度可变 + 输入超出 BIN 范围 30% 动态 span + 截断
Part 4 重叠区间处理 20% 后到 brand 优先 / 报错二选一

实战策略:先把 Part 1+2 写到 100%,再处理 Part 3 的 BIN 长度变化。Part 4 即使略掉也能拿到 80% 通过。

FAQ

Card Range Obfuscation 还在 2026 OA 出现吗?

是的。2026 春招(Q1-Q2)至少 6 名候选人反馈遇到这道题或它的变体。变体包括:要求合并同 brand 的连续区间、给输入区间数量上限 1e5。

为什么 Stripe 偏爱"区间题"?

Stripe 的核心业务(payments、subscriptions、refunds)大量涉及"时间区间合并"与"金额区间分配"。OA 题的设计哲学就是**"未来你上班大概率会写这样的代码"**。

BIN 长度 6 和 8 怎么区分?

题目会显式告知 BIN 长度,但要在代码里用 len(str(bin_value)) 推断而不是 hard-code。隐藏测试会切换 BIN 长度来测试代码的健壮性。

区间是闭区间还是半开区间?

Stripe 这道题用闭区间 [start, end]。如果你写半开区间(如 [start, end))的逻辑,所有 cursor 边界计算都要 +1,更容易出错。建议遵循题面闭区间风格。

这道题用 Java 写有优势吗?

没有。Python 的 sorted 在 1e5 数据规模下完全够用(< 100ms)。Stripe 评分对所有语言一视同仁,Python 在可读性维度甚至略占优势。


正在准备 Stripe OA?

oavoservice 提供 Stripe 完整 OA 题库与实战辅助:BIN Range、Brace Expansion、Subscription Notification、Shipping Cost 等历年题目都有完整解法与隐藏 case 复盘。我们的导师包括前 Stripe Risk 团队工程师,熟悉 Stripe 评分系统对代码可读性 + 边界处理的双高要求。

立即添加微信:Coding0201获取 Stripe OA 真题辅导

#Stripe #StripeOA #BIN #CardRange #支付系统 #OA真题


联系方式

Email: [email protected]
Telegram: @OAVOProxy