Determining card brand based on card number

Benchmark created on


Setup

class TrieNode {
    constructor() {
        this.children = {};
        this.cardBrand = null;
    }
}

class CardBrandTrie {
    constructor() {
        this.root = new TrieNode();
    }

    insert(prefix, cardBrand) {
        let node = this.root;
        for (const char of prefix) {
            if (!node.children[char]) {
                node.children[char] = new TrieNode();
            }
            node = node.children[char];
        }
        node.cardBrand = cardBrand;
    }

    search(cardNumber) {
        let node = this.root;
        let brand = null;
        for (const char of cardNumber) {
            if (node.children[char]) {
                node = node.children[char];
                if (node.cardBrand) {
                    brand = node.cardBrand;
                }
            } else {
                break;
            }
        }
        return brand;
    }
}

// Initialize the trie with card brand data
const cardBrandTrie = new CardBrandTrie();

const cardBrandData = [
    { brand: "Visa", prefixes: ["4"] },
    { brand: "MasterCard", prefixes: ["51", "52", "53", "54", "55", "2221", "2222", "2223", "2224", "2225", "2226", "2227", "2228", "2229", "223", "224", "225", "226", "227", "228", "229", "23", "24", "25", "26", "270", "271", "2720"] },
    { brand: "American Express", prefixes: ["34", "37"] },
    { brand: "Discover", prefixes: ["6011", "622126", "622127", "622128", "622129", "62213", "62214", "62215", "62216", "62217", "62218", "62219", "6222", "6223", "6224", "6225", "6226", "6227", "6228", "62290", "62291", "622920", "622921", "622922", "622923", "622924", "622925", "644", "645", "646", "647", "648", "649", "65"] },
    { brand: "JCB", prefixes: ["3528", "3529", "353", "354", "355", "356", "357", "358"] },
    { brand: "Diners Club International", prefixes: ["36"] },
    { brand: "Diners Club Carte Blanche", prefixes: ["300", "301", "302", "303", "304", "305"] },
    { brand: "Diners Club enRoute", prefixes: ["2014", "2149"] },
    { brand: "Diners Club US & Canada", prefixes: ["54"] },
    { brand: "Maestro", prefixes: ["5018", "5020", "5038", "5612", "5893", "6304", "6759", "6761", "6762", "6763"] },
    { brand: "UnionPay", prefixes: ["62"] },
    { brand: "Mir", prefixes: ["2200", "2201", "2202", "2203", "2204"] },
    { brand: "InterPayment", prefixes: ["636"] },
    { brand: "InstaPayment", prefixes: ["637", "638", "639"] },
    { brand: "UATP", prefixes: ["1"] },
    { brand: "RuPay", prefixes: ["60", "6521", "6522"] }
];

for (const { brand, prefixes } of cardBrandData) {
    for (const prefix of prefixes) {
        cardBrandTrie.insert(prefix, brand);
    }
}

function getCardBrandByTrie(cardNumber) {
    return cardBrandTrie.search(cardNumber);
}


// Card brand prefix map
const cardBrandMap = {
    "4": "Visa",
    "51": "MasterCard", "52": "MasterCard", "53": "MasterCard", "54": "MasterCard", "55": "MasterCard",
    "2221": "MasterCard", "2222": "MasterCard", "2223": "MasterCard", "2224": "MasterCard",
    "2225": "MasterCard", "2226": "MasterCard", "2227": "MasterCard", "2228": "MasterCard",
    "2229": "MasterCard", "223": "MasterCard", "224": "MasterCard", "225": "MasterCard",
    "226": "MasterCard", "227": "MasterCard", "228": "MasterCard", "229": "MasterCard",
    "23": "MasterCard", "24": "MasterCard", "25": "MasterCard", "26": "MasterCard", "270": "MasterCard",
    "271": "MasterCard", "2720": "MasterCard",
    "34": "American Express", "37": "American Express",
    "6011": "Discover", "622126": "Discover", "622127": "Discover", "622128": "Discover",
    "622129": "Discover", "62213": "Discover", "62214": "Discover", "62215": "Discover",
    "62216": "Discover", "62217": "Discover", "62218": "Discover", "62219": "Discover",
    "6222": "Discover", "6223": "Discover", "6224": "Discover", "6225": "Discover",
    "6226": "Discover", "6227": "Discover", "6228": "Discover", "62290": "Discover",
    "62291": "Discover", "622920": "Discover", "622921": "Discover", "622922": "Discover",
    "622923": "Discover", "622924": "Discover", "622925": "Discover", "644": "Discover",
    "645": "Discover", "646": "Discover", "647": "Discover", "648": "Discover", "649": "Discover",
    "65": "Discover",
    "3528": "JCB", "3529": "JCB", "353": "JCB", "354": "JCB", "355": "JCB", "356": "JCB",
    "357": "JCB", "358": "JCB",
    "36": "Diners Club International",
    "300": "Diners Club Carte Blanche", "301": "Diners Club Carte Blanche", "302": "Diners Club Carte Blanche",
    "303": "Diners Club Carte Blanche", "304": "Diners Club Carte Blanche", "305": "Diners Club Carte Blanche",
    "2014": "Diners Club enRoute", "2149": "Diners Club enRoute",
    "54": "Diners Club US & Canada",
    "5018": "Maestro", "5020": "Maestro", "5038": "Maestro", "5612": "Maestro", "5893": "Maestro",
    "6304": "Maestro", "6759": "Maestro", "6761": "Maestro", "6762": "Maestro", "6763": "Maestro",
    "62": "UnionPay",
    "2200": "Mir", "2201": "Mir", "2202": "Mir", "2203": "Mir", "2204": "Mir",
    "636": "InterPayment",
    "637": "InstaPayment", "638": "InstaPayment", "639": "InstaPayment",
    "1": "UATP",
    "60": "RuPay", "6521": "RuPay", "6522": "RuPay"
};

// Function to get card brand based on input number
function getCardBrandBySlice(cardNumber) {
    // Iterate over possible prefix lengths (up to 6 for the longest known prefix)
    for (let i = 1; i <= 6; i++) {
        const prefix = cardNumber.slice(0, i);
        if (cardBrandMap[prefix]) {
            return cardBrandMap[prefix];
        }
    }
    return null;
}

Test runner

Ready to run.

Testing in
TestOps/sec
Getting card brands by Trie
getCardBrandByTrie("4");
getCardBrandByTrie("6521");
ready
Getting card brands by Slice
getCardBrandBySlice("4");
getCardBrandBySlice("6521");
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.