qrx
Interactive QR code toolkit. Create plain or encrypted QR codes
(text, URL, WiFi, vCard, phone, SMS, email, location, calendar
event), save them as .png/.jpg, and read them back — all through
a simple terminal menu, no flags or arguments to memorize.
Installation
pip install qrx
or clone this repo and:
pip install -e .
Usage
qrx
or, without installing:
python run.py
You'll see:
1) Create QR code
2) Create encrypted QR code (readable only via qrx)
3) Read QR code
1) Create QR code
Asks which type of QR you want:
1) Plain text
2) URL
3) WiFi
4) vCard (contact)
5) Phone number
6) SMS
7) Email
8) Location (geo)
9) Calendar event
Each type asks exactly the fields it needs — pick WiFi and it asks
for network name/password/security type; pick vCard and it asks for
name/phone/email/organization/title, and so on. You never type a raw
QR payload format yourself; qrx builds the correct standard string
(WIFI:..., mailto:..., tel:..., smsto:..., geo:..., vCard,
iCalendar) for you.
At the end, you're asked for an output filename (.png or .jpg),
and the QR code image is saved there.
2) Create encrypted QR code
Exactly the same flow as option 1 (pick a type, answer its questions), but at the end you also set a password. The content is encrypted before being placed into the QR code.
Important: the QR code you get is a completely normal, standard QR
code — any phone camera can scan it. But scanning it with a regular
camera app just shows unreadable encrypted text. Only qrx (with
the correct password) can turn it back into the real content.
3) Read QR code
Asks for the path to a QR code image (.png/.jpg/.jpeg).
- If it's a normal QR code, the decoded content is shown directly.
- If it's a
qrx-encrypted QR code, you're asked for the password. Correct password → the real content is shown. Wrong password → you're told it's wrong, nothing is revealed.
Why passwords, not links
A QR code can only hold a few kilobytes of data — nowhere near
enough for a real image/photo. So qrx sticks to text-based payloads
(the 9 types above), which is also what makes it work completely
offline: no server, no internet connection needed to generate or
read a qrx QR code (unless the QR itself encodes a URL that points
somewhere — the QR always scans fine, but whether the destination
page loads depends on that server being up, same as any URL).
Programmatic usage (advanced)
If you want to skip the interactive menu and call things directly from your own code:
from qrx import formats, qr, crypto
# build a payload
payload = formats.build_wifi("MyNetwork", "mypassword", security="WPA")
# generate a QR image from it
qr.generate_qr_image(payload, "wifi.png")
# read it back
decoded = qr.read_qr_image("wifi.png")
# encrypt/decrypt payloads directly
encrypted = crypto.encrypt_payload("secret message", "mypassword")
crypto.is_encrypted(encrypted) # True
original = crypto.decrypt_payload(encrypted, "mypassword")
Available builders in qrx.formats:
| Function | Type |
|---|---|
build_plain_text(text) |
Plain text |
build_url(url) |
URL |
build_wifi(ssid, password, security, hidden) |
WiFi |
build_vcard(full_name, phone, email, organization, title) |
vCard |
build_phone(number) |
Phone number |
build_sms(number, message) |
SMS |
build_email(address, subject, body) |
|
build_geo(latitude, longitude) |
Location |
build_calendar_event(title, start, end, location, description) |
Calendar event |
How the encryption works
qrx uses Fernet (AES-128-CBC with HMAC authentication) from the
cryptography library. The password is turned into an encryption
key using PBKDF2-HMAC-SHA256 with a random 16-byte salt and 390,000
iterations, so the same password produces a different encrypted
result every time, and brute-forcing the password is expensive.
The encrypted payload embedded in the QR code looks like:
QRX-ENC-V1:<base64 salt>.<fernet token>
The QRX-ENC-V1: prefix is how qrx recognizes its own encrypted
QR codes when reading one back — it's not a secret, just a marker.
Notes
- QR error correction is set to level M (up to ~15% of the code can be damaged/obscured and still scan correctly).
- If multiple QR codes exist in one image, only the first one found is read.
- This is a local, offline tool — nothing is sent anywhere. Your data and passwords never leave your machine.
Release files for qrx 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qrx-0.1.0.tar.gz | 10.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qrx-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.1 kB
Release files / qrx-0.1.0.tar.gz
| Download URL | qrx-0.1.0.tar.gz |
|---|---|
| Size | 10.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac17de0e9f83a5912ff69ddeaad871699c430e1b241f90e63cd3f88322607e73
|
|
BLAKE2b-256 checksum How to use checksums |
54cfee048136c60e552a8825f3a0dd469ef11b50cbdb527649f87deda1975490
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|
Release files / qrx-0.1.0-py3-none-any.whl
| Download URL | qrx-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
924969fcc54d7acf99934bc4ac704acc8b67387f3c5bdef2cba679115fc97994
|
|
BLAKE2b-256 checksum How to use checksums |
29d2eb8db8e6f848d60823e66d33f36a65e31a72f762d2a1cae7bd8d3f8107fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.0
|