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
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
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
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.
The Base64-encoded string
qr.c
is first decoded and converted to a binary string.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.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).
Rows of spaces are added to the top and bottom of the code to create a margin, as specified by the margin parameter.
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)
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!
██████████████ ████ ████████ ████ ██████████████
██ ██ ████ ██ ██ ██
██ ██████ ██ ██ ██ ██ ██████ ██ ██████ ██
██ ██████ ██ ██ ████ ████████ ██ ██ ██████ ██
██ ██████ ██ ██ ██████ ████ ██ ██ ██████ ██
██ ██ ██ ██████ ██ ████ ██ ██
██████████████ ██ ██ ██ ██ ██ ██ ██ ██████████████
██ ██ ██ ████████
██ ██ ████████ ████████ ████ ██████████ ██
████ ████ ████████████ ██ ██ ████ ██ ██
██ ██████████████ ████████ ██ ██ ██ ██████ ██
██ ██████ ████ ██ ████ ██ ██
██ ████████████ ████████ ██ ██ ██████
██ ████ ██ ████████ ██ ██
██ ██████████ ██ ████ ██ ████████
████████████ ████ ██ ██ ██████ ██
██ ██████████ ██ ████████ ████████ ██████████
████ ██ ██ ██ ██ ██ ██████ ██ ██
██████ ██████ ████████ ██████ ██ ██████ ██
████ ████ ██ ████ ██
████████ ██████ ████ ██ ██████████████████
██ ██████████ ████ ██████
██████████████ ██████████ ██ ████████ ██ ██████ ██
██ ██ ██ ██ ██ ████ ████ ██ ████
██ ██████ ██ ████ ██ ████ ██ ██ ████████████ ██
██ ██████ ██ ██ ████ ████ ██ ██ ██████
██ ██████ ██ ████ ██████████ ██ ██ ██████
██ ██ ██ ████ ██████ ██████████
██████████████ ██ ██████ ██ ██ ██ ██ ██
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
Thanks for reading till then!
I hope this was useful to you, let me know in the comments what you think.
Top comments (2)
Check out my Chrome extension to generate QR-codes and download links in the format described in the article:
chrome.google.com/webstore/detail/...
How does the code handle the Base64-encoded string to generate the ASCII QR code?