Last active
November 4, 2024 16:31
-
-
Save kdmukai/5b696635ed3c68d2784aabe7ea62cef2 to your computer and use it in GitHub Desktop.
Utility to brute force calculate target QR code densities for given QR formats and output display resolutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Utility to brute force calculate target QR code densities for given QR formats and output | |
display resolutions. | |
""" | |
""" | |
density | qr size | char capacity | px per module | |
10 | 33x33 | 114 | 7.15 # L | |
26 | 33x33 | 154 | 7.15 | |
30 | 37x37 | 154 | 6.38 # M | |
46 | 37x37 | 195 | 6.38 | |
69 | 41x41 | 224 | 5.76 | |
82 | 45x45 | 279 | 5.24 | |
111 | 49x49 | 335 | 4.82 | |
120 | 53x53 | 335 | 4.45 # H | |
138 | 53x53 | 395 | 4.45 | |
171 | 57x57 | 468 | 4.14 | |
209 | 61x61 | 535 | 3.87 | |
246 | 65x65 | 619 | 3.63 | |
283 | 69x69 | 667 | 3.42 | |
314 | 73x73 | 758 | 3.23 | |
354 | 77x77 | 854 | 3.06 | |
404 | 81x81 | 938 | 2.91 | |
472 | 85x85 | 1046 | 2.78 | |
515 | 89x89 | 1153 | 2.65 | |
566 | 93x93 | 1249 | 2.54 | |
629 | 97x97 | 1352 | 2.43 | |
708 | 101x101 | 1588 | 2.34 | |
809 | 109x109 | 1704 | 2.17 | |
944 | 113x113 | 1990 | 2.09 | |
999 | 121x121 | 1990 | 1.95 | |
Results for 240px display: | |
density | qr size | char capacity | px per module | |
10 | 33x33 | 114 | 7.15 | |
26 | 33x33 | 154 | 7.15 # 7px per module | |
46 | 37x37 | 195 | 6.38 | |
69 | 41x41 | 224 | 5.76 # 6px per module | |
82 | 45x45 | 279 | 5.24 | |
111 | 49x49 | 335 | 4.82 # 5px per module | |
138 | 53x53 | 395 | 4.45 | |
171 | 57x57 | 468 | 4.14 | |
209 | 61x61 | 535 | 3.87 # 4px per module | |
246 | 65x65 | 619 | 3.63 | |
283 | 69x69 | 667 | 3.42 | |
314 | 73x73 | 758 | 3.23 | |
354 | 77x77 | 854 | 3.06 # 3px per module | |
404 | 81x81 | 938 | 2.91 | |
472 | 85x85 | 1046 | 2.78 | |
515 | 89x89 | 1153 | 2.65 | |
566 | 93x93 | 1249 | 2.54 | |
629 | 97x97 | 1352 | 2.43 | |
708 | 101x101 | 1588 | 2.34 | |
809 | 109x109 | 1704 | 2.17 | |
944 | 113x113 | 1990 | 2.09 | |
999 | 121x121 | 1990 | 1.95 # 2px per module | |
density | qr size | char capacity | px per module | |
10 | 33x33 | 114 | 7.15 | |
27 | 33x33 | 154 | 7.15 +1 | |
47 | 37x37 | 195 | 6.38 +1 | |
68 | 41x41 | 224 | 5.76 +1 | |
85 | 45x45 | 279 | 5.24 +3 | |
114 | 49x49 | 335 | 4.82 +3 | |
142 | 53x53 | 395 | 4.45 +4 | |
171 | 57x57 | 468 | 4.14 | |
214 | 61x61 | 535 | 3.87 +5 | |
244 | 65x65 | 619 | 3.63 +2 | |
285 | 69x69 | 667 | 3.42 +2 | |
342 | 73x73 | 758 | 3.23 +28 | |
428 | 77x77 | 938 | 3.06 +74 | |
570 | 85x85 | 1249 | 2.78 +98 | |
856 | 97x97 | 1853 | 2.43 +227 | |
999 | 117x117 | 1853 | 2.02 n/a | |
density | qr size | char capacity | px per module | |
26 | 33x33 | 154 | 7.15 | |
69 | 41x41 | 224 | 5.76 | |
111 | 49x49 | 335 | 4.82 | |
209 | 61x61 | 535 | 3.87 | |
354 | 77x77 | 854 | 3.06 | |
999 | 121x121 | 1990 | 1.95 | |
qr_density 10 = 33x33 | |
qr_density 30 = 37x37 | |
qr_density 120 = 53x53 | |
""" | |
import os | |
from seedsigner.models.encode_qr import UrPsbtQrEncoder, UrXpubQrEncoder | |
from embit import psbt | |
from binascii import a2b_base64 | |
# keys: max char capacity | |
# values: QR module size | |
QR_CAPACITY__ALPHANUMERIC_L = { | |
25: 21, | |
47: 25, | |
77: 29, | |
114: 33, | |
154: 37, | |
195: 41, | |
224: 45, | |
279: 49, | |
335: 53, | |
395: 57, | |
468: 61, | |
535: 65, | |
619: 69, | |
667: 73, | |
758: 77, | |
854: 81, | |
938: 85, | |
1046: 89, | |
1153: 93, | |
1249: 97, | |
1352: 101, | |
1460: 105, | |
1588: 109, | |
1704: 113, | |
1853: 117, | |
1990: 121, | |
2132: 125, | |
2223: 129, | |
2369: 133, | |
2528: 137, | |
2677: 141, | |
2840: 145, | |
3009: 149, | |
3183: 153, | |
3351: 157, | |
3537: 161, | |
} | |
def ur_psbt_qr_encoder(screen_width: int = 240, screen_height: int = 240, min_density: int = 10, max_density: int = 1000): | |
base64_psbt = "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" | |
tx = psbt.PSBT.parse(a2b_base64(base64_psbt)) | |
total_available_pixels = min(screen_width, screen_height) | |
border = 2 # TODO: make this a GUIConstant | |
available_pixels = total_available_pixels - border * 2 | |
# max_qr_modules = available_pixels // 2 # must have at least 2 pixels per QR module | |
max_qr_modules = available_pixels | |
qr_img_output_dir = os.path.join(os.getcwd(), "imgs") | |
os.mkdir(qr_img_output_dir) if not os.path.exists(qr_img_output_dir) else None | |
max_density_for_qr_modules = [] | |
prev_num_modules = 0 | |
pixels_per_qr_block = 0 | |
for density in range(min_density, max_density): | |
e = UrPsbtQrEncoder(psbt=tx, max_fragment_len=density) | |
e.ur2_encode.fountain_encoder.seq_num = e.seq_len() - 1 # final part will max out the sequence number | |
fragment = e.next_part() | |
eligible_qr_modules = [(k, v) for k, v in QR_CAPACITY__ALPHANUMERIC_L.items() if k >= len(fragment) and v <= max_qr_modules] | |
if not eligible_qr_modules: | |
print(f"density (max_fragment_size) ({density}) is too large for available QR module size") | |
break | |
qr_capacity, num_qr_modules = eligible_qr_modules[0] | |
if num_qr_modules != prev_num_modules or density in [10, 30, 120]: | |
img = e.part_to_image(fragment, width=screen_width, height=screen_height, border=border) | |
if prev_num_modules == 0 or density in [10, 30, 120]: | |
pixels_per_qr_block = available_pixels / num_qr_modules | |
max_density_for_qr_modules.append((density, num_qr_modules, qr_capacity, pixels_per_qr_block)) | |
img.save(os.path.join(qr_img_output_dir, f"{density:03}__{num_qr_modules}x{num_qr_modules}.png")) | |
else: | |
max_density_for_qr_modules.append((density - 1, prev_num_modules, qr_capacity, pixels_per_qr_block)) | |
img.save(os.path.join(qr_img_output_dir, f"{density - 1:03}__{prev_num_modules}x{prev_num_modules}.png")) | |
prev_num_modules = num_qr_modules | |
pixels_per_qr_block = available_pixels / num_qr_modules | |
# print(f"{density=:4} | {len(fragment)=} | QR size: {qr_modules}x{qr_modules} | {pixels_per_qr_block=:.2f}") | |
max_density_for_qr_modules.append((density, num_qr_modules, qr_capacity, pixels_per_qr_block)) | |
img.save(os.path.join(qr_img_output_dir, f"{density:03}__{num_qr_modules}x{num_qr_modules}.png")) | |
print(f"{'density'} | {'qr size'} | {'char capacity'} | {'px per module'}") | |
for density, num_qr_modules, qr_capacity, pixels_per_qr_block in max_density_for_qr_modules: | |
print(f"{density:>7} | {str(num_qr_modules) + 'x' + str(num_qr_modules):>7} | {qr_capacity:13} | {pixels_per_qr_block:>13.2f}") | |
# cnt = 0 | |
# max_len = 0 | |
# longest = None | |
# while cnt <= 10: | |
# fragment = e.next_part() | |
# if len(fragment) > max_len: | |
# longest = fragment | |
# max_len =len(fragment) | |
# # e.part_to_image(fragment, 240, 240) | |
# cnt += 1 | |
# print(f"{density=:4} | {max_len=:4} | {max_len - density*2=} | {longest=}") | |
if __name__ == "__main__": | |
ur_psbt_qr_encoder() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment