tde 1.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.
- tde/__init__.py +1 -0
- tde/cli.py +293 -0
- tde-1.0.0.dist-info/METADATA +345 -0
- tde-1.0.0.dist-info/RECORD +8 -0
- tde-1.0.0.dist-info/WHEEL +5 -0
- tde-1.0.0.dist-info/entry_points.txt +2 -0
- tde-1.0.0.dist-info/licenses/LICENSE +21 -0
- tde-1.0.0.dist-info/top_level.txt +1 -0
tde/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|
tde/cli.py
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import base64
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from tde import __version__
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _supports_colour() -> bool:
|
|
12
|
+
if os.getenv("NO_COLOR"):
|
|
13
|
+
return False
|
|
14
|
+
if os.getenv("TERM") == "dumb":
|
|
15
|
+
return False
|
|
16
|
+
return hasattr(sys.stdout, "isatty") and sys.stdout.isatty()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
_COLOUR = _supports_colour()
|
|
20
|
+
|
|
21
|
+
def _c(code: str, text: str) -> str:
|
|
22
|
+
return f"\033[{code}m{text}\033[0m" if _COLOUR else text
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _bold(t: str) -> str: return _c("1", t)
|
|
26
|
+
def _cyan(t: str) -> str: return _c("36", t)
|
|
27
|
+
def _green(t: str) -> str: return _c("32", t)
|
|
28
|
+
def _yellow(t: str) -> str: return _c("33", t)
|
|
29
|
+
def _red(t: str) -> str: return _c("31", t)
|
|
30
|
+
def _dim(t: str) -> str: return _c("2", t)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
BANNER = rf"""
|
|
36
|
+
{_cyan("+========================================+")}
|
|
37
|
+
{_cyan("|")} {_bold("TDE")} -- {_green("The Data Encoder / Decoder")} {_cyan("|")}
|
|
38
|
+
{_cyan("|")} {_dim(f"v{__version__} | Zero-dependency Base64")} {_cyan("|")}
|
|
39
|
+
{_cyan("+========================================+")}
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
EPILOG = f"""
|
|
43
|
+
{_bold("Examples:")}
|
|
44
|
+
|
|
45
|
+
{_green("Encode a string:")}
|
|
46
|
+
tde encode "hello world"
|
|
47
|
+
|
|
48
|
+
{_green("Decode a string:")}
|
|
49
|
+
tde decode "aGVsbG8gd29ybGQ="
|
|
50
|
+
|
|
51
|
+
{_green("URL-safe encode:")}
|
|
52
|
+
tde encode "https://example.com/api?q=1" --url
|
|
53
|
+
|
|
54
|
+
{_green("Strict decode (halt on bad chars):")}
|
|
55
|
+
tde decode "aGVsbG8gd2!9ybGQ=" --strict
|
|
56
|
+
|
|
57
|
+
{_green("Ignore garbage (strip junk, then decode):")}
|
|
58
|
+
tde decode "aGVsbG8 gd 29ybGQ=" --ignore-garbage
|
|
59
|
+
|
|
60
|
+
{_green("File I/O -- read from file, write result to file:")}
|
|
61
|
+
tde decode -i payload.txt -o output.bin
|
|
62
|
+
|
|
63
|
+
{_green("Pipe from another command:")}
|
|
64
|
+
echo hello | tde encode
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class _Formatter(argparse.RawDescriptionHelpFormatter):
|
|
69
|
+
|
|
70
|
+
def __init__(self, prog: str, **kwargs):
|
|
71
|
+
kwargs.setdefault("max_help_position", 30)
|
|
72
|
+
kwargs.setdefault("width", 80)
|
|
73
|
+
super().__init__(prog, **kwargs)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _acquire_input(args) -> bytes:
|
|
79
|
+
|
|
80
|
+
if args.input:
|
|
81
|
+
path = os.path.expanduser(args.input)
|
|
82
|
+
if not os.path.isfile(path):
|
|
83
|
+
_die(f"Input file not found: {path}")
|
|
84
|
+
try:
|
|
85
|
+
with open(path, "rb") as fh:
|
|
86
|
+
return fh.read()
|
|
87
|
+
except OSError as exc:
|
|
88
|
+
_die(f"Cannot read file '{path}': {exc}")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if not sys.stdin.isatty():
|
|
92
|
+
data = sys.stdin.buffer.read()
|
|
93
|
+
if data:
|
|
94
|
+
return data
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
if args.data:
|
|
98
|
+
return args.data.encode("utf-8")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
_die("No input provided. Supply a string, use -i <file>, or pipe data via stdin.")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _encode(payload: bytes, *, url_safe: bool) -> bytes:
|
|
107
|
+
if url_safe:
|
|
108
|
+
encoded = base64.urlsafe_b64encode(payload)
|
|
109
|
+
return encoded.rstrip(b"=")
|
|
110
|
+
return base64.b64encode(payload)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _decode(payload: bytes, *, url_safe: bool, strict: bool,
|
|
114
|
+
ignore_garbage: bool) -> bytes:
|
|
115
|
+
text = payload.decode("ascii", errors="ignore")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
if strict:
|
|
119
|
+
if url_safe:
|
|
120
|
+
bad = re.findall(r"[^A-Za-z0-9\-_=\s]", text)
|
|
121
|
+
else:
|
|
122
|
+
bad = re.findall(r"[^A-Za-z0-9+/=\s]", text)
|
|
123
|
+
if bad:
|
|
124
|
+
unique = sorted(set(bad))
|
|
125
|
+
_die(
|
|
126
|
+
f"Strict mode: invalid Base64 character(s) found: "
|
|
127
|
+
f"{', '.join(repr(c) for c in unique)}\n"
|
|
128
|
+
f" Hint: use --ignore-garbage to strip them automatically."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if ignore_garbage:
|
|
133
|
+
if url_safe:
|
|
134
|
+
text = re.sub(r"[^A-Za-z0-9\-_=]", "", text)
|
|
135
|
+
else:
|
|
136
|
+
text = re.sub(r"[^A-Za-z0-9+/=]", "", text)
|
|
137
|
+
else:
|
|
138
|
+
|
|
139
|
+
text = text.strip()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if url_safe:
|
|
143
|
+
pad = 4 - len(text) % 4
|
|
144
|
+
if pad != 4:
|
|
145
|
+
text += "=" * pad
|
|
146
|
+
try:
|
|
147
|
+
return base64.urlsafe_b64decode(text)
|
|
148
|
+
except Exception as exc:
|
|
149
|
+
_die(f"Decoding failed: {exc}")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
try:
|
|
153
|
+
return base64.b64decode(text)
|
|
154
|
+
except Exception as exc:
|
|
155
|
+
_die(f"Decoding failed: {exc}")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _emit(result: bytes, args) -> None:
|
|
161
|
+
if args.output:
|
|
162
|
+
path = os.path.expanduser(args.output)
|
|
163
|
+
try:
|
|
164
|
+
with open(path, "wb") as fh:
|
|
165
|
+
fh.write(result)
|
|
166
|
+
_info(f"Output written to {_bold(path)}")
|
|
167
|
+
except OSError as exc:
|
|
168
|
+
_die(f"Cannot write to '{path}': {exc}")
|
|
169
|
+
else:
|
|
170
|
+
|
|
171
|
+
sys.stdout.buffer.write(result)
|
|
172
|
+
sys.stdout.buffer.write(b"\n")
|
|
173
|
+
sys.stdout.buffer.flush()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _info(msg: str) -> None:
|
|
179
|
+
_stderr(f"{_green('[OK]')} {msg}")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _stderr(msg: str) -> None:
|
|
183
|
+
try:
|
|
184
|
+
sys.stderr.write(msg + "\n")
|
|
185
|
+
except UnicodeEncodeError:
|
|
186
|
+
sys.stderr.buffer.write(msg.encode("utf-8", errors="replace"))
|
|
187
|
+
sys.stderr.buffer.write(b"\n")
|
|
188
|
+
sys.stderr.buffer.flush()
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _die(msg: str, code: int = 1) -> None:
|
|
192
|
+
_stderr(f"\n{_red('Error:')} {msg}")
|
|
193
|
+
sys.exit(code)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
199
|
+
parser = argparse.ArgumentParser(
|
|
200
|
+
prog="tde",
|
|
201
|
+
description=BANNER,
|
|
202
|
+
epilog=EPILOG,
|
|
203
|
+
formatter_class=_Formatter,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
parser.add_argument(
|
|
207
|
+
"-v", "--version",
|
|
208
|
+
action="version",
|
|
209
|
+
version=f"TDE v{__version__}",
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
parser.add_argument(
|
|
214
|
+
"command",
|
|
215
|
+
choices=["encode", "decode"],
|
|
216
|
+
help="Operation to perform: 'encode' or 'decode'.",
|
|
217
|
+
)
|
|
218
|
+
parser.add_argument(
|
|
219
|
+
"data",
|
|
220
|
+
nargs="?",
|
|
221
|
+
default=None,
|
|
222
|
+
help="Inline string payload (optional if using -i or stdin).",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
io_group = parser.add_argument_group("I/O options")
|
|
227
|
+
io_group.add_argument(
|
|
228
|
+
"-i", "--input",
|
|
229
|
+
metavar="FILE",
|
|
230
|
+
help="Read payload from FILE instead of stdin/args.",
|
|
231
|
+
)
|
|
232
|
+
io_group.add_argument(
|
|
233
|
+
"-o", "--output",
|
|
234
|
+
metavar="FILE",
|
|
235
|
+
help="Write result to FILE instead of stdout.",
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
mod_group = parser.add_argument_group("Advanced modifiers")
|
|
240
|
+
mod_group.add_argument(
|
|
241
|
+
"--url",
|
|
242
|
+
action="store_true",
|
|
243
|
+
default=False,
|
|
244
|
+
help="Use URL-safe Base64 alphabet (- _ instead of + /).",
|
|
245
|
+
)
|
|
246
|
+
mod_group.add_argument(
|
|
247
|
+
"--strict",
|
|
248
|
+
action="store_true",
|
|
249
|
+
default=False,
|
|
250
|
+
help="Halt with an error on any non-Base64 character.",
|
|
251
|
+
)
|
|
252
|
+
mod_group.add_argument(
|
|
253
|
+
"--ignore-garbage",
|
|
254
|
+
action="store_true",
|
|
255
|
+
default=False,
|
|
256
|
+
help="Strip whitespace and invalid characters before decoding.",
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
return parser
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def main() -> None:
|
|
265
|
+
parser = _build_parser()
|
|
266
|
+
args = parser.parse_args()
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
if args.strict and args.ignore_garbage:
|
|
270
|
+
_die("--strict and --ignore-garbage are mutually exclusive.\n"
|
|
271
|
+
" --strict demands perfect input.\n"
|
|
272
|
+
" --ignore-garbage silently discards bad characters.\n"
|
|
273
|
+
" Pick one.")
|
|
274
|
+
|
|
275
|
+
payload = _acquire_input(args)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
if args.command == "encode":
|
|
279
|
+
result = _encode(payload, url_safe=args.url)
|
|
280
|
+
else:
|
|
281
|
+
result = _decode(
|
|
282
|
+
payload,
|
|
283
|
+
url_safe=args.url,
|
|
284
|
+
strict=args.strict,
|
|
285
|
+
ignore_garbage=args.ignore_garbage,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
_emit(result, args)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
if __name__ == "__main__":
|
|
293
|
+
main()
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tde
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: TDE โ Tanishq's Decoder & Encoder. A fast, dependency-free Base64 CLI tool.
|
|
5
|
+
Home-page: https://github.com/tanishqzope/TDE-Tool
|
|
6
|
+
Author: Tanishq Zope
|
|
7
|
+
Author-email: tanishqzope5@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Topic :: Security :: Cryptography
|
|
14
|
+
Classifier: Topic :: Utilities
|
|
15
|
+
Requires-Python: >=3.7
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: author-email
|
|
20
|
+
Dynamic: classifier
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: description-content-type
|
|
23
|
+
Dynamic: home-page
|
|
24
|
+
Dynamic: license
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
Dynamic: requires-python
|
|
27
|
+
Dynamic: summary
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://img.shields.io/badge/TDE-v1.0.0-00C853?style=for-the-badge&logo=python&logoColor=white" alt="Version"/>
|
|
31
|
+
<img src="https://img.shields.io/badge/Python-3.7+-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python"/>
|
|
32
|
+
<img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License"/>
|
|
33
|
+
<img src="https://img.shields.io/badge/Dependencies-Zero-success?style=for-the-badge" alt="Dependencies"/>
|
|
34
|
+
<img src="https://img.shields.io/badge/Platform-Win%20%7C%20Linux%20%7C%20macOS-blue?style=for-the-badge" alt="Platform"/>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<h1 align="center">๐ TDE โ Tanishq's Decoder & Encoder</h1>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<strong>A fast, lightweight, dependency-free CLI tool for Base64 encoding & decoding.</strong><br/>
|
|
41
|
+
Built purely with Python's standard libraries โ zero security overhead, absolute portability.
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="#-features">Features</a> โข
|
|
46
|
+
<a href="#-installation">Installation</a> โข
|
|
47
|
+
<a href="#-usage">Usage</a> โข
|
|
48
|
+
<a href="#%EF%B8%8F-architecture">Architecture</a> โข
|
|
49
|
+
<a href="#-contributing">Contributing</a> โข
|
|
50
|
+
<a href="#-license">License</a>
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## โจ Features
|
|
56
|
+
|
|
57
|
+
| Feature | Description |
|
|
58
|
+
|---|---|
|
|
59
|
+
| ๐ซ **Zero Dependencies** | Runs natively using only built-in Python libraries โ nothing to install, nothing to break |
|
|
60
|
+
| ๐ฅ๏ธ **Cross-Platform** | Works seamlessly on Command Prompt, PowerShell, Git Bash, WSL, and Linux/macOS terminals |
|
|
61
|
+
| ๐ **File I/O** | Read from and write directly to files for handling large payloads or binaries |
|
|
62
|
+
| ๐ **URL-Safe Mode** | Seamlessly handle JSON Web Tokens (JWTs) and URL parameters with `-` `_` alphabet |
|
|
63
|
+
| ๐ก๏ธ **Strict Validation** | Catch malformed data streams instantly with `--strict` mode |
|
|
64
|
+
| ๐งน **Garbage Collection** | Force-decode messy inputs by stripping invalid characters automatically |
|
|
65
|
+
| ๐ **Pipe Support** | Chain with other CLI tools via stdin/stdout piping |
|
|
66
|
+
| ๐จ **Coloured Output** | ANSI colour support with automatic graceful degradation |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## ๐ฆ Installation
|
|
71
|
+
|
|
72
|
+
> **Prerequisites:** Python 3.7 or higher
|
|
73
|
+
|
|
74
|
+
### Quick Install
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/tanishqzope/TDE-Tool.git
|
|
78
|
+
cd TDE-Tool
|
|
79
|
+
pip install .
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Once installed, the `tde` command is globally available from **any terminal**.
|
|
83
|
+
|
|
84
|
+
### Verify Installation
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
tde --version
|
|
88
|
+
# Output: TDE v1.0.0
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## ๐ Usage
|
|
94
|
+
|
|
95
|
+
### Basic Encoding & Decoding
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Encode a string to Base64
|
|
99
|
+
tde encode "hello world"
|
|
100
|
+
# Output: aGVsbG8gd29ybGQ=
|
|
101
|
+
|
|
102
|
+
# Decode a Base64 string
|
|
103
|
+
tde decode "aGVsbG8gd29ybGQ="
|
|
104
|
+
# Output: hello world
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### ๐ URL-Safe Mode (`--url`)
|
|
108
|
+
|
|
109
|
+
Generate Base64 strings safe for web transit โ replaces `+`/`/` with `-`/`_` and strips `=` padding. Perfect for **JWTs** and **URL parameters**.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
tde encode "https://example.com/api?token=abc" --url
|
|
113
|
+
# Output: aHR0cHM6Ly9leGFtcGxlLmNvbS9hcGk_dG9rZW49YWJj
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### ๐ก๏ธ Strict Mode (`--strict`)
|
|
117
|
+
|
|
118
|
+
Forces the tool to **halt immediately** with a clear error if the input contains any non-Base64 characters.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
tde decode "aGVsbG8gd2!9ybGQ=" --strict
|
|
122
|
+
# Error: Strict mode: invalid Base64 character(s) found: '!'
|
|
123
|
+
# Hint: use --ignore-garbage to strip them automatically.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### ๐งน Ignore Garbage (`--ignore-garbage`)
|
|
127
|
+
|
|
128
|
+
Strips whitespace, newlines, and invalid characters before decoding โ perfect for messy copy-paste inputs.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
tde decode "aGVsbG8 gd 29ybGQ=" --ignore-garbage
|
|
132
|
+
# Output: hello world
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### ๐ File Operations
|
|
136
|
+
|
|
137
|
+
Read a payload from a file and write the decoded output to a new file:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Encode a file's contents
|
|
141
|
+
tde encode -i secret.txt -o encoded_payload.txt
|
|
142
|
+
|
|
143
|
+
# Decode back to original
|
|
144
|
+
tde decode -i encoded_payload.txt -o original.txt
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### ๐ Piping Support
|
|
148
|
+
|
|
149
|
+
Chain TDE with other CLI tools:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Pipe from echo
|
|
153
|
+
echo "sensitive data" | tde encode
|
|
154
|
+
|
|
155
|
+
# Chain with curl
|
|
156
|
+
curl -s https://api.example.com/data | tde decode
|
|
157
|
+
|
|
158
|
+
# Pipe between TDE commands (round-trip)
|
|
159
|
+
echo "hello" | tde encode | tde decode
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### ๐ Full Help Menu
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
tde --help
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
+========================================+
|
|
170
|
+
| TDE -- The Data Encoder / Decoder |
|
|
171
|
+
| v1.0.0 | Zero-dependency Base64 |
|
|
172
|
+
+========================================+
|
|
173
|
+
|
|
174
|
+
positional arguments:
|
|
175
|
+
{encode,decode} Operation to perform: 'encode' or 'decode'.
|
|
176
|
+
data Inline string payload (optional if using -i or stdin).
|
|
177
|
+
|
|
178
|
+
I/O options:
|
|
179
|
+
-i, --input FILE Read payload from FILE instead of stdin/args.
|
|
180
|
+
-o, --output FILE Write result to FILE instead of stdout.
|
|
181
|
+
|
|
182
|
+
Advanced modifiers:
|
|
183
|
+
--url Use URL-safe Base64 alphabet (- _ instead of + /).
|
|
184
|
+
--strict Halt with an error on any non-Base64 character.
|
|
185
|
+
--ignore-garbage Strip whitespace and invalid characters before decoding.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## ๐๏ธ Architecture
|
|
191
|
+
|
|
192
|
+
### High-Level Overview
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
196
|
+
โ tde <command> [data] [flags] โ
|
|
197
|
+
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
198
|
+
โ
|
|
199
|
+
โผ
|
|
200
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
201
|
+
โ 1. ARGUMENT PARSER (argparse) โ
|
|
202
|
+
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
|
|
203
|
+
โ โ command โ โ data โ โ flags โ โ I/O options โ โ
|
|
204
|
+
โ โencode/ โ โ(inline) โ โ--url โ โ -i input file โ โ
|
|
205
|
+
โ โdecode โ โ โ โ--strictโ โ -o output file โ โ
|
|
206
|
+
โ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโฌโโโโโ โโโโโโโโโโฌโโโโโโโโโ โ
|
|
207
|
+
โโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโ
|
|
208
|
+
โ โ โ โ
|
|
209
|
+
โผ โผ โ โ
|
|
210
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโ
|
|
211
|
+
โ 2. INPUT ROUTER โ โ โ
|
|
212
|
+
โ Priority Hierarchy: โ โ โ
|
|
213
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโ โ โ โ
|
|
214
|
+
โ โ 1. File (-i flag) โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโ โ
|
|
215
|
+
โ โ 2. Stdin (piped) โ โ โ
|
|
216
|
+
โ โ 3. Arg (inline) โ โ โ
|
|
217
|
+
โ โโโโโโโโโโโโฌโโโโโโโโโโโโ โ โ
|
|
218
|
+
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
219
|
+
โ โ
|
|
220
|
+
โผ โผ
|
|
221
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
222
|
+
โ 3. PROCESSING CORE โ
|
|
223
|
+
โ โ
|
|
224
|
+
โ โโ ENCODE โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
225
|
+
โ โ input bytes โโโบ b64encode() โโโบ result โ โ
|
|
226
|
+
โ โ --url? โโโบ urlsafe_b64encode() โโโบ strip '=' pad โ โ
|
|
227
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
228
|
+
โ โ
|
|
229
|
+
โ โโ DECODE โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
230
|
+
โ โ --strict? โโโบ regex validate โโโบ halt on bad โ โ
|
|
231
|
+
โ โ --ignore-garbage? โโโบ regex strip junk chars โ โ
|
|
232
|
+
โ โ --url? โโโบ restore padding โโโบ urlsafe_b64 โ โ
|
|
233
|
+
โ โ (default) โโโบ b64decode() โโโบ result โ โ
|
|
234
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
235
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
236
|
+
โ
|
|
237
|
+
โผ
|
|
238
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
239
|
+
โ 4. OUTPUT ROUTER โ
|
|
240
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
241
|
+
โ โ -o flag set? โโโบ Write bytes to file โ โ
|
|
242
|
+
โ โ (default) โโโบ Print to stdout โ โ
|
|
243
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
244
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Data Flow
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
User Input โโโบ Argument Parser โโโบ Input Router โโโบ Processing Core โโโบ Output Router
|
|
251
|
+
โ โ โ โ
|
|
252
|
+
Parse command Read from: Apply flags: Deliver to:
|
|
253
|
+
& flags โข File (-i) โข --url โข File (-o)
|
|
254
|
+
โข Stdin (pipe) โข --strict โข Stdout
|
|
255
|
+
โข Inline arg โข --ignore-garbage
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Module Structure
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
TDE-Tool/
|
|
262
|
+
โโโ .gitignore # Git ignore rules
|
|
263
|
+
โโโ LICENSE # MIT License
|
|
264
|
+
โโโ README.md # This file
|
|
265
|
+
โโโ setup.py # Installer with console_scripts entry point
|
|
266
|
+
โโโ tde/ # Main package
|
|
267
|
+
โโโ __init__.py # Version constant (__version__ = "1.0.0")
|
|
268
|
+
โโโ cli.py # Complete CLI implementation
|
|
269
|
+
# โโโ ANSI colour helpers
|
|
270
|
+
# โโโ Banner & help formatter
|
|
271
|
+
# โโโ _acquire_input() โ Input Router
|
|
272
|
+
# โโโ _encode() โ Encoding engine
|
|
273
|
+
# โโโ _decode() โ Decoding engine
|
|
274
|
+
# โโโ _emit() โ Output Router
|
|
275
|
+
# โโโ main() โ Entry point
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## ๐ง CLI Reference
|
|
281
|
+
|
|
282
|
+
| Argument | Type | Description |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| `encode` | Command | Convert input to Base64 |
|
|
285
|
+
| `decode` | Command | Convert Base64 back to original |
|
|
286
|
+
| `<data>` | Positional | Inline string payload |
|
|
287
|
+
| `-i`, `--input` | Flag | Read payload from a file |
|
|
288
|
+
| `-o`, `--output` | Flag | Write result to a file |
|
|
289
|
+
| `-v`, `--version` | Flag | Show version (`TDE v1.0.0`) |
|
|
290
|
+
| `-h`, `--help` | Flag | Show help menu with examples |
|
|
291
|
+
| `--url` | Modifier | Use URL-safe Base64 alphabet |
|
|
292
|
+
| `--strict` | Modifier | Error on invalid characters |
|
|
293
|
+
| `--ignore-garbage` | Modifier | Strip invalid characters before decoding |
|
|
294
|
+
|
|
295
|
+
> โ ๏ธ `--strict` and `--ignore-garbage` are **mutually exclusive** โ they cannot be used together.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## ๐ฏ Use Cases
|
|
300
|
+
|
|
301
|
+
| Scenario | Command |
|
|
302
|
+
|---|---|
|
|
303
|
+
| ๐ Encode API keys for config files | `tde encode "sk-abc123secret"` |
|
|
304
|
+
| ๐ Generate URL-safe JWT tokens | `tde encode "payload" --url` |
|
|
305
|
+
| ๐ง Decode email attachments | `tde decode -i attachment.b64 -o file.pdf` |
|
|
306
|
+
| ๐งช Validate Base64 integrity | `tde decode "data..." --strict` |
|
|
307
|
+
| ๐ Clean up messy copy-paste | `tde decode "broken data" --ignore-garbage` |
|
|
308
|
+
| ๐ Round-trip verification | `echo "test" \| tde encode \| tde decode` |
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## ๐ค Contributing
|
|
313
|
+
|
|
314
|
+
Contributions are welcome! Here's how you can help:
|
|
315
|
+
|
|
316
|
+
1. **Fork** the repository
|
|
317
|
+
2. **Create** a feature branch (`git checkout -b feature/awesome-feature`)
|
|
318
|
+
3. **Commit** your changes (`git commit -m "Add awesome feature"`)
|
|
319
|
+
4. **Push** to the branch (`git push origin feature/awesome-feature`)
|
|
320
|
+
5. **Open** a Pull Request
|
|
321
|
+
|
|
322
|
+
### Guidelines
|
|
323
|
+
|
|
324
|
+
- Use only Python standard library โ **no external dependencies**
|
|
325
|
+
- Maintain cross-platform compatibility
|
|
326
|
+
- Add comments for complex logic
|
|
327
|
+
- Test on both Windows and Linux/macOS
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## ๐ License
|
|
332
|
+
|
|
333
|
+
This project is licensed under the **MIT License** โ see the [LICENSE](LICENSE) file for details.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## ๐ค Author
|
|
338
|
+
|
|
339
|
+
**Tanishq Zope** โ [@tanishqzope](https://github.com/tanishqzope)
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
<p align="center">
|
|
344
|
+
<sub>Built with โค๏ธ and pure Python. No dependencies were harmed in the making of this tool.</sub>
|
|
345
|
+
</p>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
tde/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
|
2
|
+
tde/cli.py,sha256=R-8RIZPJinDEXNdwwWCv0TeM7wq6AlzObV85ixb4veA,7164
|
|
3
|
+
tde-1.0.0.dist-info/licenses/LICENSE,sha256=aaHKA_NthNc1NiIeuPxs_1zL8VTlYlY-zqbTqPpRuiQ,1069
|
|
4
|
+
tde-1.0.0.dist-info/METADATA,sha256=vRQlYsn4sbAgvsHDTfDXLbu1SF1Su6aMe7GoQANJQuY,15633
|
|
5
|
+
tde-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
6
|
+
tde-1.0.0.dist-info/entry_points.txt,sha256=bCr2PfEF4FhYGbiU47UVw99Ru5rk3f0uHdAy8L-znGA,37
|
|
7
|
+
tde-1.0.0.dist-info/top_level.txt,sha256=v0tXPRi-QeUe7-sR39AFkSG53g-Cuv_b0R_8lwc5DQ0,4
|
|
8
|
+
tde-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tanishq Zope
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tde
|