Generate 10-Digit Random Numbers in Python

I was working on a project that required generating unique 10-digit identifiers for customer accounts in a banking application. The challenge was to create truly random 10-digit numbers that wouldn’t repeat and look natural.

I’ve discovered that there are several reliable ways to generate 10-digit random numbers. Each method has its advantages depending on your specific use case.

In this article, I’ll share 5 proven methods to generate 10-digit random numbers in Python, complete with practical examples and real-world applications.

Method 1: Use random.randint() Function

Python’s random.randint() function is probably the simplest way to generate 10-digit random numbers. I use this method when I need simple random numbers without any special formatting requirements.

Here’s how it works:

import random

# Generate a single 10-digit random number
def generate_10_digit_number():
    return random.randint(1000000000, 9999999999)

# Generate multiple 10-digit numbers
def generate_multiple_numbers(count):
    numbers = []
    for i in range(count):
        numbers.append(random.randint(1000000000, 9999999999))
    return numbers

# Example usage
single_number = generate_10_digit_number()
print(f"Single 10-digit number: {single_number}")

# Generate 5 random 10-digit numbers
multiple_numbers = generate_multiple_numbers(5)
print("Multiple 10-digit numbers:")
for i, number in enumerate(multiple_numbers, 1):
    print(f"{i}. {number}")

You can refer to the screenshot below to see the output.

random 10 digit number

This method generates numbers between 1,000,000,000 and 9,999,999,999, ensuring you always get exactly 10 digits.

Method 2: Use random.randrange() Function

Python’s random.randrange() function gives you more control over the range and step size. I often prefer this method when working with large datasets because it’s slightly more efficient.

import random

# Using randrange for 10-digit numbers
def generate_with_randrange():
    return random.randrange(1000000000, 10000000000)

# Generate numbers with specific patterns
def generate_phone_like_numbers(area_code="555"):
    """Generate 10-digit numbers that look like US phone numbers"""
    # First 3 digits are area code, next 7 are random
    remaining_digits = random.randrange(1000000, 10000000)
    return int(f"{area_code}{remaining_digits}")

# Generate numbers avoiding certain digits
def generate_without_zeros():
    """Generate 10-digit numbers without zeros"""
    while True:
        number = random.randrange(1000000000, 10000000000)
        if '0' not in str(number):
            return number

# Example usage
print("Using randrange:")
for i in range(3):
    print(f"{i+1}. {generate_with_randrange()}")

print("\nPhone-like numbers:")
for i in range(3):
    phone_number = generate_phone_like_numbers()
    # Format as phone number for display
    formatted = f"({str(phone_number)[:3]}) {str(phone_number)[3:6]}-{str(phone_number)[6:]}"
    print(f"{i+1}. {phone_number} -> {formatted}")

print("\nNumbers without zeros:")
for i in range(3):
    print(f"{i+1}. {generate_without_zeros()}")

You can refer to the screenshot below to see the output.

10 digit random number generator

This method offers efficient range control and flexibility, especially for patterned or filtered number generation.

Method 3: Use String Formatting with random.choice()

When I need more control over individual digits or want to create numbers with specific patterns, I use string formatting with random.choice() methods in Python. This method is perfect for creating realistic-looking data.

import random
import string

# Generate 10-digit numbers using string methods
def generate_with_string_method():
    """Generate 10-digit number by choosing each digit"""
    # First digit cannot be 0 for a true 10-digit number
    first_digit = random.choice('123456789')
    remaining_digits = ''.join(random.choices('0123456789', k=9))
    return int(first_digit + remaining_digits)

# Generate numbers with weighted probabilities
def generate_weighted_digits():
    """Generate numbers where certain digits appear more frequently"""
    digits = '0123456789'
    # Weight digits 1-5 more heavily than 6-9 and 0
    weights = [5, 10, 10, 10, 10, 10, 5, 5, 5, 5]  # corresponds to digits 0-9

    first_digit = random.choices('123456789', k=1)[0]  # First digit can't be 0
    remaining_digits = random.choices(digits, weights=weights, k=9)

    return int(first_digit + ''.join(remaining_digits))

# Generate Social Security Number-like format (for testing only)
def generate_ssn_format():
    """Generate 10-digit number in XXX-XX-XXXXX format"""
    # Note: This is for educational purposes only - never use for real SSNs
    part1 = random.randint(100, 999)  # 3 digits
    part2 = random.randint(10, 99)    # 2 digits  
    part3 = random.randint(10000, 99999)  # 5 digits

    number_only = int(f"{part1}{part2:02d}{part3}")
    formatted = f"{part1}-{part2:02d}-{part3}"

    return number_only, formatted

# Example usage
print("String method generation:")
for i in range(3):
    print(f"{i+1}. {generate_with_string_method()}")

print("\nWeighted digit generation:")
for i in range(3):
    print(f"{i+1}. {generate_weighted_digits()}")

print("\nSSN-like format (testing only):")
for i in range(3):
    number, formatted = generate_ssn_format()
    print(f"{i+1}. {number} -> {formatted}")

You can refer to the screenshot below to see the output.

generate 10 digit random number

This approach provides fine-grained control over each digit, making it ideal for realistic and custom patterns.

Method 4: Use the secrets Module for Cryptographically Secure Numbers

For applications requiring high security, such as generating unique transaction IDs or temporary passwords, I always use the secrets module. It provides cryptographically secure random numbers.

import secrets
import random

# Cryptographically secure 10-digit numbers
def generate_secure_10_digit():
    """Generate cryptographically secure 10-digit number"""
    return secrets.randbelow(9000000000) + 1000000000

# Generate secure numbers for different use cases
def generate_transaction_id():
    """Generate secure transaction ID"""
    return secrets.randbelow(9000000000) + 1000000000

def generate_secure_batch(count):
    """Generate multiple secure numbers ensuring uniqueness"""
    numbers = set()
    while len(numbers) < count:
        numbers.add(generate_secure_10_digit())
    return list(numbers)

# Generate secure numbers with custom prefix
def generate_account_number(bank_code="001"):
    """Generate account numbers with bank code prefix"""
    # Bank code (3 digits) + 7 random digits
    random_part = secrets.randbelow(9000000) + 1000000
    return int(f"{bank_code}{random_part}")

# Compare security vs speed
def compare_methods():
    """Compare regular random vs secrets module"""
    import time

    # Test regular random
    start_time = time.time()
    regular_numbers = [random.randint(1000000000, 9999999999) for _ in range(1000)]
    regular_time = time.time() - start_time

    # Test secrets module
    start_time = time.time()
    secure_numbers = [generate_secure_10_digit() for _ in range(1000)]
    secure_time = time.time() - start_time

    print(f"Regular random: {regular_time:.4f} seconds for 1000 numbers")
    print(f"Secrets module: {secure_time:.4f} seconds for 1000 numbers")
    print(f"Secure method is {secure_time/regular_time:.2f}x slower")

# Example usage
print("Cryptographically secure numbers:")
for i in range(3):
    print(f"{i+1}. Transaction ID: {generate_transaction_id()}")

print("\nSecure unique batch:")
secure_batch = generate_secure_batch(5)
for i, number in enumerate(secure_batch, 1):
    print(f"{i}. {number}")

print("\nAccount numbers with bank code:")
for i in range(3):
    account = generate_account_number("105")  # Bank code 105
    formatted_account = f"{str(account)[:3]}-{str(account)[3:]}"
    print(f"{i+1}. {account} -> {formatted_account}")

print("\nPerformance comparison:")
compare_methods()

You can refer to the screenshot below to see the output.

random 10 digit number generator

This method ensures cryptographically secure random numbers, suitable for sensitive and high-security applications.

Method 5: Use Custom Functions for Specific Formats

In real-world applications, I often need to generate numbers that follow specific business rules or formats. Here are some custom functions I’ve developed over the years.

import random
import time
from datetime import datetime

class RandomNumberGenerator:
    """Custom class for generating various 10-digit number formats"""
    
    def __init__(self):
        self.used_numbers = set()
    
    def generate_unique_number(self):
        """Generate unique 10-digit numbers (no repeats)"""
        while True:
            number = random.randint(1000000000, 9999999999)
            if number not in self.used_numbers:
                self.used_numbers.add(number)
                return number
    
    def generate_timestamp_based(self):
        """Generate number based on current timestamp"""
        # Use current timestamp + random digits
        timestamp = int(time.time())
        # Take last 6 digits of timestamp + 4 random digits
        timestamp_part = timestamp % 1000000
        random_part = random.randint(1000, 9999)
        return int(f"{timestamp_part:06d}{random_part}")
    
    def generate_checksum_number(self):
        """Generate 9-digit number + 1 checksum digit"""
        # Generate 9 random digits
        base_number = random.randint(100000000, 999999999)
        
        # Calculate simple checksum (sum of digits mod 10)
        digit_sum = sum(int(digit) for digit in str(base_number))
        checksum = digit_sum % 10
        
        return int(f"{base_number}{checksum}")
    
    def generate_formatted_id(self, prefix="", suffix=""):
        """Generate ID with optional prefix/suffix"""
        if prefix and suffix:
            # Calculate remaining digits needed
            total_prefix_suffix = len(str(prefix)) + len(str(suffix))
            if total_prefix_suffix >= 10:
                raise ValueError("Prefix and suffix too long for 10-digit number")
            
            remaining_digits = 10 - total_prefix_suffix
            random_part = random.randint(10**(remaining_digits-1), 10**remaining_digits - 1)
            return int(f"{prefix}{random_part}{suffix}")
        else:
            return random.randint(1000000000, 9999999999)
    
    def generate_luhn_compliant(self):
        """Generate 10-digit number that passes Luhn algorithm check"""
        # Generate first 9 digits
        digits = [random.randint(1, 9)]  # First digit can't be 0
        digits.extend([random.randint(0, 9) for _ in range(8)])
        
        # Calculate Luhn checksum for last digit
        def luhn_checksum(card_num):
            def digits_of(n):
                return [int(d) for d in str(n)]
            digits = digits_of(card_num)
            odd_digits = digits[-1::-2]
            even_digits = digits[-2::-2]
            checksum = sum(odd_digits)
            for d in even_digits:
                checksum += sum(digits_of(d*2))
            return checksum % 10
        
        base_num = int(''.join(map(str, digits)))
        check_digit = (10 - luhn_checksum(base_num * 10)) % 10
        return int(f"{base_num}{check_digit}")
    
    def generate_us_zip_extended(self):
        """Generate 10-digit numbers that look like US ZIP+4 codes"""
        # ZIP code (5 digits) + extension (4 digits) + random digit
        zip_code = random.randint(10000, 99999)
        extension = random.randint(1000, 9999)
        extra_digit = random.randint(0, 9)
        return int(f"{zip_code}{extension}{extra_digit}")

Advanced usage examples

def demonstrate_custom_methods():
    """Demonstrate all custom methods"""
    generator = RandomNumberGenerator()
    
    print("Custom 10-digit number generation methods:\n")
    
    # Unique numbers
    print("1. Unique numbers (no repeats):")
    for i in range(3):
        unique_num = generator.generate_unique_number()
        print(f"   {i+1}. {unique_num}")
    
    # Timestamp-based
    print("\n2. Timestamp-based numbers:")
    for i in range(3):
        timestamp_num = generator.generate_timestamp_based()
        print(f"   {i+1}. {timestamp_num}")
        time.sleep(0.1)  # Small delay to show different timestamps
    
    # Checksum numbers
    print("\n3. Numbers with checksum:")
    for i in range(3):
        checksum_num = generator.generate_checksum_number()
        # Show the checksum digit
        checksum_digit = str(checksum_num)[-1]
        base_part = str(checksum_num)[:-1]
        print(f"   {i+1}. {checksum_num} (base: {base_part}, checksum: {checksum_digit})")
    
    # Formatted IDs
    print("\n4. Formatted IDs with prefix/suffix:")
    formatted_ids = [
        generator.generate_formatted_id(prefix="20", suffix="1"),  # Year prefix, category suffix
        generator.generate_formatted_id(prefix="555"),             # Area code prefix
        generator.generate_formatted_id(suffix="99")               # Status suffix
    ]
    for i, formatted_id in enumerate(formatted_ids, 1):
        print(f"   {i}. {formatted_id}")
    
    # Luhn compliant
    print("\n5. Luhn algorithm compliant numbers:")
    for i in range(3):
        luhn_num = generator.generate_luhn_compliant()
        print(f"   {i+1}. {luhn_num}")
    
    # ZIP+4 style
    print("\n6. US ZIP+4 style numbers:")
    for i in range(3):
        zip_num = generator.generate_us_zip_extended()
        # Format for display
        zip_str = str(zip_num)
        formatted_zip = f"{zip_str[:5]}-{zip_str[5:9]}-{zip_str[9]}"
        print(f"   {i+1}. {zip_num} -> {formatted_zip}")

Real-world application example

def create_customer_system():
    """Example of using 10-digit numbers in a customer management system"""
    generator = RandomNumberGenerator()
    
    class Customer:
        def __init__(self, name, state):
            self.name = name
            self.state = state
            self.customer_id = generator.generate_unique_number()
            self.account_number = generator.generate_checksum_number()
            self.transaction_id = generator.generate_timestamp_based()
    
    # Create sample customers
    customers = [
        Customer("John Smith", "CA"),
        Customer("Sarah Johnson", "TX"),
        Customer("Mike Davis", "NY"),
        Customer("Lisa Wilson", "FL"),
        Customer("Robert Brown", "WA")
    ]
    
    print("Customer Management System - Generated IDs:")
    print("-" * 70)
    print(f"{'Name':<15} {'State':<5} {'Customer ID':<12} {'Account #':<12} {'Transaction ID':<12}")
    print("-" * 70)
    
    for customer in customers:
        print(f"{customer.name:<15} {customer.state:<5} {customer.customer_id:<12} "
              f"{customer.account_number:<12} {customer.transaction_id:<12}")

# Run demonstrations
if __name__ == "__main__":
    demonstrate_custom_methods()
    print("\n" + "="*70 + "\n")
    create_customer_system()

This approach allows you to meet specific business rules or formats, enabling highly tailored number generation.

Performance Comparison and Best Practices

Based on my experience, here’s when to use each method:

import time
import random
import secrets

def performance_benchmark():
    """Compare performance of different methods"""
    methods = {
        'randint': lambda: random.randint(1000000000, 9999999999),
        'randrange': lambda: random.randrange(1000000000, 10000000000),
        'secrets': lambda: secrets.randbelow(9000000000) + 1000000000,
        'string_method': lambda: int(''.join(random.choices('123456789', k=1) + random.choices('0123456789', k=9)))
    }
    
    iterations = 10000
    results = {}
    
    for method_name, method_func in methods.items():
        start_time = time.time()
        for _ in range(iterations):
            method_func()
        end_time = time.time()
        results[method_name] = end_time - start_time
    
    print(f"Performance test ({iterations:,} iterations):")
    for method, duration in sorted(results.items(), key=lambda x: x[1]):
        print(f"{method:<15}: {duration:.4f} seconds")

# Run performance test
performance_benchmark()

Throughout my Python development career, I’ve found these 5 methods to be incredibly reliable for generating 10-digit random numbers. Each method serves different purposes – from simple random generation to cryptographically secure applications.

The random.randint() method works perfectly for basic applications like generating test data or simple IDs. When I need better performance with large datasets, random.randrange() is my go-to choice.

For applications requiring formatting control or specific digit patterns, the string formatting approach gives you maximum flexibility. The secrets module is essential when security matters, such as generating transaction IDs or temporary authentication codes.

You may also like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.