Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

idsmith

Validate and generate checksum-correct IBANs, personal IDs, bank accounts, credit cards, SWIFT/BIC, company IDs, driver’s licenses, tax IDs, and passports across multiple countries.

Built for developers and QA engineers who need a robust way to validate existing identifiers or create realistic, algorithmically valid test data.

Features

  • Validator + Generator — verify existing strings or create new data
  • 124 IBAN countries — full IBAN registry coverage with mod-97-10 checksum validation
  • 159 bank account formats — US ABA routing, MX CLABE, AU BSB, IN IFSC, AR CBU, NG NUBAN, BR mod-11, etc.
  • 97 personal ID formats — checksum-verified (SSN, CPF, Aadhaar, Resident ID, and more)
  • 250 company ID formats — VAT numbers, EINs, and Business IDs with major economy checksums
  • Universal Credit Cards — Visa, Mastercard, Amex, Discover, JCB, and Diners Club with Luhn support
  • SWIFT/BIC — valid 8 and 11 character codes with ISO country positioning
  • 79 driver’s license formats — with country-specific checksum and format validation
  • 80 tax ID formats — with checksum validation (PAN, TIN, CPF, SIN, Steuer-IdNr, USCI, Partita IVA, NIF, BSN, RFC, and more)
  • 79 passport formats — with country-specific format validation

Available in 3 Languages

PlatformPackageInstall
Rustidsmithcargo add idsmith
Pythonidsmithpip install idsmith
Node.jsidsmithnpm install idsmith

The Python and Node.js packages are native bindings to the Rust core — same speed, same correctness, idiomatic APIs.

Performance

LibraryLanguageThroughputRelative Speed
idsmithRust~1,310,000 ops/s1.0x
ibantoolsNode.js~460,000 ops/s~2.8x slower
python-stdnumPython~54,000 ops/s~24x slower
Document Type (idsmith Rust)Throughput
Personal ID (US SSN)~9,300,000 ops/s
Credit Card (Visa)~14,900,000 ops/s
Driver License (US)~10,100,000 ops/s
Passport (DE)~19,100,000 ops/s
Tax ID (India PAN)~7,800,000 ops/s

Validation Standards

CategoryValidation Source
IBANibantools
Personal IDpython-stdnum, taiwan-id
Bank Accountabavalidator, clabe-validator
Credit CardISO/IEC 7812 (Luhn Algorithm)
SWIFT/BICISO 9362 Standards

Installation

Rust

Add to your Cargo.toml:

[dependencies]
idsmith = { version = "0.4.0", default-features = false }

Or install the CLI:

cargo install idsmith

Note: Use default-features = false when using as a library to exclude CLI dependencies (clap, etc.).

Cargo Features

FeatureDescriptionDefault
cliFull CLI binary (clap, csv, json)Yes
jsonserde::Serialize on all result typesNo
csvCSV output formattingNo
# Library only — minimal dependencies
idsmith = { version = "0.4.0", default-features = false }

# Library with JSON serialization
idsmith = { version = "0.4.0", default-features = false, features = ["json"] }

Python

Requires Python 3.8+.

pip install idsmith

Pre-built wheels are available for Linux, macOS, and Windows.

Node.js

Requires Node.js 18+.

npm install idsmith

Pre-built native binaries are available for:

  • Linux (x86_64, aarch64)
  • macOS (x86_64, aarch64)
  • Windows (x86_64)

From Source

git clone https://github.com/Sunyata-OU/idsmith
cd idsmith

# Rust
cargo build --release

# Python
cd bindings/python
pip install maturin
maturin develop

# Node.js
cd bindings/node
npm install
npm run build

Rust Quick Start

Setup

[dependencies]
idsmith = { version = "0.4.0", default-features = false }
rand = "0.8"

Validation

#![allow(unused)]
fn main() {
use idsmith::{credit_cards, personal_ids, bank_accounts, company_ids, swift_codes};

// Simple validation (returns bool)
let card_ok = credit_cards().validate("4152839405126374");
let swift_ok = swift_codes().validate("PBIHNLY9XXX");

// Country-specific validation (returns Option<bool>)
let ssn_ok = personal_ids().validate("US", "446-72-2445").unwrap_or(false);
let vat_ok = company_ids().validate("DE", "DE141158922");
let dl_ok = idsmith::driver_licenses().validate("US", "A123456789012");
let passport_ok = idsmith::passports().validate("DE", "C01234567");
let tin_ok = idsmith::tax_ids().validate("IN", "ABCDE1234F");
let acc_ok = bank_accounts().validate("MX", "167078019952865929").unwrap_or(false);

// IBAN validation
let iban_ok = idsmith::iban::validate_iban("DE47508562162522867909");
}

Generation

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::{credit_cards, personal_ids, bank_accounts};

let mut rng = thread_rng();

// Generate with default options
let card = credit_cards().generate(&Default::default(), &mut rng).unwrap();
println!("{} - {}", card.brand, card.formatted);

// Generate a US bank account
let opts = idsmith::bank_account::GenOptions { bank_code: None };
let account = bank_accounts().generate("US", &opts, &mut rng).unwrap();
println!("{}", account.formatted);

// Generate a Brazilian personal ID (CPF)
let id = personal_ids().generate("BR", &Default::default(), &mut rng).unwrap();
println!("{}", id);

// Generate a German IBAN
let iban = idsmith::iban::generate_iban(Some("DE"), &mut rng).unwrap();
println!("{}", idsmith::iban::format_iban(&iban));

// Generate a Passport
let passport = idsmith::passports().generate(&Default::default(), &mut rng).unwrap();

// Generate a Tax ID (TIN)
let tin = idsmith::tax_ids().generate(&Default::default(), &mut rng).unwrap();
}

Parsing

#![allow(unused)]
fn main() {
let result = personal_ids().parse("FI", "050497-598S").unwrap();
println!("DOB: {:?}, Gender: {:?}", result.dob, result.gender);
}

Optional Features

FeatureDescription
jsonEnables serde::Serialize on all result types
csvEnables CSV output formatting
cliFull CLI binary (enabled by default)
# Library only — minimal dependencies
idsmith = { version = "0.4.0", default-features = false }

# Library with JSON serialization
idsmith = { version = "0.4.0", default-features = false, features = ["json"] }

CLI Usage

Installation

cargo install idsmith

Validating Data

Use the validate command to check if a code is checksum and format correct.

# Validate an IBAN
idsmith validate iban DE47508562162522867909

# Validate a National ID (requires country code)
idsmith validate id 446-72-2445 --country US

# Validate a Credit Card
idsmith validate card 5590133141634919

# Validate a Bank Account
idsmith validate account 167078019952865929 --country MX

# Validate a SWIFT/BIC code
idsmith validate swift PBIHNLY9XXX

# Validate a Driver's License
idsmith validate license A123456789012 --country US

# Validate a Tax ID
idsmith validate tax ABCDE1234F --country IN

# Validate a Passport
idsmith validate passport 123456789 --country US

Generating Data

Generate any identifier using subcommands. Use the optional count positional argument.

# Generate 5 German IBANs
idsmith iban DE 5

# Generate 3 US Bank Accounts in JSON
idsmith account 3 --country US --json -

# Generate a random Credit Card
idsmith card --brand amex

# Generate 10 Brazilian personal IDs
idsmith id 10 --country BR

# Generate Company IDs
idsmith company 5 --country GB

# Generate SWIFT codes
idsmith swift 3 --country US

# Generate 5 US Driver's Licenses
idsmith license 5 --country US

# Generate 3 Indian Tax IDs (PAN)
idsmith tax 3 --country IN

# Generate 10 German Passports
idsmith passport 10 --country DE

Output Formats

# Default: plain text (one per line)
idsmith iban DE 5

# JSON output
idsmith iban DE 5 --json -

# CSV output
idsmith iban DE 5 --csv -

# JSON to file
idsmith iban DE 100 --json output.json

# CSV to file
idsmith iban DE 100 --csv output.csv

Filtering Options

# Personal ID with gender filter
idsmith id 5 --country EE --gender male

# Personal ID with year filter
idsmith id 5 --country EE --year 1990

# Bank account with bank code
idsmith account 5 --country US --bank-code 021000021

# Credit card by brand
idsmith card 5 --brand visa

Rust API Reference

The full Rust API documentation is auto-generated from source code using cargo doc.

View the Rust API Reference →

Key Entry Points

FunctionDescription
idsmith::bank_accounts()Global registry for bank account operations
idsmith::personal_ids()Global registry for personal ID operations
idsmith::credit_cards()Global registry for credit card operations
idsmith::company_ids()Global registry for company ID operations
idsmith::swift_codes()Global registry for SWIFT/BIC operations
idsmith::driver_licenses()Global registry for driver’s license operations
idsmith::tax_ids()Global registry for tax ID operations
idsmith::passports()Global registry for passport operations
idsmith::iban::generate_iban()Generate a valid IBAN
idsmith::iban::validate_iban()Validate an IBAN string
idsmith::iban::format_iban()Format an IBAN with spaces

Modules

ModuleDescription
idsmith::bank_accountBank account types and Registry
idsmith::personal_idPersonal ID types, Registry, Gender enum
idsmith::credit_cardCredit card types and Registry
idsmith::company_idCompany ID types and Registry
idsmith::swiftSWIFT/BIC types and Registry
idsmith::driver_licenseDriver’s license types and Registry
idsmith::tax_idTax ID types, Registry, holder_type support
idsmith::passportPassport types and Registry
idsmith::ibanIBAN generation, validation, and formatting

Python Quick Start

Installation

pip install idsmith

Validation

import idsmith

# IBAN
idsmith.validate_iban("DE47508562162522867909")  # True

# Personal ID
idsmith.PersonalId.validate("US", "446-72-2445")  # True

# Credit Card
idsmith.CreditCard.validate("4152839405126374")  # True

# Bank Account
idsmith.BankAccount.validate("US", "021000021-123456789")  # True

# Company ID
idsmith.CompanyId.validate("GB", "GB123456789")  # True

# Driver's License
idsmith.DriverLicense.validate("US", "A123456789012")  # True

# Passport
idsmith.Passport.validate("DE", "C01234567")  # True

# Tax ID (TIN)
idsmith.TaxId.validate("IN", "ABCDE1234F")  # True

# SWIFT/BIC
idsmith.Swift.validate("CHASGB2LXXX")  # True

Generation

import idsmith

# Generate an IBAN
iban = idsmith.generate_iban("DE")
print(iban)  # DE47508562162522867909

# Generate a bank account (returns a dict)
account = idsmith.BankAccount.generate("US")
print(account["formatted"])   # 021000021 | 123456789
print(account["country_code"])  # US

# Generate a personal ID with options
code = idsmith.PersonalId.generate("EE", gender="female", year=1990)
print(code)  # 49001011234

# Generate a credit card
card = idsmith.CreditCard.generate(brand="visa")
print(card["formatted"])  # 4152 8394 0512 6374
print(card["brand"])      # VISA

# Generate a company ID
company = idsmith.CompanyId.generate(country="GB")
print(company["code"])  # GB123456789

# Generate a SWIFT code
swift = idsmith.Swift.generate(country="US")
print(swift["code"])  # CHASUSU5XXX

# Generate a Driver's License
dl = idsmith.DriverLicense.generate(country="US")

# Generate a Passport
passport = idsmith.Passport.generate(country="DE")

# Generate a Tax ID (TIN)
tin = idsmith.TaxId.generate(country="IN")

Parsing

result = idsmith.PersonalId.parse("EE", "49001011234")
print(result["dob"])     # 1990-01-01
print(result["gender"])  # female
print(result["valid"])   # True

Listing Supported Countries

# IBAN countries
countries = idsmith.iban_countries()  # ["AD", "AE", "AL", ...]

# Bank account countries (returns list of dicts)
for c in idsmith.BankAccount.list_countries():
    print(f"{c['code']} - {c['name']} ({c['format']})")

# Personal ID countries
for c in idsmith.PersonalId.list_countries():
    print(f"{c['code']} - {c['country_name']} ({c['id_name']})")

# Credit card brands
brands = idsmith.CreditCard.list_brands()  # ["Visa", "Mastercard", ...]

# Check if a country is supported
idsmith.BankAccount.is_supported("US")  # True
idsmith.PersonalId.is_supported("EE")   # True

Error Handling

Unsupported countries raise ValueError:

try:
    idsmith.PersonalId.generate("XX")
except ValueError as e:
    print(e)  # Unsupported country: XX

Python API Reference

Module: idsmith

Classes

BankAccount

MethodSignatureReturns
generate(country: str, bank_code: str | None = None)dict
validate(country: str, raw: str)bool
format(country: str, raw: str)str
list_countries()list[dict]
is_supported(country: str)bool

generate returns:

{
    "country_code": "US",
    "country_name": "United States",
    "format_name": "ABA Routing + Account",
    "bank_code": "021000021",       # or None
    "branch_code": None,             # or str
    "account_number": "123456789",
    "check_digits": None,            # or str
    "formatted": "021000021 | 123456789",
    "raw": "021000021123456789",
    "iban": None,                    # or str (for IBAN countries)
    "valid": True
}

PersonalId

MethodSignatureReturns
generate(country: str, gender: str | None = None, year: int | None = None)str
validate(country: str, code: str)bool
parse(country: str, code: str)dict
list_countries()list[dict]
is_supported(country: str)bool

gender parameter: "male" or "female" (or None for random).

parse returns:

{
    "country_code": "EE",
    "code": "49001011234",
    "gender": "female",   # or None
    "dob": "1990-01-01",  # or None
    "valid": True
}

CreditCard

MethodSignatureReturns
generate(brand: str | None = None)dict
validate(number: str)bool
format(brand: str, number: str)str
list_brands()list[str]

Supported brands: visa, mastercard, amex, discover, jcb, diners

generate returns:

{
    "brand": "VISA",
    "number": "4152839405126374",
    "formatted": "4152 8394 0512 6374",
    "cvv": "123",
    "expiry": "09/28",
    "valid": True
}

CompanyId

MethodSignatureReturns
generate(country: str | None = None)dict
validate(country: str, code: str)bool
list_countries()list[dict]

generate returns:

{
    "country_code": "GB",
    "country_name": "United Kingdom",
    "name": "VAT Number",
    "code": "GB123456789",
    "valid": True
}

Swift

MethodSignatureReturns
generate(country: str | None = None)dict
validate(code: str)bool

generate returns:

{
    "code": "CHASUSU5XXX",
    "bank": "CHAS",
    "country": "US",
    "location": "U5",
    "branch": "XXX",   # or None
    "valid": True
}

DriverLicense

MethodSignatureReturns
generate(country: str | None = None)dict
validate(country: str, code: str)bool
list_countries()list[dict]
is_supported(country: str)bool

generate returns:

{
    "country_code": "US",
    "country_name": "United States",
    "name": "Driver's License",
    "code": "A123456789012",
    "valid": True
}

TaxId

MethodSignatureReturns
generate(country: str | None = None, holder_type: str | None = None)dict
validate(country: str, code: str)bool
list_countries()list[dict]
is_supported(country: str)bool

holder_type parameter (IN only): "P" (Person), "C" (Company), "H" (HUF), "F" (Firm), "A" (AOP), "T" (Trust), "B" (BOI), "L" (Local Authority), "J" (Artificial Juridical Person), "G" (Government).

generate returns:

{
    "country_code": "IN",
    "country_name": "India",
    "name": "PAN",
    "code": "ABCDE1234F",
    "valid": True
}

Passport

MethodSignatureReturns
generate(country: str | None = None)dict
validate(country: str, code: str)bool
list_countries()list[dict]
is_supported(country: str)bool

generate returns:

{
    "country_code": "US",
    "country_name": "United States",
    "name": "Passport",
    "code": "123456789",
    "valid": True
}

Functions

FunctionSignatureReturns
generate_iban(country: str | None = None)str
validate_iban(iban: str)bool
format_iban(iban: str)str
iban_countries()list[str]

Node.js Quick Start

Installation

npm install idsmith

Validation

const {
  BankAccount, PersonalId, CreditCard, CompanyId,
  Swift, DriverLicense, Passport, TaxId, validateIban
} = require('idsmith');

// IBAN
validateIban('DE47508562162522867909');  // true

// Personal ID
PersonalId.validate('US', '446-72-2445');  // true

// Credit Card
CreditCard.validate('4152839405126374');  // true

// Bank Account
BankAccount.validate('US', '021000021-123456789');  // true

// Company ID
CompanyId.validate('GB', 'GB123456789');  // true

// Driver's License
DriverLicense.validate('US', 'A123456789012');  // true

// Passport
Passport.validate('DE', 'C01234567');  // true

// Tax ID (TIN)
TaxId.validate('IN', 'ABCDE1234F');  // true

// SWIFT/BIC
Swift.validate('CHASGB2LXXX');  // true

Generation

const {
  BankAccount, PersonalId, CreditCard, CompanyId, Swift,
  DriverLicense, Passport, TaxId,
  generateIban, formatIban
} = require('idsmith');

// Generate an IBAN
const iban = generateIban('DE');
console.log(formatIban(iban));  // DE47 5085 6216 2522 8679 09

// Generate a bank account
const account = BankAccount.generate('US');
console.log(account.formatted);    // 021000021 | 123456789
console.log(account.countryCode);  // US

// Generate a personal ID with options
const code = PersonalId.generate('EE', 'female', 1990);
console.log(code);  // 49001011234

// Generate a credit card
const card = CreditCard.generate('visa');
console.log(card.formatted);  // 4152 8394 0512 6374
console.log(card.brand);      // VISA

// Generate a company ID
const company = CompanyId.generate('GB');
console.log(company.code);  // GB123456789

// Generate a SWIFT code
const swift = Swift.generate('US');
console.log(swift.code);  // CHASUSU5XXX

// Generate a Driver's License
const dl = DriverLicense.generate('US');

// Generate a Passport
const passport = Passport.generate('DE');

// Generate a Tax ID (TIN)
const tin = TaxId.generate('IN');

TypeScript

Full TypeScript support is included. Types are auto-generated from Rust definitions.

import {
  BankAccount, PersonalId, CreditCard,
  generateIban, validateIban,
  type AccountResult, type CardResult
} from 'idsmith';

const account: AccountResult = BankAccount.generate('US');
const card: CardResult = CreditCard.generate('visa');
const valid: boolean = validateIban('DE47508562162522867909');

Parsing

const result = PersonalId.parse('EE', '49001011234');
console.log(result.dob);     // 1990-01-01
console.log(result.gender);  // female
console.log(result.valid);   // true

Listing Supported Countries

const { BankAccount, PersonalId, CreditCard, ibanCountries } = require('idsmith');

// IBAN countries
const countries = ibanCountries();  // ['AD', 'AE', 'AL', ...]

// Bank account countries
BankAccount.listCountries().forEach(c => {
  console.log(`${c.code} - ${c.name} (${c.format})`);
});

// Personal ID countries
PersonalId.listCountries().forEach(c => {
  console.log(`${c.code} - ${c.countryName} (${c.idName})`);
});

// Credit card brands
CreditCard.listBrands();  // ['Visa', 'Mastercard', ...]

// Check support
BankAccount.isSupported('US');  // true
PersonalId.isSupported('EE');   // true

Error Handling

Unsupported countries throw an error:

try {
  PersonalId.generate('XX');
} catch (e) {
  console.error(e.message);  // Unsupported country: XX
}

Node.js API Reference

Classes

BankAccount

MethodSignatureReturns
generate(country: string, bankCode?: string)AccountResult
validate(country: string, raw: string)boolean
format(country: string, raw: string)string
listCountries()BankCountryInfo[]
isSupported(country: string)boolean
interface AccountResult {
  countryCode: string;
  countryName: string;
  formatName: string;
  bankCode: string | null;
  branchCode: string | null;
  accountNumber: string;
  checkDigits: string | null;
  formatted: string;
  raw: string;
  iban: string | null;
  valid: boolean;
}

interface BankCountryInfo {
  code: string;
  name: string;
  format: string;
  hasIban: boolean;
}

PersonalId

MethodSignatureReturns
generate(country: string, gender?: string, year?: number)string
validate(country: string, code: string)boolean
parse(country: string, code: string)IdResult
listCountries()CountryInfo[]
isSupported(country: string)boolean

gender parameter: "male" or "female" (or omit for random).

interface IdResult {
  countryCode: string;
  code: string;
  gender: string | null;
  dob: string | null;
  valid: boolean;
}

CreditCard

MethodSignatureReturns
generate(brand?: string)CardResult
validate(number: string)boolean
format(brand: string, number: string)string
listBrands()string[]

Supported brands: visa, mastercard, amex, discover, jcb, diners

interface CardResult {
  brand: string;
  number: string;
  formatted: string;
  cvv: string;
  expiry: string;
  valid: boolean;
}

CompanyId

MethodSignatureReturns
generate(country?: string)CompanyResult
validate(country: string, code: string)boolean
listCountries()CountryInfo[]
interface CompanyResult {
  countryCode: string;
  countryName: string;
  name: string;
  code: string;
  valid: boolean;
}

Swift

MethodSignatureReturns
generate(country?: string)SwiftResult
validate(code: string)boolean
interface SwiftResult {
  code: string;
  bank: string;
  country: string;
  location: string;
  branch: string | null;
  valid: boolean;
}

DriverLicense

MethodSignatureReturns
generate(country?: string)DriverLicenseResult
validate(country: string, code: string)boolean
listCountries()CountryInfo[]
isSupported(country: string)boolean
interface DriverLicenseResult {
  countryCode: string;
  countryName: string;
  name: string;
  code: string;
  valid: boolean;
}

TaxId

MethodSignatureReturns
generate(country?: string, options?: TaxIdOptions)TaxIdResult
validate(country: string, code: string)boolean
listCountries()CountryInfo[]
isSupported(country: string)boolean
interface TaxIdOptions {
  holderType?: string;  // IN only: P, C, H, F, A, T, B, L, J, G
}

interface TaxIdResult {
  countryCode: string;
  countryName: string;
  name: string;
  code: string;
  valid: boolean;
}

Passport

MethodSignatureReturns
generate(country?: string)PassportResult
validate(country: string, code: string)boolean
listCountries()CountryInfo[]
isSupported(country: string)boolean
interface PassportResult {
  countryCode: string;
  countryName: string;
  name: string;
  code: string;
  valid: boolean;
}

Functions

FunctionSignatureReturns
generateIban(country?: string)string
validateIban(iban: string)boolean
formatIban(iban: string)string
ibanCountries()string[]

Shared Types

interface CountryInfo {
  code: string;
  countryName: string;
  idName: string;
}

IBAN

Generate and validate IBANs for 124 countries with full mod-97-10 checksum validation.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
let mut rng = thread_rng();

let iban = idsmith::iban::generate_iban(Some("DE"), &mut rng).unwrap();
let formatted = idsmith::iban::format_iban(&iban);
// DE47 5085 6216 2522 8679 09

// Random country
let random = idsmith::iban::generate_iban(None, &mut rng).unwrap();
}

Python

import idsmith

iban = idsmith.generate_iban("DE")
formatted = idsmith.format_iban(iban)

# Random country
random = idsmith.generate_iban()

JavaScript

const { generateIban, formatIban } = require('idsmith');

const iban = generateIban('DE');
const formatted = formatIban(iban);

// Random country
const random = generateIban();

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::iban::validate_iban("DE47508562162522867909");  // true
}

Python

idsmith.validate_iban("DE47508562162522867909")  # True

JavaScript

validateIban('DE47508562162522867909');  // true

List Supported Countries

Rust

#![allow(unused)]
fn main() {
let countries = idsmith::iban::supported_countries();
// ["AD", "AE", "AL", "AT", ...]
}

Python

countries = idsmith.iban_countries()
# ["AD", "AE", "AL", "AT", ...]

JavaScript

const countries = ibanCountries();
// ['AD', 'AE', 'AL', 'AT', ...]

Personal ID

Generate, validate, and parse national identity numbers for 97 countries with checksum verification (SSN, CPF, Aadhaar, PESEL, etc.).

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::personal_id::{GenOptions, date::Gender};

let mut rng = thread_rng();
let registry = idsmith::personal_ids();

// Default options (random gender, random year)
let id = registry.generate("EE", &Default::default(), &mut rng).unwrap();

// With gender and year
let opts = GenOptions {
    gender: Some(Gender::Female),
    year: Some(1990),
};
let id = registry.generate("EE", &opts, &mut rng).unwrap();
}

Python

import idsmith

# Default options
code = idsmith.PersonalId.generate("EE")

# With gender and year
code = idsmith.PersonalId.generate("EE", gender="female", year=1990)

JavaScript

const { PersonalId } = require('idsmith');

// Default options
const code = PersonalId.generate('EE');

// With gender and year
const code2 = PersonalId.generate('EE', 'female', 1990);

Validate

Rust

#![allow(unused)]
fn main() {
let valid = idsmith::personal_ids().validate("US", "446-72-2445").unwrap();
}

Python

valid = idsmith.PersonalId.validate("US", "446-72-2445")  # True

JavaScript

const valid = PersonalId.validate('US', '446-72-2445');  // true

Parse

Extract metadata (date of birth, gender) from an ID.

Rust

#![allow(unused)]
fn main() {
let result = idsmith::personal_ids().parse("EE", "49001011234").unwrap();
// result.dob    → Some("1990-01-01")
// result.gender → Some("female")
// result.valid  → true
}

Python

result = idsmith.PersonalId.parse("EE", "49001011234")
# result["dob"]    → "1990-01-01"
# result["gender"] → "female"
# result["valid"]  → True

JavaScript

const result = PersonalId.parse('EE', '49001011234');
// result.dob    → '1990-01-01'
// result.gender → 'female'
// result.valid  → true

Checksum-Verified Countries (56)

RegionCountries
EuropeEE, LT, LV, FI, SE, NO, DK, IS, DE, AT, CH, NL, BE, FR, ES, PT, IT, GB, IE, PL, CZ, SK, RO, BG, HR, SI, RS, BA, ME, TR, GR
AmericasUS, CA, BR, AR, CL, CO, UY, EC, PE, MX
Asia-PacificCN, IN, JP, KR, TW, TH, SG, MY, ID, HK, AU, NZ
Africa/Middle EastZA, IL, EG

Bank Account

Generate, validate, and format bank account numbers for 159 countries. Includes specific implementations for 16 major economies with IBAN support for 124 countries.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::bank_account::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::bank_accounts();

let result = registry.generate("US", &GenOptions::default(), &mut rng).unwrap();
// result.formatted → "021000021 | 123456789"
// result.raw       → "021000021123456789"
// result.iban      → None (US doesn't use IBAN)

// IBAN countries include the IBAN
let de = registry.generate("DE", &GenOptions::default(), &mut rng).unwrap();
// de.iban → Some("DE47508562162522867909")
}

Python

import idsmith

result = idsmith.BankAccount.generate("US")
print(result["formatted"])  # 021000021 | 123456789
print(result["iban"])       # None

# With bank code filter
result = idsmith.BankAccount.generate("US", bank_code="021000021")

JavaScript

const { BankAccount } = require('idsmith');

const result = BankAccount.generate('US');
console.log(result.formatted);  // 021000021 | 123456789
console.log(result.iban);       // null

// With bank code filter
const result2 = BankAccount.generate('US', '021000021');

Validate

Rust

#![allow(unused)]
fn main() {
let valid = idsmith::bank_accounts().validate("MX", "167078019952865929").unwrap();
}

Python

valid = idsmith.BankAccount.validate("MX", "167078019952865929")

JavaScript

const valid = BankAccount.validate('MX', '167078019952865929');

Format

Rust

#![allow(unused)]
fn main() {
let formatted = idsmith::bank_accounts().format("US", "021000021123456789").unwrap();
}

Python

formatted = idsmith.BankAccount.format("US", "021000021123456789")

JavaScript

const formatted = BankAccount.format('US', '021000021123456789');

Specific Country Formats

CountryFormatHas IBAN
USABA Routing + AccountNo
CAInstitution + Transit + AccountNo
MXCLABE (18 digits)No
AUBSB + AccountNo
INIFSC + AccountNo
JPBank + Branch + AccountNo
CNBank Account (Luhn)No
GBSort Code + AccountYes
BRBank + Branch + AccountNo
ARCBUNo
NGNUBANNo
+ 85IBAN-based accountsYes
+ 140Generic bank formatsVaries

Credit Card

Generate and validate credit card numbers for 6 major brands with Luhn checksum. Generated cards include CVV (3 digits, 4 for Amex) and a random future expiration date.

Supported Brands

BrandPrefixLength
Visa416
Mastercard51-55, 2221-272016
Amex34, 3715
Discover6011, 65, 644-64916
JCB3528-358916
Diners300-305, 36, 3814

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::credit_card::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::credit_cards();

// Random brand
let card = registry.generate(&GenOptions::default(), &mut rng).unwrap();

// Specific brand
let opts = GenOptions { brand: Some("visa".to_string()) };
let visa = registry.generate(&opts, &mut rng).unwrap();
// visa.brand     → "VISA"
// visa.number    → "4152839405126374"
// visa.formatted → "4152 8394 0512 6374"
// visa.cvv       → "123"
// visa.expiry    → "09/28"
}

Python

import idsmith

card = idsmith.CreditCard.generate()           # random brand
visa = idsmith.CreditCard.generate(brand="visa")  # specific brand
print(visa["formatted"])  # 4152 8394 0512 6374
print(visa["cvv"])        # 123
print(visa["expiry"])     # 09/28

JavaScript

const { CreditCard } = require('idsmith');

const card = CreditCard.generate();        // random brand
const visa = CreditCard.generate('visa');  // specific brand
console.log(visa.formatted);  // 4152 8394 0512 6374
console.log(visa.cvv);        // 123
console.log(visa.expiry);     // 09/28

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::credit_cards().validate("4152839405126374");  // true
idsmith::credit_cards().validate("0000000000000000");  // false
}

Python

idsmith.CreditCard.validate("4152839405126374")  # True
idsmith.CreditCard.validate("0000000000000000")  # False

JavaScript

CreditCard.validate('4152839405126374');  // true
CreditCard.validate('0000000000000000');  // false

Format

Rust

#![allow(unused)]
fn main() {
idsmith::credit_cards().format("visa", "4152839405126374");
// "4152 8394 0512 6374"

idsmith::credit_cards().format("amex", "371449635398431");
// "3714 496353 98431"
}

Python

idsmith.CreditCard.format("visa", "4152839405126374")
# "4152 8394 0512 6374"

JavaScript

CreditCard.format('visa', '4152839405126374');
// '4152 8394 0512 6374'

Company ID

Generate and validate business identifiers (VAT numbers, EINs, CIFs) for 250 countries. Specific checksum implementations for GB, DE, FR, IT, and ES.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::company_id::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::company_ids();

// Random country
let result = registry.generate(&GenOptions::default(), &mut rng).unwrap();

// Specific country
let opts = GenOptions { country: Some("GB".to_string()) };
let gb = registry.generate(&opts, &mut rng).unwrap();
// gb.country_code → "GB"
// gb.name         → "VAT Number"
// gb.code         → "GB123456789"
}

Python

import idsmith

result = idsmith.CompanyId.generate()                   # random country
gb = idsmith.CompanyId.generate(country="GB")           # specific country
print(gb["name"])  # VAT Number
print(gb["code"])  # GB123456789

JavaScript

const { CompanyId } = require('idsmith');

const result = CompanyId.generate();      // random country
const gb = CompanyId.generate('GB');      // specific country
console.log(gb.name);  // VAT Number
console.log(gb.code);  // GB123456789

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::company_ids().validate("GB", "GB123456789");  // true
idsmith::company_ids().validate("DE", "DE141158922");  // true
}

Python

idsmith.CompanyId.validate("GB", "GB123456789")  # True

JavaScript

CompanyId.validate('GB', 'GB123456789');  // true

Checksum-Verified Countries

CountryFormatChecksum
GBVAT Number (9 digits)Weighted mod-97
DEUSt-IdNr (9 digits)ISO 7064 mod 11,10
FRTVA (11 digits)SIREN + mod-97
ITPartita IVA (11 digits)Luhn
ESCIF (letter + 7 digits + check)Custom weighted

SWIFT/BIC

Generate and validate 8 and 11 character SWIFT/BIC codes with ISO 9362 country positioning.

Format

A SWIFT code consists of:

  • 4 characters — bank code
  • 2 characters — ISO country code
  • 2 characters — location code
  • 3 characters (optional) — branch code

Example: CHAS US U5 XXXCHASUSU5XXX

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::swift::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::swift_codes();

// Random country
let result = registry.generate(&GenOptions::default(), &mut rng);

// Specific country
let opts = GenOptions { country: Some("US".to_string()) };
let us = registry.generate(&opts, &mut rng);
// us.code     → "CHASUSU5XXX"
// us.bank     → "CHAS"
// us.country  → "US"
// us.location → "U5"
// us.branch   → Some("XXX")
}

Python

import idsmith

result = idsmith.Swift.generate()                 # random country
us = idsmith.Swift.generate(country="US")         # specific country
print(us["code"])  # CHASUSU5XXX

JavaScript

const { Swift } = require('idsmith');

const result = Swift.generate();      // random country
const us = Swift.generate('US');      // specific country
console.log(us.code);  // CHASUSU5XXX

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::swift_codes().validate("CHASUSU5XXX");  // true (11 chars)
idsmith::swift_codes().validate("CHASUSU5");     // true (8 chars)
idsmith::swift_codes().validate("INVALID");      // false
}

Python

idsmith.Swift.validate("CHASUSU5XXX")  # True
idsmith.Swift.validate("CHASUSU5")     # True

JavaScript

Swift.validate('CHASUSU5XXX');  // true
Swift.validate('CHASUSU5');     // true

Known Banks

The generator uses real bank codes for major countries:

CountryBanks
USCHAS, CITI, BOFA, JPMC, WFCU
GBBARC, LLOY, HSBC, NWRS, RBOS
DEDEUT, COBA, DABA, DRE2, DZAD
FRBNPA, SOGE, CRLY, BCIT, BCEP

Other countries generate random 4-letter bank codes.

Driver’s License

Generate and validate driver’s license numbers for 79 countries with specific checksum and format implementations.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::driver_license::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::driver_licenses();

// Random country
let result = registry.generate(&GenOptions::default(), &mut rng).unwrap();

// Specific country
let opts = GenOptions { country: Some("US".to_string()), state: None };
let us = registry.generate(&opts, &mut rng).unwrap();
// us.country_code → "US"
// us.name         → "Driver's License"
// us.code         → "A123456789012"
}

Python

import idsmith

result = idsmith.DriverLicense.generate()                   # random country
us = idsmith.DriverLicense.generate(country="US")           # specific country
print(us["name"])  # Driver's License
print(us["code"])  # A123456789012

JavaScript

const { DriverLicense } = require('idsmith');

const result = DriverLicense.generate();      // random country
const us = DriverLicense.generate('US');      // specific country
console.log(us.name);  // Driver's License
console.log(us.code);  // A123456789012

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::driver_licenses().validate("US", "A123456789012");  // true
idsmith::driver_licenses().validate("IN", "KA0120190012345"); // true
}

Python

idsmith.DriverLicense.validate("US", "A123456789012")  # True

JavaScript

DriverLicense.validate('US', 'A123456789012');  // true

Country-Specific Implementations

CountryFormatDescription
IN15 chars ({STATE}{RTO}{YEAR}{SERIAL})Indian DL with state, RTO code, year, and serial
US13 chars (1 alpha + 12 digits)US driver’s license number
GB16 chars DVLA alphanumericDVLA format with name-derived characters
DE11 chars alphanumericGerman Führerschein number
FR12 chars (2 alpha + 10 digits)French permis de conduire
BR11 digits with 2 check digits (CNH)Brazilian CNH with mod-based check digits
AU8-10 chars alphanumericAustralian state-issued license
CA13 chars (1 alpha + 12 digits)Canadian provincial license
JP12 digitsJapanese driver’s license number
CN12 digitsChinese driver’s license number
IT10 chars (2 alpha + 7 digits + 1 alpha)Italian patente di guida
ES9 chars (8 digits + check letter)Spanish DNI-format with mod-23 check
NL10 digitsDutch rijbewijs number
SE10 digits (personnummer format)Swedish körkort with Luhn checksum
KR12 digits (region + year + serial)Korean driver’s license with region codes
SG9 chars (NRIC format)Singapore license with weighted checksum
ZA13 digits (ID number format)South African license with Luhn checksum
MX12 chars (CURP-derived)Mexican licencia de conducir

Tax ID

Generate and validate tax identification numbers for 80 countries with specific checksum and format implementations.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::tax_id::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::tax_ids();

// Random country
let result = registry.generate(&GenOptions::default(), &mut rng).unwrap();

// Specific country
let opts = GenOptions { country: Some("IN".to_string()), holder_type: None };
let india = registry.generate(&opts, &mut rng).unwrap();
// india.country_code → "IN"
// india.name         → "PAN"
// india.code         → "ABCDE1234F"

// India PAN with holder type
let opts = GenOptions {
    country: Some("IN".to_string()),
    holder_type: Some("C".to_string()),  // C = Company
};
let pan = registry.generate(&opts, &mut rng).unwrap();
}

Python

import idsmith

result = idsmith.TaxId.generate()                          # random country
india = idsmith.TaxId.generate(country="IN")               # specific country
print(india["name"])  # PAN
print(india["code"])  # ABCDE1234F

# India PAN with holder type
pan = idsmith.TaxId.generate(country="IN", holder_type="C")

JavaScript

const { TaxId } = require('idsmith');

const result = TaxId.generate();           // random country
const india = TaxId.generate('IN');        // specific country
console.log(india.name);  // PAN
console.log(india.code);  // ABCDE1234F

// India PAN with holder type
const pan = TaxId.generate('IN', { holderType: 'C' });

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::tax_ids().validate("IN", "ABCDE1234F");   // true
idsmith::tax_ids().validate("BR", "12345678909");   // true
}

Python

idsmith.TaxId.validate("IN", "ABCDE1234F")  # True

JavaScript

TaxId.validate('IN', 'ABCDE1234F');  // true

Checksum-Verified Countries

CountryFormatChecksum
INPAN (10 chars, AAAAA0000A)Pattern validation, holder_type option (P/C/H/F/A/T/B/L/J/G)
USTIN (9 digits)Area number constraints (no 000, 666, 9xx)
GBUTR (10 digits)Weighted mod-11 checksum
DESteuer-IdNr (11 digits)ISO 7064 mod 11,10
FRNIF (13 digits)Mod-97 checksum
BRCPF (11 digits)Mod-11 checksum (two check digits)
AUTFN (9 digits)Weighted checksum (mod 11)
CASIN (9 digits)Luhn checksum
JPMy Number (12 digits)Mod-11 weighted checksum
CNUSCI (18 chars alphanumeric)Mod-31 weighted checksum
ITPartita IVA (11 digits)Luhn-variant checksum
ESNIF (8 digits + letter)Mod-23 check letter
NLBSN (9 digits)11-check (weighted sum)
SEPersonnummer (10 digits)Luhn checksum
KRBRN (10 digits)Weighted check digit
SGTax Ref (9 chars, NRIC format)Weighted mod-11 with check letter
ZATax Number (10 digits)Luhn checksum
MXRFC (12-13 chars)Mod-11 alphanumeric check digit

Passport

Generate and validate passport numbers for 79 countries with specific format implementations.

Generate

Rust

#![allow(unused)]
fn main() {
use rand::thread_rng;
use idsmith::passport::GenOptions;

let mut rng = thread_rng();
let registry = idsmith::passports();

// Random country
let result = registry.generate(&GenOptions::default(), &mut rng).unwrap();

// Specific country
let opts = GenOptions { country: Some("US".to_string()) };
let us = registry.generate(&opts, &mut rng).unwrap();
// us.country_code → "US"
// us.name         → "Passport"
// us.code         → "123456789"
}

Python

import idsmith

result = idsmith.Passport.generate()                   # random country
us = idsmith.Passport.generate(country="US")           # specific country
print(us["name"])  # Passport
print(us["code"])  # 123456789

JavaScript

const { Passport } = require('idsmith');

const result = Passport.generate();      // random country
const us = Passport.generate('US');      // specific country
console.log(us.name);  // Passport
console.log(us.code);  // 123456789

Validate

Rust

#![allow(unused)]
fn main() {
idsmith::passports().validate("US", "123456789");   // true
idsmith::passports().validate("DE", "C01X00T47");   // true
}

Python

idsmith.Passport.validate("US", "123456789")  # True

JavaScript

Passport.validate('US', '123456789');  // true

Country-Specific Implementations

CountryFormatDescription
IN8 chars (1 alpha + 7 digits)Indian passport number
US9 digitsUS passport number
GB9 digitsBritish passport number
DE9 chars (C + 8 alphanumeric)German Reisepass with serial check digit
FR9 chars (2 alpha + 7 digits)French passport number
BR8 chars (2 alpha + 6 digits)Brazilian passport number
AU8 chars (1 alpha + 7 digits)Australian passport number
CA8 chars (2 alpha + 6 digits)Canadian passport number
JP9 chars (2 alpha + 7 digits)Japanese passport number
CN9 chars (E/G + 8 digits)Chinese passport (E for ordinary, G for official)
IT9 chars (2 alpha + 7 digits)Italian passaporto
ES9 chars (3 alpha + 6 digits)Spanish pasaporte
NL9 chars (2 alpha + 7 digits)Dutch paspoort
SE8 digitsSwedish pass
KR9 chars (M/S + 8 digits)Korean passport (M = regular, S = official)
SG9 chars (E + 7 digits + 1 alpha)Singapore passport
ZA9 chars (1 alpha + 8 digits)South African passport
MX10 digitsMexican pasaporte

Contributing

See the full CONTRIBUTING.md on GitHub.

Quick Reference

Core Rust Crate

cargo test -p idsmith
cargo fmt -p idsmith -- --check
cargo clippy -p idsmith -- -D warnings

Python Bindings

cd bindings/python
pip install maturin[patchelf] pytest
maturin develop
pytest tests/ -v

Node.js Bindings

cd bindings/node
npm install
npm run build
npm test

Repo Structure

idsmith/
├── src/                   # Rust core library + CLI
├── tests/                 # Integration tests
├── bindings/
│   ├── python/            # PyO3 + maturin → PyPI
│   └── node/              # napi-rs → npm
├── docs/                  # This documentation (mdBook)
└── .github/workflows/     # CI per package