absfuyu 4.1.1__py3-none-any.whl → 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of absfuyu might be problematic. Click here for more details.
- absfuyu/__init__.py +4 -4
- absfuyu/__main__.py +13 -1
- absfuyu/cli/__init__.py +4 -2
- absfuyu/cli/color.py +7 -0
- absfuyu/cli/do_group.py +9 -91
- absfuyu/cli/tool_group.py +136 -0
- absfuyu/config/__init__.py +17 -34
- absfuyu/core/__init__.py +49 -0
- absfuyu/core/baseclass.py +299 -0
- absfuyu/core/baseclass2.py +165 -0
- absfuyu/core/decorator.py +67 -0
- absfuyu/core/docstring.py +163 -0
- absfuyu/core/dummy_cli.py +67 -0
- absfuyu/core/dummy_func.py +47 -0
- absfuyu/dxt/__init__.py +42 -0
- absfuyu/dxt/dictext.py +201 -0
- absfuyu/dxt/dxt_support.py +79 -0
- absfuyu/dxt/intext.py +586 -0
- absfuyu/dxt/listext.py +508 -0
- absfuyu/dxt/strext.py +530 -0
- absfuyu/{extensions → extra}/__init__.py +3 -2
- absfuyu/extra/beautiful.py +251 -0
- absfuyu/{extensions/extra → extra}/data_analysis.py +51 -82
- absfuyu/fun/__init__.py +110 -135
- absfuyu/fun/tarot.py +9 -17
- absfuyu/game/__init__.py +6 -0
- absfuyu/game/game_stat.py +6 -0
- absfuyu/game/sudoku.py +7 -1
- absfuyu/game/tictactoe.py +12 -5
- absfuyu/game/wordle.py +14 -8
- absfuyu/general/__init__.py +6 -79
- absfuyu/general/content.py +22 -36
- absfuyu/general/generator.py +17 -42
- absfuyu/general/human.py +108 -228
- absfuyu/general/shape.py +1334 -0
- absfuyu/logger.py +8 -13
- absfuyu/pkg_data/__init__.py +137 -99
- absfuyu/pkg_data/deprecated.py +133 -0
- absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
- absfuyu/sort.py +6 -130
- absfuyu/tools/__init__.py +2 -2
- absfuyu/tools/checksum.py +44 -22
- absfuyu/tools/converter.py +82 -50
- absfuyu/tools/keygen.py +25 -30
- absfuyu/tools/obfuscator.py +246 -112
- absfuyu/tools/passwordlib.py +330 -0
- absfuyu/tools/shutdownizer.py +287 -0
- absfuyu/tools/web.py +2 -9
- absfuyu/util/__init__.py +15 -15
- absfuyu/util/api.py +10 -15
- absfuyu/util/json_method.py +7 -24
- absfuyu/util/lunar.py +3 -9
- absfuyu/util/path.py +22 -27
- absfuyu/util/performance.py +43 -67
- absfuyu/util/shorten_number.py +65 -14
- absfuyu/util/zipped.py +9 -15
- absfuyu-5.0.0.dist-info/METADATA +143 -0
- absfuyu-5.0.0.dist-info/RECORD +68 -0
- absfuyu/core.py +0 -57
- absfuyu/everything.py +0 -32
- absfuyu/extensions/beautiful.py +0 -188
- absfuyu/extensions/dev/__init__.py +0 -244
- absfuyu/extensions/dev/password_hash.py +0 -80
- absfuyu/extensions/dev/passwordlib.py +0 -258
- absfuyu/extensions/dev/project_starter.py +0 -60
- absfuyu/extensions/dev/shutdownizer.py +0 -156
- absfuyu/extensions/extra/__init__.py +0 -24
- absfuyu/fun/WGS.py +0 -134
- absfuyu/general/data_extension.py +0 -1796
- absfuyu/tools/stats.py +0 -226
- absfuyu/util/pkl.py +0 -67
- absfuyu-4.1.1.dist-info/METADATA +0 -121
- absfuyu-4.1.1.dist-info/RECORD +0 -61
- {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/WHEEL +0 -0
- {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Development
|
|
6
|
-
--------------------
|
|
7
|
-
Some stuffs that are not ready to use yet.
|
|
8
|
-
Use at your own risk, everything is subject to change
|
|
9
|
-
|
|
10
|
-
Version: 2.0.0
|
|
11
|
-
Date updated: 23/11/2023 (dd/mm/yyyy)
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
# Module level
|
|
15
|
-
###########################################################################
|
|
16
|
-
__all__ = [
|
|
17
|
-
"password_check",
|
|
18
|
-
"fib",
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# Library
|
|
23
|
-
###########################################################################
|
|
24
|
-
import base64
|
|
25
|
-
import re
|
|
26
|
-
from collections import deque
|
|
27
|
-
from functools import lru_cache
|
|
28
|
-
from typing import Dict, Final, List, NamedTuple
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# PASSWORD CHECKER
|
|
32
|
-
def password_check(password: str) -> bool:
|
|
33
|
-
"""
|
|
34
|
-
Verify the strength of 'password'.
|
|
35
|
-
Returns a dict indicating the wrong criteria.
|
|
36
|
-
A password is considered strong if:
|
|
37
|
-
- 8 characters length or more
|
|
38
|
-
- 1 digit or more
|
|
39
|
-
- 1 symbol or more
|
|
40
|
-
- 1 uppercase letter or more
|
|
41
|
-
- 1 lowercase letter or more
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
# calculating the length
|
|
45
|
-
length_error = len(password) < 8
|
|
46
|
-
|
|
47
|
-
# searching for digits
|
|
48
|
-
digit_error = re.search(r"\d", password) is None
|
|
49
|
-
|
|
50
|
-
# searching for uppercase
|
|
51
|
-
uppercase_error = re.search(r"[A-Z]", password) is None
|
|
52
|
-
|
|
53
|
-
# searching for lowercase
|
|
54
|
-
lowercase_error = re.search(r"[a-z]", password) is None
|
|
55
|
-
|
|
56
|
-
# searching for symbols
|
|
57
|
-
symbols = re.compile(r"[ !#$%&'()*+,-./[\\\]^_`{|}~" + r'"]')
|
|
58
|
-
symbol_error = symbols.search(password) is None
|
|
59
|
-
|
|
60
|
-
detail = {
|
|
61
|
-
"password_ok": not any(
|
|
62
|
-
[ # overall result
|
|
63
|
-
length_error,
|
|
64
|
-
digit_error,
|
|
65
|
-
uppercase_error,
|
|
66
|
-
lowercase_error,
|
|
67
|
-
symbol_error,
|
|
68
|
-
]
|
|
69
|
-
),
|
|
70
|
-
"length_error": length_error,
|
|
71
|
-
"digit_error": digit_error,
|
|
72
|
-
"uppercase_error": uppercase_error,
|
|
73
|
-
"lowercase_error": lowercase_error,
|
|
74
|
-
"symbol_error": symbol_error,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return detail["password_ok"]
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# FIBONACCI WITH CACHE
|
|
81
|
-
@lru_cache(maxsize=5)
|
|
82
|
-
def fib(n: int) -> int:
|
|
83
|
-
"""Fibonacci (recursive)"""
|
|
84
|
-
# max recursion is 484
|
|
85
|
-
if n < 2:
|
|
86
|
-
return n
|
|
87
|
-
return fib(n - 1) + fib(n - 2)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
# https://stackoverflow.com/questions/563022/whats-python-good-practice-for-importing-and-offering-optional-features
|
|
91
|
-
def optional_import(module: str, name: str = None, package: str = None):
|
|
92
|
-
import importlib
|
|
93
|
-
|
|
94
|
-
try:
|
|
95
|
-
module = importlib.import_module(module)
|
|
96
|
-
return module if name is None else getattr(module, name)
|
|
97
|
-
except ImportError as e:
|
|
98
|
-
if package is None:
|
|
99
|
-
package = module
|
|
100
|
-
msg = f"install the '{package}' package to make use of this feature"
|
|
101
|
-
import_error = e
|
|
102
|
-
|
|
103
|
-
def _failed_import(*args):
|
|
104
|
-
raise ValueError(msg) from import_error
|
|
105
|
-
|
|
106
|
-
return _failed_import
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def load_toml_file(toml_file: str):
|
|
110
|
-
"""
|
|
111
|
-
Load ``.toml`` file
|
|
112
|
-
|
|
113
|
-
:param toml_file: Path to ``.toml`` file
|
|
114
|
-
"""
|
|
115
|
-
from sys import version_info as _python_version
|
|
116
|
-
|
|
117
|
-
if _python_version.minor < 11:
|
|
118
|
-
try:
|
|
119
|
-
import tomli as tomllib # type: ignore
|
|
120
|
-
except ImportError:
|
|
121
|
-
raise ImportError("Please install tomli python package")
|
|
122
|
-
except:
|
|
123
|
-
raise SystemExit
|
|
124
|
-
else:
|
|
125
|
-
import tomllib
|
|
126
|
-
|
|
127
|
-
with open(toml_file, "rb") as file:
|
|
128
|
-
toml_data = tomllib.load(file)
|
|
129
|
-
return toml_data
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def get_sitemap(url: str):
|
|
133
|
-
import re
|
|
134
|
-
|
|
135
|
-
import requests
|
|
136
|
-
|
|
137
|
-
class Url(NamedTuple):
|
|
138
|
-
base: str
|
|
139
|
-
extra: str
|
|
140
|
-
|
|
141
|
-
def __str__(self) -> str:
|
|
142
|
-
return f"{self.base}{self.extra}"
|
|
143
|
-
|
|
144
|
-
def __repr__(self) -> str:
|
|
145
|
-
return f"{self.__class__.__name__}({self.base}{self.extra})"
|
|
146
|
-
|
|
147
|
-
# robots.txt
|
|
148
|
-
# sitemap.xml
|
|
149
|
-
if not url.endswith("/"):
|
|
150
|
-
url += "/"
|
|
151
|
-
pattern = re.compile(
|
|
152
|
-
r"([(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)([-a-zA-Z0-9@:%_\+.~#?&//=]*)",
|
|
153
|
-
re.IGNORECASE,
|
|
154
|
-
)
|
|
155
|
-
try:
|
|
156
|
-
url += "sitemap.xml"
|
|
157
|
-
res = requests.get(url).text
|
|
158
|
-
except:
|
|
159
|
-
# W.I.P
|
|
160
|
-
url += "robots.txt"
|
|
161
|
-
res = requests.get(url).text
|
|
162
|
-
regex = re.findall(pattern, res)
|
|
163
|
-
return list(map(Url._make, regex))
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
from absfuyu.general import ClassBase
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
class SimpleStrEncrypt(ClassBase):
|
|
170
|
-
"""
|
|
171
|
-
Simple Encryption
|
|
172
|
-
|
|
173
|
-
Logic:
|
|
174
|
-
- Base64
|
|
175
|
-
- Shift characters
|
|
176
|
-
"""
|
|
177
|
-
|
|
178
|
-
def __init__(self, times_to_base64_encode: int = 10, shift: int = 13) -> None:
|
|
179
|
-
"""
|
|
180
|
-
:param times_to_base64_encode: How many time to base64 encode
|
|
181
|
-
:type times_to_base64_encode: int
|
|
182
|
-
:param shift: Shift characters to the right for how many position
|
|
183
|
-
:type shift: int
|
|
184
|
-
"""
|
|
185
|
-
self.times_to_base64_encode = times_to_base64_encode
|
|
186
|
-
self.shift = shift
|
|
187
|
-
|
|
188
|
-
# Support
|
|
189
|
-
def _convert_table(self, text: str, shift: int) -> Dict[str, str]:
|
|
190
|
-
data = text
|
|
191
|
-
|
|
192
|
-
data = deque(sorted(list(set(data))))
|
|
193
|
-
translate = data.copy()
|
|
194
|
-
translate.rotate(shift)
|
|
195
|
-
convert_table = dict(zip(data, translate))
|
|
196
|
-
|
|
197
|
-
return convert_table
|
|
198
|
-
|
|
199
|
-
@staticmethod
|
|
200
|
-
def _use_convert_table(text: str, convert_table: Dict[str, str]) -> str:
|
|
201
|
-
"""Use convert table"""
|
|
202
|
-
data = list(text)
|
|
203
|
-
for i, x in enumerate(data):
|
|
204
|
-
data[i] = convert_table[x]
|
|
205
|
-
return "".join(data)
|
|
206
|
-
|
|
207
|
-
@staticmethod
|
|
208
|
-
def _b64encode(text: str) -> str:
|
|
209
|
-
return base64.b64encode(text.encode()).decode()
|
|
210
|
-
|
|
211
|
-
@staticmethod
|
|
212
|
-
def _b64decode(text: str) -> str:
|
|
213
|
-
return base64.b64decode(text).decode()
|
|
214
|
-
|
|
215
|
-
# Main
|
|
216
|
-
def encode(self, text: str) -> str:
|
|
217
|
-
# Base64
|
|
218
|
-
data = text
|
|
219
|
-
for _ in range(self.times_to_base64_encode):
|
|
220
|
-
data = self._b64encode(data)
|
|
221
|
-
|
|
222
|
-
# Shift
|
|
223
|
-
convert_table = self._convert_table(data, self.shift)
|
|
224
|
-
return self._use_convert_table(data, convert_table)
|
|
225
|
-
|
|
226
|
-
def decode(self, text: str) -> str:
|
|
227
|
-
# Shift back
|
|
228
|
-
data = text
|
|
229
|
-
convert_table = self._convert_table(data, -self.shift)
|
|
230
|
-
data = self._use_convert_table(data, convert_table)
|
|
231
|
-
|
|
232
|
-
# Base64
|
|
233
|
-
for _ in range(self.times_to_base64_encode):
|
|
234
|
-
data = self._b64decode(data)
|
|
235
|
-
|
|
236
|
-
return data
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# testing
|
|
240
|
-
CON_VAR: Final[List[str]] = ["a", "b"] # Declare as final
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if __name__ == "__main__":
|
|
244
|
-
print(get_sitemap("https://kingdomality.com/"))
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
# Library
|
|
5
|
-
##############################################################
|
|
6
|
-
import hashlib as __hash
|
|
7
|
-
import os as __os
|
|
8
|
-
from typing import Dict as __Dict
|
|
9
|
-
from typing import NewType as __NewType
|
|
10
|
-
from typing import TypeVar as __TypeVar
|
|
11
|
-
from typing import Union as __Union
|
|
12
|
-
|
|
13
|
-
# Define type
|
|
14
|
-
##############################################################
|
|
15
|
-
Password = __NewType("Password", str)
|
|
16
|
-
Salt = __NewType("Salt", str)
|
|
17
|
-
Key = __NewType("Key", str)
|
|
18
|
-
Salt_V = __NewType("Salt_V", bytes)
|
|
19
|
-
Key_V = __NewType("Key_V", bytes)
|
|
20
|
-
Combo = __Dict[__Union[Salt, Key], __Union[Salt_V, Key_V]]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Function
|
|
24
|
-
##############################################################
|
|
25
|
-
def password_hash(password: Password) -> Combo:
|
|
26
|
-
"""
|
|
27
|
-
Generate hash for password
|
|
28
|
-
"""
|
|
29
|
-
salt = __os.urandom(32)
|
|
30
|
-
key = __hash.pbkdf2_hmac(
|
|
31
|
-
hash_name="sha256",
|
|
32
|
-
password=password.encode("utf-8"),
|
|
33
|
-
salt=salt,
|
|
34
|
-
iterations=100000,
|
|
35
|
-
)
|
|
36
|
-
out = {
|
|
37
|
-
"salt": salt,
|
|
38
|
-
"key": key,
|
|
39
|
-
}
|
|
40
|
-
return out
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def password_hash_check(
|
|
44
|
-
password: Password,
|
|
45
|
-
combo: Combo,
|
|
46
|
-
) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
Compare hashes between 2 passwords
|
|
49
|
-
"""
|
|
50
|
-
if "salt" in combo and "key" in combo:
|
|
51
|
-
salt = combo["salt"]
|
|
52
|
-
compare_key = combo["key"]
|
|
53
|
-
else:
|
|
54
|
-
return None
|
|
55
|
-
|
|
56
|
-
key = __hash.pbkdf2_hmac(
|
|
57
|
-
hash_name="sha256",
|
|
58
|
-
password=password.encode("utf-8"),
|
|
59
|
-
salt=salt,
|
|
60
|
-
iterations=100000,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
if key == compare_key:
|
|
64
|
-
return True
|
|
65
|
-
else:
|
|
66
|
-
return False
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def tj():
|
|
70
|
-
import json
|
|
71
|
-
|
|
72
|
-
combo = password_hash("lmao")
|
|
73
|
-
for k, v in combo.items():
|
|
74
|
-
combo[k] = str(v)
|
|
75
|
-
j = json.dumps(combo, indent=4)
|
|
76
|
-
return j
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if __name__ == "__main__":
|
|
80
|
-
print(tj())
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Passwordlib
|
|
6
|
-
--------------------
|
|
7
|
-
Password library
|
|
8
|
-
|
|
9
|
-
Version: 1.0.0dev1
|
|
10
|
-
Date updated: 30/11/2023 (dd/mm/yyyy)
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
# Library
|
|
14
|
-
###########################################################################
|
|
15
|
-
# from collections import namedtuple
|
|
16
|
-
import hashlib
|
|
17
|
-
import os
|
|
18
|
-
import random
|
|
19
|
-
import re
|
|
20
|
-
from typing import List, Optional
|
|
21
|
-
|
|
22
|
-
from absfuyu_res import DATA
|
|
23
|
-
|
|
24
|
-
from absfuyu.general.data_extension import DictExt, Text
|
|
25
|
-
from absfuyu.general.generator import Charset, Generator
|
|
26
|
-
from absfuyu.logger import logger
|
|
27
|
-
from absfuyu.util import set_min
|
|
28
|
-
from absfuyu.util.pkl import Pickler
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# Function
|
|
32
|
-
###########################################################################
|
|
33
|
-
def password_check(password: str) -> bool:
|
|
34
|
-
"""
|
|
35
|
-
Verify the strength of ``password``.
|
|
36
|
-
A password is considered strong if:
|
|
37
|
-
|
|
38
|
-
- 8 characters length or more
|
|
39
|
-
- 1 digit or more
|
|
40
|
-
- 1 symbol or more
|
|
41
|
-
- 1 uppercase letter or more
|
|
42
|
-
- 1 lowercase letter or more
|
|
43
|
-
|
|
44
|
-
:param password: Password want to be checked
|
|
45
|
-
:type password: str
|
|
46
|
-
:rtype: bool
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
# calculating the length
|
|
50
|
-
length_error = len(password) < 8
|
|
51
|
-
|
|
52
|
-
# searching for digits
|
|
53
|
-
digit_error = re.search(r"\d", password) is None
|
|
54
|
-
|
|
55
|
-
# searching for uppercase
|
|
56
|
-
uppercase_error = re.search(r"[A-Z]", password) is None
|
|
57
|
-
|
|
58
|
-
# searching for lowercase
|
|
59
|
-
lowercase_error = re.search(r"[a-z]", password) is None
|
|
60
|
-
|
|
61
|
-
# searching for symbols
|
|
62
|
-
symbols = re.compile(r"[ !#$%&'()*+,-./[\\\]^_`{|}~" + r'"]')
|
|
63
|
-
symbol_error = symbols.search(password) is None
|
|
64
|
-
|
|
65
|
-
detail = {
|
|
66
|
-
"length_error": length_error,
|
|
67
|
-
"digit_error": digit_error,
|
|
68
|
-
"uppercase_error": uppercase_error,
|
|
69
|
-
"lowercase_error": lowercase_error,
|
|
70
|
-
"symbol_error": symbol_error,
|
|
71
|
-
}
|
|
72
|
-
logger.debug(f"Password error summary: {detail}")
|
|
73
|
-
|
|
74
|
-
return not any(
|
|
75
|
-
[
|
|
76
|
-
length_error,
|
|
77
|
-
digit_error,
|
|
78
|
-
uppercase_error,
|
|
79
|
-
lowercase_error,
|
|
80
|
-
symbol_error,
|
|
81
|
-
]
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# Class
|
|
86
|
-
###########################################################################
|
|
87
|
-
class Password:
|
|
88
|
-
"""Password"""
|
|
89
|
-
|
|
90
|
-
def __init__(self) -> None:
|
|
91
|
-
"""doc_string"""
|
|
92
|
-
self.password: str = None
|
|
93
|
-
self._words: List[str] = Pickler.load(DATA.PASSWORDLIB)
|
|
94
|
-
|
|
95
|
-
def __str__(self) -> str:
|
|
96
|
-
return f"{self.__class__.__name__}()"
|
|
97
|
-
|
|
98
|
-
def __repr__(self) -> str:
|
|
99
|
-
return self.__str__()
|
|
100
|
-
|
|
101
|
-
def password_hash(self):
|
|
102
|
-
"""
|
|
103
|
-
Generate hash for password
|
|
104
|
-
"""
|
|
105
|
-
salt = os.urandom(32)
|
|
106
|
-
key = hashlib.pbkdf2_hmac(
|
|
107
|
-
hash_name="sha256",
|
|
108
|
-
password=self.password.encode("utf-8"),
|
|
109
|
-
salt=salt,
|
|
110
|
-
iterations=100000,
|
|
111
|
-
)
|
|
112
|
-
out = {
|
|
113
|
-
"salt": salt,
|
|
114
|
-
"key": key,
|
|
115
|
-
}
|
|
116
|
-
return out
|
|
117
|
-
|
|
118
|
-
@staticmethod
|
|
119
|
-
def password_check(password: str):
|
|
120
|
-
data = Text(password).analyze()
|
|
121
|
-
data.__setitem__("length", len(password))
|
|
122
|
-
data = DictExt(data).apply(lambda x: True if x > 0 else False)
|
|
123
|
-
return data
|
|
124
|
-
|
|
125
|
-
@property
|
|
126
|
-
def words(self) -> List[str]:
|
|
127
|
-
"""
|
|
128
|
-
Word list to generate passphrase
|
|
129
|
-
|
|
130
|
-
:rtype: list[str]
|
|
131
|
-
"""
|
|
132
|
-
return self._words
|
|
133
|
-
|
|
134
|
-
# Password generator
|
|
135
|
-
@staticmethod
|
|
136
|
-
def generate_password(
|
|
137
|
-
length: int = 8,
|
|
138
|
-
include_uppercase: bool = True,
|
|
139
|
-
include_number: bool = True,
|
|
140
|
-
include_special: bool = True,
|
|
141
|
-
) -> str:
|
|
142
|
-
r"""
|
|
143
|
-
Generate a random password
|
|
144
|
-
|
|
145
|
-
Parameters
|
|
146
|
-
----------
|
|
147
|
-
length : int
|
|
148
|
-
| Length of the password.
|
|
149
|
-
| Minimum value: ``8``
|
|
150
|
-
| (Default: ``8``)
|
|
151
|
-
|
|
152
|
-
include_uppercase : bool
|
|
153
|
-
Include uppercase character in the password (Default: ``True``)
|
|
154
|
-
|
|
155
|
-
include_number : bool
|
|
156
|
-
Include digit character in the password (Default: ``True``)
|
|
157
|
-
|
|
158
|
-
include_special : bool
|
|
159
|
-
Include special character in the password (Default: ``True``)
|
|
160
|
-
|
|
161
|
-
Returns
|
|
162
|
-
-------
|
|
163
|
-
str
|
|
164
|
-
Generated password
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Example:
|
|
168
|
-
--------
|
|
169
|
-
>>> Password.generate_password()
|
|
170
|
-
[T&b@mq2
|
|
171
|
-
"""
|
|
172
|
-
charset = Charset.LOWERCASE
|
|
173
|
-
check = 0
|
|
174
|
-
|
|
175
|
-
if include_uppercase:
|
|
176
|
-
charset += Charset.UPPERCASE
|
|
177
|
-
check += 1
|
|
178
|
-
|
|
179
|
-
if include_number:
|
|
180
|
-
charset += Charset.DIGIT
|
|
181
|
-
check += 1
|
|
182
|
-
|
|
183
|
-
if include_special:
|
|
184
|
-
charset += r"[ !#$%&'()*+,-./[\\\]^_`{|}~" + r'"]'
|
|
185
|
-
check += 1
|
|
186
|
-
|
|
187
|
-
while True:
|
|
188
|
-
pwd = Generator.generate_string(
|
|
189
|
-
charset=charset,
|
|
190
|
-
size=set_min(length, min_value=8),
|
|
191
|
-
times=1,
|
|
192
|
-
string_type_if_1=True,
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
analyze = Text(pwd).analyze() # Count each type of char
|
|
196
|
-
|
|
197
|
-
s = sum([1 for x in analyze.values() if x > 0])
|
|
198
|
-
if s > check: # Break loop if each type of char has atleast 1
|
|
199
|
-
break
|
|
200
|
-
return pwd
|
|
201
|
-
|
|
202
|
-
def generate_passphrase(
|
|
203
|
-
self,
|
|
204
|
-
num_of_blocks: int = 5,
|
|
205
|
-
block_divider: Optional[str] = None,
|
|
206
|
-
first_letter_cap: bool = True,
|
|
207
|
-
include_number: bool = True,
|
|
208
|
-
) -> str:
|
|
209
|
-
"""
|
|
210
|
-
Generate a random passphrase
|
|
211
|
-
|
|
212
|
-
Parameters
|
|
213
|
-
----------
|
|
214
|
-
num_of_blocks : int
|
|
215
|
-
Number of word used (Default: ``5``)
|
|
216
|
-
|
|
217
|
-
block_divider : str
|
|
218
|
-
Character symbol that between each word (Default: ``"-"``)
|
|
219
|
-
|
|
220
|
-
first_letter_cap : bool
|
|
221
|
-
Capitalize first character of each word (Default: ``True``)
|
|
222
|
-
|
|
223
|
-
include_number : bool
|
|
224
|
-
Add number to the end of each word (Default: ``True``)
|
|
225
|
-
|
|
226
|
-
Returns
|
|
227
|
-
-------
|
|
228
|
-
str
|
|
229
|
-
Generated passphrase
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Example:
|
|
233
|
-
--------
|
|
234
|
-
>>> print(Password().generate_passphrase())
|
|
235
|
-
Myomectomies7-Sully4-Torpedomen7-Netful2-Begaud8
|
|
236
|
-
"""
|
|
237
|
-
|
|
238
|
-
def convert_func(value: str):
|
|
239
|
-
if first_letter_cap:
|
|
240
|
-
value = value.title()
|
|
241
|
-
if include_number:
|
|
242
|
-
value += str(random.choice(range(10)))
|
|
243
|
-
return value
|
|
244
|
-
|
|
245
|
-
if not block_divider:
|
|
246
|
-
block_divider = "-"
|
|
247
|
-
|
|
248
|
-
return block_divider.join(
|
|
249
|
-
[convert_func(random.choice(self.words)) for _ in range(num_of_blocks)]
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
# Run
|
|
254
|
-
###########################################################################
|
|
255
|
-
if __name__ == "__main__":
|
|
256
|
-
logger.setLevel(10)
|
|
257
|
-
# print(os.urandom(32))
|
|
258
|
-
print(Password.password_check(Password.generate_password()))
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Project starter
|
|
6
|
-
------------------------
|
|
7
|
-
|
|
8
|
-
Version: 1.0.0dev1
|
|
9
|
-
Date updated: 01/12/2023 (dd/mm/yyyy)
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
# Module level
|
|
13
|
-
###########################################################################
|
|
14
|
-
__all__ = ["get_parser"]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# Library
|
|
18
|
-
###########################################################################
|
|
19
|
-
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
|
|
20
|
-
from typing import Optional
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Function
|
|
24
|
-
###########################################################################
|
|
25
|
-
def get_parser(
|
|
26
|
-
name: Optional[str] = None,
|
|
27
|
-
description: Optional[str] = None,
|
|
28
|
-
epilog: Optional[str] = None,
|
|
29
|
-
*,
|
|
30
|
-
version: str = "",
|
|
31
|
-
add_help: bool = True,
|
|
32
|
-
) -> ArgumentParser:
|
|
33
|
-
arg_parser = ArgumentParser(
|
|
34
|
-
prog=name,
|
|
35
|
-
description=description,
|
|
36
|
-
epilog=epilog,
|
|
37
|
-
add_help=add_help,
|
|
38
|
-
formatter_class=ArgumentDefaultsHelpFormatter,
|
|
39
|
-
# allow_abbrev=False, # Disable long options recognize
|
|
40
|
-
# exit_on_error=True
|
|
41
|
-
)
|
|
42
|
-
arg_parser.add_argument(
|
|
43
|
-
"--version", action="version", version=f"%(prog)s {version}"
|
|
44
|
-
)
|
|
45
|
-
_ll_val = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
46
|
-
arg_parser.add_argument(
|
|
47
|
-
"--log-level",
|
|
48
|
-
metavar="LOG_LEVEL",
|
|
49
|
-
dest="log_level",
|
|
50
|
-
choices=_ll_val,
|
|
51
|
-
default="INFO",
|
|
52
|
-
help=f"Log level: {_ll_val}",
|
|
53
|
-
)
|
|
54
|
-
return arg_parser
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# Run
|
|
58
|
-
###########################################################################
|
|
59
|
-
if __name__ == "__main__":
|
|
60
|
-
pass
|