QR Code (Quick Response Code) is a two-dimensional barcode capable of storing large amounts of data while supporting rapid scanning and recognition. From mobile payments to product traceability, QR codes have become an integral part of our daily lives. This guide provides a comprehensive overview of QR Code encoding principles, technical details, and best practices.

Table of Contents

Key Takeaways

  • High Storage Capacity: QR Codes can store up to 7,089 numeric characters or 4,296 alphanumeric characters.
  • Fast Recognition: Three finder patterns enable scanners to quickly locate and read from any angle.
  • Robust Error Correction: Supports four error correction levels (L/M/Q/H), recovering up to 30% of damaged data.
  • Multiple Encoding Modes: Supports numeric, alphanumeric, byte, and Kanji encoding modes.
  • 40 Versions: From 21×21 to 177×177 modules, accommodating different data capacity needs.
  • Wide Applications: Extensively used in payments, marketing, logistics, and authentication.

Need to generate a QR code quickly? Try our free online tool with multiple formats and customization options.

Generate QR Code Now - Free Online QR Code Generator

What is a QR Code?

QR Code (Quick Response Code) is a two-dimensional barcode invented by Denso Wave, a Japanese company, in 1994. Unlike traditional one-dimensional barcodes that can only store data horizontally, QR Codes store information in both horizontal and vertical directions, resulting in much higher data density.

Key characteristics of QR Codes:

  1. High Data Density: Storage capacity is tens of times greater than traditional barcodes
  2. Omnidirectional Scanning: Supports 360-degree scanning from any angle
  3. Fault Tolerance: Can be read correctly even when partially damaged
  4. Fast Decoding: Specifically designed for high-speed reading

QR Code Structure Explained

A standard QR Code consists of multiple functional regions:

┌─────────────────────────────────────┐
│ ▓▓▓▓▓▓▓ ░░░░░░░░░░░░░░░ ▓▓▓▓▓▓▓ │
│ ▓░░░░░▓ ░░░░░░░░░░░░░░░ ▓░░░░░▓ │
│ ▓░▓▓▓░▓ ░░░░░░░░░░░░░░░ ▓░▓▓▓░▓ │
│ ▓░▓▓▓░▓ ░░░ Data Area ░░░ ▓░▓▓▓░▓ │
│ ▓░▓▓▓░▓ ░░░░░░░░░░░░░░░ ▓░▓▓▓░▓ │
│ ▓░░░░░▓ ░░░░░░░░░░░░░░░ ▓░░░░░▓ │
│ ▓▓▓▓▓▓▓ ░▓░▓░▓░▓░▓░▓░▓░ ▓▓▓▓▓▓▓ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░ Data & Error Code ░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓▓▓▓▓▓▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓░░░░░▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓░▓▓▓░▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓░▓▓▓░▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓░▓▓▓░▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓░░░░░▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ▓▓▓▓▓▓▓ ░░░░░░░░░░░░░░░░░░░░░░░░ │
└─────────────────────────────────────┘

Finder Patterns

Each of the three corners of a QR Code contains a 7×7 module finder pattern. These patterns have a unique 1:1:3:1:1 ratio that can be quickly identified regardless of the scanning direction.

▓▓▓▓▓▓▓
▓░░░░░▓
▓░▓▓▓░▓
▓░▓▓▓░▓
▓░▓▓▓░▓
▓░░░░░▓
▓▓▓▓▓▓▓

Functions of finder patterns:

  • Help scanners determine the position and orientation of the QR Code
  • Calculate the tilt angle of the QR Code
  • Determine module size

Timing Patterns

Timing patterns are alternating black and white module lines connecting the three finder patterns, helping scanners determine the coordinate positions of modules.

Horizontal timing: ▓░▓░▓░▓░▓░▓░▓
Vertical timing: Same alternating pattern

Format Information

The format information region stores two key parameters:

  • Error Correction Level (2 bits): L, M, Q, H levels
  • Mask Pattern (3 bits): One of 8 mask patterns

Format information is BCH encoded with built-in error correction capability.

Data Region

The data region stores the actual encoded data and error correction codes. Data is filled into modules following a specific path, typically starting from the bottom-right corner and moving upward in a serpentine pattern.

Data Encoding Modes

QR Codes support four main encoding modes, each optimized for different types of data:

Mode Mode Indicator Supported Characters Bits per Character
Numeric 0001 0-9 3.33 bits
Alphanumeric 0010 0-9, A-Z, space, $%*+-./: 5.5 bits
Byte 0100 ISO 8859-1 / UTF-8 8 bits
Kanji 1000 Shift JIS characters 13 bits

Numeric Mode Encoding Example

Numeric mode groups digits into sets of three, converting each group to 10-bit binary:

Input: "01234567"
Groups: "012" "345" "67"
Encoding: 012 → 0000001100 (10 bits)
          345 → 0101011001 (10 bits)
          67  → 1000011    (7 bits, last group < 3 digits)

Alphanumeric Mode Encoding Example

Alphanumeric mode maps characters to values 0-44, encoding two characters as 11 bits:

Character value table: 0-9→0-9, A-Z→10-35, space→36, $→37, %→38...

Input: "AC-42"
Groups: "AC" "-4" "2"
Encoding: AC → (10×45+12) = 462 → 00111001110 (11 bits)
          -4 → (41×45+4)  = 1849 → 11100111001 (11 bits)
          2  → 2 → 000010 (6 bits, single character)

Error Correction Mechanism

Error correction capability is one of the most important features of QR Codes, implemented using Reed-Solomon error correction codes.

Four Error Correction Levels

Level Name Recovery Capacity Use Case
L Low ~7% Large data, clean environment
M Medium ~15% General purpose (recommended default)
Q Quartile ~25% Industrial, possible damage
H High ~30% Harsh environment, logo overlay

Reed-Solomon Error Correction

Reed-Solomon (RS) codes are powerful error correction codes widely used in CDs, DVDs, QR Codes, and more.

How it works:

  1. Data Polynomial: Data is treated as polynomial coefficients over the finite field GF(2^8)
  2. Generator Polynomial: A specific generator polynomial is used to calculate error correction codes
  3. Error Code Calculation: The data polynomial divided by the generator polynomial yields the error correction code as the remainder
Let D(x) be the data polynomial, G(x) be the generator polynomial
Error code E(x) = D(x) × x^n mod G(x)
where n is the number of error correction bytes

Error Correction Capacity Calculation:

RS codes can correct:

  • Error correction bytes = 2t (where t is the number of correctable error symbols)
  • If there are e errors and r erasures: 2e + r ≤ 2t

QR Code Versions and Capacity

QR Codes have 40 versions, with the version number determining the size and data capacity:

Version Modules Numeric Capacity (L) Alphanumeric Capacity (L) Byte Capacity (L)
1 21×21 41 25 17
2 25×25 77 47 32
5 37×37 154 93 64
10 57×57 652 395 271
20 97×97 1,903 1,153 792
40 177×177 7,089 4,296 2,953

Version Selection Formula:

Modules = 17 + (Version × 4)
Example: Version 10 = 17 + (10 × 4) = 57 modules

Code Examples

JavaScript

// Using the qrcode library to generate QR codes
// npm install qrcode

import QRCode from 'qrcode';

// Generate QR code as Data URL (for displaying in web pages)
async function generateQRCodeDataURL(text, options = {}) {
  const defaultOptions = {
    errorCorrectionLevel: 'M',
    type: 'image/png',
    width: 256,
    margin: 2,
    color: {
      dark: '#000000',
      light: '#ffffff'
    }
  };
  
  const config = { ...defaultOptions, ...options };
  
  try {
    const dataURL = await QRCode.toDataURL(text, config);
    return dataURL;
  } catch (error) {
    console.error('Failed to generate QR code:', error);
    throw error;
  }
}

// Generate QR code to Canvas
async function generateQRCodeToCanvas(canvas, text, options = {}) {
  await QRCode.toCanvas(canvas, text, {
    errorCorrectionLevel: 'H',
    width: 300,
    ...options
  });
}

// Generate SVG format QR code
async function generateQRCodeSVG(text) {
  const svgString = await QRCode.toString(text, {
    type: 'svg',
    errorCorrectionLevel: 'M'
  });
  return svgString;
}

// Usage example
const qrDataURL = await generateQRCodeDataURL('https://qubittool.com', {
  errorCorrectionLevel: 'H',
  width: 512
});
console.log('QR code generated:', qrDataURL);

Python

import qrcode
from qrcode.constants import ERROR_CORRECT_L, ERROR_CORRECT_M, ERROR_CORRECT_Q, ERROR_CORRECT_H
from PIL import Image
import io
import base64

def generate_qrcode(data: str, 
                    error_correction: str = 'M',
                    box_size: int = 10,
                    border: int = 4,
                    fill_color: str = 'black',
                    back_color: str = 'white') -> Image.Image:
    """
    Generate a QR Code
    
    Args:
        data: The data to encode
        error_correction: Error correction level ('L', 'M', 'Q', 'H')
        box_size: Pixel size of each module
        border: Border width (in modules)
        fill_color: Foreground color
        back_color: Background color
    
    Returns:
        PIL Image object
    """
    error_levels = {
        'L': ERROR_CORRECT_L,
        'M': ERROR_CORRECT_M,
        'Q': ERROR_CORRECT_Q,
        'H': ERROR_CORRECT_H
    }
    
    qr = qrcode.QRCode(
        version=None,  # Auto-select version
        error_correction=error_levels.get(error_correction, ERROR_CORRECT_M),
        box_size=box_size,
        border=border
    )
    
    qr.add_data(data)
    qr.make(fit=True)
    
    img = qr.make_image(fill_color=fill_color, back_color=back_color)
    return img

def generate_qrcode_with_logo(data: str, 
                               logo_path: str,
                               logo_size_ratio: float = 0.3) -> Image.Image:
    """
    Generate a QR code with embedded logo (uses H-level error correction for readability)
    """
    qr = qrcode.QRCode(
        error_correction=ERROR_CORRECT_H,
        box_size=10,
        border=4
    )
    qr.add_data(data)
    qr.make(fit=True)
    
    qr_img = qr.make_image(fill_color='black', back_color='white').convert('RGB')
    
    logo = Image.open(logo_path)
    qr_width, qr_height = qr_img.size
    logo_max_size = int(qr_width * logo_size_ratio)
    logo.thumbnail((logo_max_size, logo_max_size), Image.Resampling.LANCZOS)
    
    logo_pos = ((qr_width - logo.size[0]) // 2, (qr_height - logo.size[1]) // 2)
    qr_img.paste(logo, logo_pos)
    
    return qr_img

def qrcode_to_base64(img: Image.Image, format: str = 'PNG') -> str:
    """Convert QR code image to Base64 string"""
    buffer = io.BytesIO()
    img.save(buffer, format=format)
    return base64.b64encode(buffer.getvalue()).decode()

# Usage example
if __name__ == '__main__':
    # Generate basic QR code
    qr_img = generate_qrcode(
        'https://qubittool.com/en/tools/qrcode-generator',
        error_correction='H',
        box_size=10
    )
    qr_img.save('qrcode.png')
    
    # Get QR code info
    print(f"QR code size: {qr_img.size}")
    print(f"Base64 length: {len(qrcode_to_base64(qr_img))}")

Go

package main

import (
	"image/png"
	"os"

	"github.com/skip2/go-qrcode"
)

// ErrorCorrectionLevel represents error correction level
type ErrorCorrectionLevel int

const (
	Low      ErrorCorrectionLevel = iota // 7% error correction
	Medium                               // 15% error correction
	High                                 // 25% error correction
	Highest                              // 30% error correction
)

// GenerateQRCode generates a QR code and saves it as a PNG file
func GenerateQRCode(content string, level qrcode.RecoveryLevel, size int, filename string) error {
	return qrcode.WriteFile(content, level, size, filename)
}

// GenerateQRCodeBytes generates a QR code and returns PNG byte data
func GenerateQRCodeBytes(content string, level qrcode.RecoveryLevel, size int) ([]byte, error) {
	return qrcode.Encode(content, level, size)
}

// GenerateQRCodeWithColor generates a QR code with custom colors
func GenerateQRCodeWithColor(content string, level qrcode.RecoveryLevel, size int, filename string) error {
	qr, err := qrcode.New(content, level)
	if err != nil {
		return err
	}

	qr.DisableBorder = false

	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	return png.Encode(file, qr.Image(size))
}

func main() {
	// Generate basic QR code
	err := GenerateQRCode(
		"https://qubittool.com/en/tools/qrcode-generator",
		qrcode.High, // Use high error correction level
		256,
		"qrcode.png",
	)
	if err != nil {
		panic(err)
	}

	// Generate QR code byte data
	pngData, err := GenerateQRCodeBytes(
		"Hello, QR Code!",
		qrcode.Medium,
		512,
	)
	if err != nil {
		panic(err)
	}

	println("QR code PNG data size:", len(pngData), "bytes")
}

Best Practices

1. Choose the Right Error Correction Level

Use Case Recommended Level Reason
Web links, digital content L or M Small data, good display environment
Print materials, business cards M Balance capacity and error correction
Industrial labels, outdoor Q or H Possible damage, wear
Logo embedding required H Logo will obscure some data

2. Optimize Data Encoding

// Optimize URL length
// Bad: https://www.example.com/products/item?id=12345&ref=qrcode
// Good: https://example.com/p/12345

// Use URL shortener services
// Bad: https://qubittool.com/en/tools/qrcode-generator?utm_source=print&utm_medium=flyer
// Good: https://qbt.io/qr

// Use numeric mode for pure numeric data
// Data "1234567890" in numeric mode saves ~60% space compared to byte mode

3. Ensure Sufficient Contrast

/* Recommended color contrast */
.qrcode-good {
  /* Dark foreground, light background */
  --foreground: #000000;
  --background: #ffffff;
}

.qrcode-acceptable {
  /* Dark blue foreground, light background */
  --foreground: #1a365d;
  --background: #f7fafc;
}

/* Colors to avoid */
.qrcode-bad {
  /* Insufficient contrast */
  --foreground: #718096;
  --background: #a0aec0;
}

4. Maintain Adequate Quiet Zone

QR codes require at least 4 modules of white space (quiet zone) around them to ensure scanners can correctly identify boundaries.

Recommended quiet zone width:
- Minimum: 4 modules
- Recommended: 4-8 modules
- Print materials: 6-8 modules suggested

5. Test on Different Devices and Environments

// QR code testing checklist
const testChecklist = [
  'Test under different lighting conditions',
  'Test with multiple phone models',
  'Test with different scanning apps',
  'Verify readability after printing',
  'Test minimum recognizable size',
  'Check readability with logo overlay'
];

Common Use Cases

1. Mobile Payments

QR code payments are currently the most widespread application:

  • Static codes: Merchants display fixed payment codes
  • Dynamic codes: Unique QR code generated for each transaction
  • Security considerations: Use short expiration times, amount limits

2. Product Traceability

QR code content example:
{
  "product_id": "SKU123456",
  "batch": "2026-01-12-A",
  "factory": "Shenzhen Factory",
  "trace_url": "https://trace.example.com/SKU123456"
}

3. Authentication

  • Electronic tickets (concerts, flights, trains)
  • Membership cards and coupons
  • Access control systems

4. Marketing Promotion

  • Product packaging linking to detail pages
  • Offline ads driving online traffic
  • Social media account follows

5. Information Sharing

  • WiFi connection information
  • Electronic business cards (vCard)
  • Geographic coordinates
WiFi QR code format:
WIFI:T:WPA;S:NetworkName;P:Password;;

vCard format:
BEGIN:VCARD
VERSION:3.0
N:Doe;John
TEL:+1-555-123-4567
EMAIL:john.doe@example.com
END:VCARD

FAQ

How much data can a QR code store?

QR Code maximum capacity depends on version and error correction level:

  • Numeric: Up to 7,089 characters (Version 40, L-level error correction)
  • Alphanumeric: Up to 4,296 characters
  • Byte data: Up to 2,953 bytes
  • Kanji: Up to 1,817 characters

In practice, it's recommended to keep data under 500 bytes to ensure a good scanning experience.

How do I choose the right QR code size?

QR code minimum size depends on:

  • Scanning distance
  • Print resolution
  • Data volume (version)

Rule of thumb:

Minimum size (mm) ≈ Scanning distance (mm) / 10

Examples:
- Close-range phone scanning (10-30cm): Recommend 2-3cm
- Poster long-range scanning (1-2m): Recommend 10-20cm

Can QR codes use colors?

Yes, but note:

  • Foreground color must be darker than background
  • Maintain at least 40% contrast
  • Avoid gradient colors
  • Red and green may have insufficient contrast

How do I embed a logo in a QR code?

  1. Use H-level (30%) error correction
  2. Logo size should not exceed 30% of QR code area
  3. Place logo in the center
  4. Ensure logo edges are clear
  5. Always test readability after generation

What's the difference between QR codes and barcodes?

Feature 1D Barcode QR Code
Data direction Horizontal Horizontal + Vertical
Data capacity ~20 characters Up to 7000+ characters
Error correction None 7%-30%
Scanning angle Horizontal 360 degrees
Data types Numbers/letters only Any binary

How can I generate a QR code without coding?

You can use online tools like our free QR code generator to quickly generate QR codes in various formats without writing any code, with support for custom colors, sizes, and error correction levels.

Conclusion

QR Code, as a mature two-dimensional encoding technology, has become an essential part of modern digital life thanks to its high capacity, robust error correction, and fast recognition. Understanding its encoding principles and best practices will help you better utilize QR code technology across various application scenarios.

Quick Summary:

  • Use M-level error correction for general purposes, H-level for logo embedding
  • Keep data concise, prefer short links
  • Ensure adequate contrast and quiet zone
  • Always test on multiple devices after generation
  • Choose appropriate size based on scanning distance

Ready to generate a QR code? Try our free online tool:

Generate QR Code Now - Free Online QR Code Generator