python
17 lines · 6 steps
Validating card numbers with the Luhn check
A digit-doubling checksum catches most mistyped or invalid card numbers.
Explained by
highlit
1def is_valid_card_number(number: str) -> bool:
2 digits = [int(c) for c in number if c.isdigit()]
3
4 if len(digits) < 13 or len(digits) > 19:
5 return False
6
7 checksum = 0
8 parity = len(digits) % 2
9
10 for index, digit in enumerate(digits):
11 if index % 2 == parity:
12 digit *= 2
13 if digit > 9:
14 digit -= 9
15 checksum += digit
16
17 return checksum % 10 == 0
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1The Luhn algorithm doubles every other digit and subtracts 9 when the result exceeds 9, which is equivalent to summing its digits.
- 2Deriving parity from the total length lets you double the correct positions no matter how many digits there are.
- 3A checksum that must be divisible by 10 catches most single-digit typos and simple transpositions cheaply.
Related explainers
typescript
import { NestFactory } from '@nestjs/core'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { ValidationPipe } from '@nestjs/common'; import { ApiProperty } from '@nestjs/swagger';
Wiring validation and Swagger docs in NestJS
validation
openapi
decorators
Intermediate
8 steps
python
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status from pydantic import BaseModel, EmailStr from sqlalchemy.orm import Session
Building a signup endpoint in FastAPI
dependency-injection
request-validation
background-tasks
Intermediate
8 steps
python
from django import forms from django.utils import timezone from .models import Reservation
Multi-field validation in a Django ModelForm
form validation
cross-field validation
modelform
Intermediate
7 steps
python
from django import template from django.urls import reverse, NoReverseMatch from django.utils.html import format_html
Active nav-link template tags in Django
template tags
url routing
active state
Intermediate
7 steps
python
from functools import wraps import asyncio from fastapi import APIRouter, FastAPI, Request
Per-route request timeouts in FastAPI
decorators
async
timeouts
Intermediate
6 steps
rust
use std::net::Ipv4Addr; use std::str::FromStr; #[derive(Debug, Clone, Copy)]
Parsing and matching IPv4 CIDR ranges in Rust
bitwise-operations
parsing
error-handling
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/validating-card-numbers-with-the-luhn-check-explained-python-829f/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.