Faker 银行数据生成器实战指南:Faker::Bank 从账号到 IBAN 校验位的完整解析
【免费下载链接】fakerA library for generating fake data such as names, addresses, and phone numbers.项目地址: https://gitcode.com/GitHub_Trending/fake/faker
导读
Faker::Bank 是 faker 库中专用于生成银行相关伪造数据的模块,覆盖银行账号、IBAN 国际银行账号、路由号码(Routing Number)、SWIFT/BIC 代码与银行名称等常见场景。本文以 bank.md 文档为主体,结合 bank.rb 源码实现与 test_faker_bank.rb 测试用例,逐一讲解每个生成器的参数、默认值、底层算法与数据来源,帮助你在开发测试数据、支付模拟、国际汇款演示等场景中正确使用并理解其生成原理。
Faker::Bank 功能总览
该模块定义在 lib/faker/default/bank.rb 中,通过flexible :bank声明其数据来源为 locale 中faker.bank命名空间。核心公开方法如下:
| 方法 | 说明 | 默认行为 |
|---|---|---|
account_number | 生成银行账号 | 默认 10 位数字,可指定位数 |
iban | 生成 IBAN 国际银行账号 | 默认英国(GB),校验位真实有效 |
iban_country_code | 随机返回一个使用 IBAN 体系的国家代码 | ISO 3166 两位大写 |
name | 生成银行名称 | 从 locale 数据池随机选取 |
routing_number | 生成美国路由号码 | 9 位数字且通过校验 |
routing_number_with_format | 生成带分数格式的路由号码 | 形如前缀-分子/分母 |
swift_bic | 生成 SWIFT/BIC 代码 | 从 locale 数据池随机选取 |
bsb_number | 生成澳大利亚 BSB 分行代码 | 6 位数字 |
下面按方法逐一深入。
一、account_number:生成银行账号
基本用法
Faker::Bank.account_number #=> 6738582379 # Keyword arguments: digits Faker::Bank.account_number(digits: 13) #=> 673858237902源码实现
从源码(lib/faker/default/bank.rb#L19-L21)可见,account_number的实现非常直接:
def account_number(digits: 10) Array.new(digits) { rand(10) }.join end即通过digits次随机取值(0-9)拼成一个纯数字字符串,默认 10 位。测试用例(test_faker_bank.rb#L34-L40)验证了默认 10 位、digits: 12为 12 位、digits: 100为 100 位的行为,说明该参数不设上限。
注意:account_number是纯随机数字串,不携带任何校验逻辑。它适合用于“看起来像账号”的占位数据,若需要可校验的账号结构,应使用下一节的iban。
二、iban:生成带真实校验位的国际银行账号
基本用法
# Faker generates valid IBAN check digits, but national check digits (BBAN) are not supported Faker::Bank.iban #=> "GB76DZJM33188515981979" # Keyword arguments: country_code # All countries should be supported Faker::Bank.iban(country_code: "be") #=> "BE6375388567752043"iban是 Faker::Bank 中最有技术含量的生成器。它生成的 IBAN 具备真实有效的 IBAN 校验位(第 3、4 位),可通过mod 97 == 1的国际化校验,但不包含各国国内(BBAN)的本地校验位——这一点在官方文档中已明确标注。
country_code 参数的两种形态
- 省略或传字符串(如
"be"、"GB"):按指定国家生成,默认值为'GB'; - 传
nil:随机挑选一个使用 IBAN 体系的国家(Faker::Bank.iban(country_code: nil) #=> "DE45186738071857270067")。
若传入的country_code在 locale 中不存在,会抛出ArgumentError: Could not find iban details for xxx,测试用例 test_iban_invalid 对该行为做了断言。
生成流程源码解析
iban的完整逻辑位于 lib/faker/default/bank.rb#L35-L52,核心分三步:
def iban(country_code: 'GB') country_code ||= iban_country_code begin pattern = fetch("bank.iban_details.#{country_code.downcase}.bban_pattern") rescue I18n::MissingTranslationData raise ArgumentError, "Could not find iban details for #{country_code}" end # Use Faker::Base.regexify for creating a sample from bank account format regex account = Base.regexify(/#{pattern}/) # Add country code and checksum to the generated account to form valid IBAN country_code.upcase + iban_checksum(country_code, account) + account end- 确定国家:未指定时通过
iban_country_code随机选取; - 按 BBAN 正则生成主体:从 locale 数据中读取该国的
bban_pattern,用Faker::Base.regexify依据正则随机生成账号主体; - 拼装最终 IBAN:将国家码大写、计算出的两位校验位与账号主体拼接为
国家码 + 校验位 + BBAN的完整结构。
校验位算法:mod 97 国际标准
iban_checksum(lib/faker/default/bank.rb#L156-L169)实现了 IBAN 标准的校验位计算(源码注释引用维基百科 Generating IBAN check digits 一节):
def iban_checksum(country_code, account) # Converts letters to numbers according the iban rules, A=10..Z=35 account_to_number = "#{account}#{country_code}00".upcase.chars.map do |d| d =~ /[A-Z]/ ? (d.ord - 55).to_s : d end.join.to_i # This is the correct answer to (iban_to_num + checksum) % 97 == 1 checksum = 98 - (account_to_number % 97) # Use leftpad to make the size always to 2 checksum.to_s.rjust(2, '0') end要点:
- 将账号主体拼接国家码与
"00"后,字母按A=10 ... Z=35规则转成数字并拼成大整数; - 计算
98 - (整数 % 97)得到校验位,右对齐补零确保恒为两位; - 校验位取值范围为
02..98,测试工具函数valid_iban_checksum?(test_faker_bank.rb#L724-L731)验证最终结果满足整体 mod 97 == 1。
各国 IBAN 格式:数据驱动生成
iban能支持“所有国家”的秘密在于 locale 数据文件 lib/locales/en/bank.yml#L117 的iban_details段。每个国家维护两项:length(IBAN 总长度)与bban_pattern(BBAN 部分的正则)。节选如下:
iban_details: ad: # Andorra length: 24 bban_pattern: '\d{8}[A-Z0-9]{12}' be: # Belgium length: 16 bban_pattern: '\d{12}' de: # Germany length: 22 bban_pattern: '\d{18}' gb: # United Kingdom length: 22 bban_pattern: '[A-Z]{4}\d{14}' fr: # France length: 27 bban_pattern: '\d{10}[A-Z0-9]{11}\d{2}'正因为是正则驱动,iban(country_code:)对任意已收录国家都能生成长度与形态符合该国规范、且校验位有效的 IBAN。测试文件为每个国家都编写了独立的长度与正则断言(如test_iban_gb断言^GB\d{2}[A-Z]{4}\d{14}$且长度 22),覆盖安道尔、阿联酋、中国台湾省未收录等约 70 个国家/地区。
iban_country_code:随机国家
Faker::Bank.iban_country_code #=> "CH"该方法(lib/faker/default/bank.rb#L63-L65)从faker.bank.iban_details的所有键中随机取样并转大写,返回两位 ISO 3166 国家码。它是iban(country_code: nil)的内部支撑。
三、routing_number:带校验的 9 位路由号码
基本用法
Faker::Bank.routing_number #=> "729343831"源码实现与校验算法
routing_number(美国 ABA 路由号码)是 9 位数字,其第 9 位为校验位。源码(lib/faker/default/bank.rb#L171-L177)先随机生成 9 位数字,再用加权公式计算校验位并修正:
def checksum(num_string) num_array = num_string.chars.map(&:to_i) ( 7 * (num_array[0] + num_array[3] + num_array[6]) + 3 * (num_array[1] + num_array[4] + num_array[7]) + 9 * (num_array[2] + num_array[5]) ) % 10 end def valid_routing_number routing_number = compile_routing_number checksum = checksum(routing_number) return routing_number if valid_checksum?(routing_number, checksum) routing_number[0..7] + checksum.to_s end校验公式为7*(第1+4+7位) + 3*(第2+5+8位) + 9*(第3+6位) 对 10 取模。测试 test_routing_number 验证生成的 9 位号码恒满足该公式结果为 0,即校验位总是有效的。此外,前两位会从 ABA 允许的区间池(00-12、21-32、61-72、80)中选取(见compile_routing_number,lib/faker/default/bank.rb#L144-L148),使号码在结构上更贴近真实。
routing_number_with_format:分数格式
Faker::Bank.routing_number_with_format #=> "2-5432/0110"routing_number_with_format(lib/faker/default/bank.rb#L102-L104)将有效路由号码渲染为传统支票上的“分数形式”:随机前缀(1-50)+ 分子(后 4 位)+ 分母(前 5 位),格式为前缀-分子/分母,对应正则\d{1,2}-\d{1,4}/\d{1,4}(见测试 test_routing_number_with_format)。
四、name 与 swift_bic:来自 locale 数据池的取值
Faker::Bank.name #=> "ABN AMRO CORPORATE FINANCE LIMITED" Faker::Bank.swift_bic #=> "AAFMGB21"这两个方法(lib/faker/default/bank.rb#L76-L78、#L115-L117)不涉及算法,直接从 locale 数据池中随机取样:
- 银行名称取自
faker.bank.name,在 lib/locales/en/bank.yml#L27-L49 中维护了一份真实感较强的机构名单(如 UBS CLEARING AND EXECUTION SERVICES LIMITED、SANTANDER UK PLC 等); - SWIFT/BIC 代码取自
faker.bank.swift_bic(lib/locales/en/bank.yml#L50 起),收录了AACCGB21、ABNAGB21VOC等真实格式的 BIC 字符串,其中部分带有 8 或 11 位变体。
由于数据来源是 YAML,这两个方法天然支持多语言/多地区 locale 的覆盖(如 lib/locales/ja/bank.yml、lib/locales/zh-CN/bank.yml 均存在bank命名空间),切换 locale 后即可输出当地银行名称与 BIC。
五、bsb_number:澳大利亚分行代码
Faker::Bank.bsb_number #=> "036616"bsb_number(lib/faker/default/bank.rb#L129-L131)生成 6 位澳大利亚 BSB(Bank-State-Branch)号码。其实现compile_bsb_number(lib/faker/default/bank.rb#L150-L154)对前两位从真实 BSB 前缀池(01、03、06、08、11、12、73、76、78、30)取样,第 3 位从州编号 2-7 中取样,后三位随机。对应测试 test_bsb_number 断言其为 6 位纯数字。
六、数据与测试:验证生成结果的可靠性
数据层面
所有随机取样的词条与各国 IBAN 规则均集中在 locale 文件 lib/locales/en/bank.yml(共 391 行),其中iban_details段数据源在文件头注明参考自 iban-tools 项目与 tbg5-finance 的 IBAN 文档。若需要为特定国家补充或修正格式,只需修改对应bban_pattern与length即可,无需改动 Ruby 代码。
测试层面
test/faker/default/test_faker_bank.rb(732 行)是理解模块行为的最佳入口,值得关注的设计:
- 每个 IBAN 国家独立用例:逐个断言长度、前缀正则与校验位有效性,保证新增国家不会破坏整体;
- 确定性验证:法国、英国、格鲁吉亚的用例使用
deterministically_verify辅助方法(见 test/support 相关 helper),对随机生成结果进行多重采样验证; - 真实样本校验:
test_iban_checksum使用 iban.com 公布的真实 IBAN 样本(如GB33BUKB20201555555555、NL02ABNA0123456789)反推校验位并逐一比对,从侧面印证iban_checksum与国际标准一致; - 错误路径覆盖:
test_iban_invalid确认未知国家码抛ArgumentError。
七、使用边界与注意事项
- 校验位语义:
iban仅保证 IBAN 级校验位(第 3-4 位)正确,不保证国内 BBAN 本地校验位(如德国的国家校验、法国的 RIB 密钥)。用于界面展示、格式测试足够,用于真实支付场景的严格校验则不足; - 国家码大小写:
iban(country_code:)对大小写不敏感(内部统一downcase查询、upcase输出),但必须是 IBAN 体系内的 ISO 3166 代码,否则抛ArgumentError; - 账号与路由号码的区别:
account_number是纯随机串、无校验;routing_number带 ABA 校验且前缀受限,适合需要“可被解析”的模拟场景; - 数据随机性:
name、swift_bic为有限数据池随机抽样,大批量生成时可能出现重复,测试文件中被注释的test_swift_bic_collission用例正说明了这一观察。
小结
通过本文可以掌握 Faker::Bank 的全部公开 API 及其底层原理:account_number的位数控制、iban的 mod 97 校验位算法与正则驱动的多国格式、routing_number的加权校验公式,以及name/swift_bic/bsb_number的数据池来源。若需进一步研究,建议对照阅读 bank.rb、bank.yml 与 test_faker_bank.rb 三份文件,它们共同构成了“文档—实现—数据—验证”的完整闭环。
【免费下载链接】fakerA library for generating fake data such as names, addresses, and phone numbers.项目地址: https://gitcode.com/GitHub_Trending/fake/faker
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考