tools.utils
2025-05-17
Parent:c4bc2d77d4be
tools.utils/pw/aw_pw_tool
+ shell утилиты
| awgur@4 | 1 #!/usr/bin/env python3 |
| awgur@4 | 2 # devel.a0fs.ru -- TOOLS:SEC:aw_pw_tool -- v0.r202505.1 |
| awgur@4 | 3 # devel.a0fs.ru -- TOOLS:SEC:safe_pw -- v0.r202409.2 |
| awgur@4 | 4 # devel.a0fs.ru -- pwtrns.py -- v0.r202402.8 |
| awgur@4 | 5 |
| awgur@4 | 6 from sys import stdin, stdout, stderr |
| awgur@4 | 7 from random import seed as rnd_seed, choice as rnd_choice |
| awgur@4 | 8 from argparse import ArgumentParser |
| awgur@4 | 9 from string import ascii_letters, digits |
| awgur@4 | 10 from typing import List, Iterable, Optional |
| awgur@4 | 11 |
| awgur@4 | 12 |
| awgur@4 | 13 ### VAR |
| awgur@4 | 14 SAFECH= { |
| awgur@4 | 15 'def': '%-=_;:+/,.@', |
| awgur@4 | 16 'url': '-._', |
| awgur@4 | 17 } |
| awgur@4 | 18 |
| awgur@4 | 19 TRDICT = { |
| awgur@4 | 20 'f': 'а', ',': 'б', 'd': 'в', 'u': 'г', 'l': 'д', 't': 'е', '`': 'ё', |
| awgur@4 | 21 ';': 'ж', 'p': 'з', 'b': 'и', 'q': 'й', 'r': 'к', 'k': 'л', 'v': 'м', |
| awgur@4 | 22 'y': 'н', 'j': 'о', 'g': 'п', 'h': 'р', 'c': 'с', 'n': 'т', 'e': 'у', |
| awgur@4 | 23 'a': 'ф', '[': 'х', 'w': 'ц', 'x': 'ч', 'i': 'ш', 'o': 'щ', 'm': 'ь', |
| awgur@4 | 24 's': 'ы', ']': 'ъ', "'": 'э', '.': 'ю', 'z': 'я', 'F': 'А', '<': 'Б', |
| awgur@4 | 25 'D': 'В', 'U': 'Г', 'L': 'Д', 'T': 'Е', '~': 'Ё', ':': 'Ж', 'P': 'З', |
| awgur@4 | 26 'B': 'И', 'Q': 'Й', 'R': 'К', 'K': 'Л', 'V': 'М', 'Y': 'Н', 'J': 'О', |
| awgur@4 | 27 'G': 'П', 'H': 'Р', 'C': 'С', 'N': 'Т', 'E': 'У', 'A': 'Ф', '{': 'Х', |
| awgur@4 | 28 'W': 'Ц', 'X': 'Ч', 'I': 'Ш', 'O': 'Щ', 'M': 'Ь', 'S': 'Ы', '}': 'Ъ', |
| awgur@4 | 29 '"': 'Э', '>': 'Ю', 'Z': 'Я', |
| awgur@4 | 30 } |
| awgur@4 | 31 |
| awgur@4 | 32 GOODPWCH=ascii_letters + digits + ' ' |
| awgur@4 | 33 |
| awgur@4 | 34 |
| awgur@4 | 35 ### FUNC |
| awgur@4 | 36 def err(msg: str): |
| awgur@4 | 37 for l in msg.splitlines(): |
| awgur@4 | 38 stderr.write(f'ERR: {l}\n') |
| awgur@4 | 39 |
| awgur@4 | 40 |
| awgur@4 | 41 def out(s: str): |
| awgur@4 | 42 stdout.write(f'{s}\n') |
| awgur@4 | 43 |
| awgur@4 | 44 |
| awgur@4 | 45 def panic(code, msg): |
| awgur@4 | 46 err(msg) |
| awgur@4 | 47 exit(code) |
| awgur@4 | 48 |
| awgur@4 | 49 |
| awgur@4 | 50 def ptr_reverse(d: dict) -> dict: |
| awgur@4 | 51 return dict([(v, k) for k, v in d.items()]) |
| awgur@4 | 52 |
| awgur@4 | 53 |
| awgur@4 | 54 def get_args(words: Optional[List[str]]) -> Iterable[str]: |
| awgur@4 | 55 if words and isinstance(words, (tuple, list)): |
| awgur@4 | 56 for i in words: |
| awgur@4 | 57 yield i.strip() |
| awgur@4 | 58 |
| awgur@4 | 59 else: |
| awgur@4 | 60 for i in stdin: |
| awgur@4 | 61 yield i.strip() |
| awgur@4 | 62 |
| awgur@4 | 63 def out_res(flag: bool, word: str, tr_word: str): |
| awgur@4 | 64 if flag: |
| awgur@4 | 65 out(f'"{word}" -> "{tr_word}"') |
| awgur@4 | 66 |
| awgur@4 | 67 else: |
| awgur@4 | 68 out(f'{tr_word}') |
| awgur@4 | 69 |
| awgur@4 | 70 |
| awgur@4 | 71 # ARGS |
| awgur@4 | 72 ap = ArgumentParser( |
| awgur@4 | 73 prog='aw_pw_tool', |
| awgur@4 | 74 description='Инструмент для работы с паролями, их преобразованием и трансляцией' |
| awgur@4 | 75 ) |
| awgur@4 | 76 |
| awgur@4 | 77 ap.add_argument('-u', '--url', action='store_true', default=False, |
| awgur@4 | 78 help='Режим фильтрации пароля от опасных для url символов' |
| awgur@4 | 79 ) |
| awgur@4 | 80 |
| awgur@4 | 81 ap.add_argument('-S', '--show-passwd', action='store_true', default=False, |
| awgur@4 | 82 help='Показывать пароли до преобразования' |
| awgur@4 | 83 ) |
| awgur@4 | 84 |
| awgur@4 | 85 ap.add_argument('-t', '--pwtrans', action='store_true', default=False, |
| awgur@4 | 86 help='Режим трансляции паролей из английской в русскую раскладку') |
| awgur@4 | 87 |
| awgur@4 | 88 ap.add_argument('-r', '--reverse', action='store_true', default=False, |
| awgur@4 | 89 help='Для трансляции паролей: переводим из русской в английскую раскладку') |
| awgur@4 | 90 |
| awgur@4 | 91 |
| awgur@4 | 92 ap.add_argument('word', nargs='*', help='Слово для перевода') |
| awgur@4 | 93 |
| awgur@4 | 94 |
| awgur@4 | 95 ### DO |
| awgur@4 | 96 try: |
| awgur@4 | 97 args = ap.parse_args() |
| awgur@4 | 98 |
| awgur@4 | 99 if args.pwtrans: |
| awgur@4 | 100 if args.reverse: |
| awgur@4 | 101 d = ptr_reverse(TRDICT) |
| awgur@4 | 102 |
| awgur@4 | 103 else: |
| awgur@4 | 104 d = TRDICT |
| awgur@4 | 105 |
| awgur@4 | 106 for w in get_args(args.word): |
| awgur@4 | 107 out_res( |
| awgur@4 | 108 args.show_passwd, |
| awgur@4 | 109 w, |
| awgur@4 | 110 ''.join(map(lambda x: d[x] if x in d else x, w)) |
| awgur@4 | 111 ) |
| awgur@4 | 112 |
| awgur@4 | 113 else: |
| awgur@4 | 114 # Init random generator |
| awgur@4 | 115 rnd_seed() |
| awgur@4 | 116 |
| awgur@4 | 117 if args.url: |
| awgur@4 | 118 cur_safe_ch = SAFECH['url'] |
| awgur@4 | 119 |
| awgur@4 | 120 else: |
| awgur@4 | 121 cur_safe_ch = SAFECH['def'] |
| awgur@4 | 122 |
| awgur@4 | 123 GOODPWCH += cur_safe_ch |
| awgur@4 | 124 |
| awgur@4 | 125 for w in get_args(args.word): |
| awgur@4 | 126 if len(w) == 0: |
| awgur@4 | 127 break |
| awgur@4 | 128 |
| awgur@4 | 129 buf = '' |
| awgur@4 | 130 for c in w: |
| awgur@4 | 131 if c not in GOODPWCH: |
| awgur@4 | 132 c = rnd_choice(cur_safe_ch) |
| awgur@4 | 133 |
| awgur@4 | 134 buf += c |
| awgur@4 | 135 |
| awgur@4 | 136 out_res( |
| awgur@4 | 137 args.show_passwd, |
| awgur@4 | 138 w, |
| awgur@4 | 139 buf |
| awgur@4 | 140 ) |
| awgur@4 | 141 |
| awgur@4 | 142 except Exception as e: |
| awgur@4 | 143 err(f'{type(e).__name__}: {e}') |
| awgur@4 | 144 |
| awgur@4 | 145 except KeyboardInterrupt: |
| awgur@4 | 146 exit() |