diff --git a/shell/qaskpass b/shell/qaskpass index 6d0c7f5..2dd4443 100755 --- a/shell/qaskpass +++ b/shell/qaskpass @@ -4,11 +4,14 @@ import argparse import curses import hashlib import os +import random +import re import sys import termios +import time import tty -__version__ = "20250309.a" +__version__ = "20250310.a" class getch: @@ -49,37 +52,64 @@ def termsize(): class bc: - m = "\033[95m" - b = "\033[94m" - g = "\033[92m" - y = "\033[93m" - r = "\033[91m" - c = "\033[96m" - B = "\033[1m" + m = "\033[35m" + b = "\033[34m" + g = "\033[32m" + y = "\033[33m" + r = "\033[31m" + c = "\033[36m" + k = "\033[30m\033[40m" + M = "\033[95m" + B = "\033[94m" + G = "\033[92m" + Y = "\033[93m" + R = "\033[91m" + C = "\033[96m" + bold = "\033[1m" z = "\033[0m" def disable(self): - for x in "rgbcmyBz": + for x in "rgbcmyzkRGBCMY": setattr(self, x, "") + setattr(self, "bold", "") -def animchar(i, pos, colorpos, width, c): +def pwscore(s): + score = len(s) / 8 + simple = False + if re.search("[A-Z]", s): + score *= 2 + simple = True + if re.search("[a-z]", s): + score *= 1.5 + simple = True + if re.search("[0-9]", s): + score *= 1.5 + simple = True + if not simple: + score *= 2 + return score + + +def animchar(i, pos, colorpos, width, c, user_input): if i < 0: return " " if pos == colorpos: - clr = c.c + clr = c.C else: - if i < 10: - clr = c.r - elif i < 20: - clr = c.y - else: - clr = c.g - return clr + "▁▂▃▄▅▆▇█▇▆▅▄▃▂"[int(i / width) % 14] + clr = c.r + score = pwscore(user_input) + for limit in ((c.r, 2), (c.y, 4), (c.c, 8), (c.g, 14)): + if score > limit[1] - 1 + 2 * random.random(): + clr = limit[0] + else: + break + + return clr + "▁▂▃▄▅▆▇█▇▆▅▄▃▂"[int(random.randint(-1, 1) + (i / width)) % 14] -def pquit(s="", e=0): - print("", file=sys.stderr) +def pquit(s="", e=0, c=bc()): + print(c.z, file=sys.stderr) print(s, end="", file=sys.stdout if e == 0 else sys.stderr) sys.exit(e) @@ -91,28 +121,32 @@ if __name__ == "__main__": # 127 = backspace ch = getch() user_input = "" - display = "**** ****" + + dot = "•" + display = f"{dot*4} {dot*4}" c = bc() if opts.no_color: c.disable() if opts.title: - print(f"{c.y}{c.B}{opts.title}{c.z}", file=sys.stderr) + print(f"{c.Y}{opts.title}{c.z}", file=sys.stderr) enter_exitcode = 0 while True: try: if opts.w > 0: dot_color = c.m + dot = "•" if opts.expect_sha256: enter_exitcode = 10 if hashlib.sha256(user_input.encode("utf-8")).hexdigest() == opts.expect_sha256: - dot_color = c.g + c.B + dot_color = c.G + dot = "♥" enter_exitcode = 0 colorpos = len(user_input) % opts.w - display = dot_color + "•••• " + display = dot_color + f"{dot*4} " for i in range(opts.w): - display += animchar(len(user_input) - i, i, colorpos, opts.w, c) - display += dot_color + " ••••" + c.z - print("\r" + display, file=sys.stderr, end="") + display += animchar(len(user_input) - i, i, colorpos, opts.w, c, user_input) + display += dot_color + f" {dot*4}" + c.z + print("\r" + c.z + display + "\r" + c.k, file=sys.stderr, end="") sys.stderr.flush() key = ch.get()