DEV Community

Cover image for The story of one QR-code...
Sergey Royz
Sergey Royz

Posted on

The story of one QR-code...

As a beginner programmer, you may have heard of QR codes, those square-shaped patterns of black and white squares that store information such as URLs, contact information, or other types of data. But have you ever wondered how QR codes work or how you could generate one in Python? In this article, we'll explore a Python script that generates an ASCII QR code from a given set of data.


The Code Breakdown

Let's start by breaking down the code step by step:

1. Importing Necessary Libraries

import json
import base64
from typing import NamedTuple, Union
Enter fullscreen mode Exit fullscreen mode

The code begins by importing two standard Python libraries: json for working with JSON data and base64 for handling Base64-encoded strings. Additionally, it imports the NamedTuple class and the Union type hint from the typing module.

2. Defining a NamedTuple

class TextToQR(NamedTuple):
    n0: int
    x: int
    c: str
Enter fullscreen mode Exit fullscreen mode

Here, a NamedTuple named TextToQR is defined with three fields: n0, x, and c. This NamedTuple will be used to represent the data needed to generate the ASCII QR code.

3. Generating the ASCII QR Code

def generate_ascii_qr_code(qr: TextToQR, margin: int = 2) -> list[str]:
    # Decode the Base64 string and convert it to a binary string
    decoded = bytes(base64.b64decode(qr.c)).decode('utf-8')
    binary = ''.join(list(map(lambda b: bin(ord(b)).replace('0b', '').zfill(8), decoded)))
    binary = binary[qr.n0:]

    x = qr.x

    rows = []
    rows.extend(['  ' * (x + margin * 2) for _ in range(margin)])

    for i in range(x):
        row = binary[i * x:(i + 1) * x]
        row = ''.join(list(map(lambda c: '█' * 2 if c == '1' else '  ', row)))
        rows.append(('  ' * margin) + row + ('  ' * margin))

    rows.extend(['  ' * (x + margin * 2) for _ in range(margin)])

    return rows
Enter fullscreen mode Exit fullscreen mode

This function, generate_ascii_qr_code, takes a TextToQR object as input along with an optional margin parameter. It generates an ASCII QR code based on the provided data.

  1. The Base64-encoded string qr.c is first decoded and converted to a binary string.

  2. The binary string is sliced starting from the index qr.n0. This allows you to specify where in the binary string to begin generating the QR code.

  3. The code then constructs the ASCII QR code by iterating through the binary string, replacing '1' with '██' (two filled squares) and '0' with ' ' (two spaces).

  4. Rows of spaces are added to the top and bottom of the code to create a margin, as specified by the margin parameter.

  5. The function returns a list of strings, where each string represents a row of the ASCII QR code.

4. Main Program

if __name__ == "__main__":
    data = """
    {
    "n0": 7,
    "x": 29,
    "c": "AcO9wp5nw7ggBsKgw50Swp12w6rDnsKLwrdTwrJdwoLCh1oPw7VVX8OAKF4BF8K8b8Kcw5/CqGpPw69JdsOmEMORF8OnwoJOLMKeAMKkfQHCl8K/YMKnBXzCvcOjw61KEcOKB3fCuXQDMmBedsKfw7AAwp8Yw6fDt8OLw5dgwpLCti11wq1fwpvCpMOZF10Nw7JeCMKNw4/Cn8OTwolS"
    }
    """
    data = json.loads(data)

    qr = generate_ascii_qr_code(TextToQR(**data))
    for line in qr:
        print(line)
Enter fullscreen mode Exit fullscreen mode

The main program begins by loading JSON data containing the QR code configuration. It then calls the generate_ascii_qr_code function with this data and prints each row of the generated ASCII QR code.

Let's see how it works!

After running the code from the above it produces the following awesome output!



    ██████████████  ████    ████████    ████    ██████████████    
    ██          ██                    ████  ██  ██          ██    
    ██  ██████  ██      ██    ██  ██    ██████  ██  ██████  ██    
    ██  ██████  ██  ██  ████  ████████  ██      ██  ██████  ██    
    ██  ██████  ██  ██    ██████  ████    ██    ██  ██████  ██    
    ██          ██  ██        ██████  ██  ████  ██          ██    
    ██████████████  ██  ██  ██  ██  ██  ██  ██  ██████████████    
                    ██  ██        ██  ████████                    
    ██      ██  ████████  ████████      ████  ██████████    ██    
    ████    ████  ████████████  ██  ██        ████  ██  ██        
    ██    ██████████████  ████████  ██    ██    ██  ██████  ██    
    ██  ██████    ████        ██        ████  ██      ██          
    ██  ████████████    ████████          ██    ██    ██████      
        ██  ████    ██    ████████                  ██  ██        
    ██      ██████████  ██              ████    ██  ████████      
    ████████████  ████          ██  ██    ██████          ██      
    ██  ██████████    ██  ████████  ████████      ██████████      
    ████  ██  ██    ██  ██        ██      ██████    ██  ██        
            ██████  ██████  ████████  ██████    ██  ██████  ██    
                    ████    ████    ██    ████            ██      
    ████████    ██████  ████  ██    ██████████████████            
                    ██    ██████████      ████      ██████        
    ██████████████  ██████████    ██  ████████  ██  ██████  ██    
    ██          ██    ██    ██  ██  ████  ████      ██  ████      
    ██  ██████  ██  ████  ██  ████  ██  ██  ████████████    ██    
    ██  ██████  ██    ██    ████  ████    ██      ██  ██████      
    ██  ██████  ██        ████  ██████████    ██    ██  ██████    
    ██          ██      ██      ████  ██████    ██████████        
    ██████████████  ██    ██████      ██    ██  ██  ██    ██      



Enter fullscreen mode Exit fullscreen mode

Can you read the code? ;)

Tools

  • the service used in the article: https://qrshare.io
  • CLI tool for instant file upload from the console:
pip install qrshare-io-cli
Enter fullscreen mode Exit fullscreen mode

Thanks for reading till then!
I hope this was useful to you, let me know in the comments what you think.

Top comments (2)

Collapse
 
zjor profile image
Sergey Royz

Check out my Chrome extension to generate QR-codes and download links in the format described in the article:

chrome.google.com/webstore/detail/...

Image description

Collapse
 
garptica profile image
Tom

How does the code handle the Base64-encoded string to generate the ASCII QR code?