pyrotcrypt 0.1.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.
pyrotcrypt/__init__.py ADDED
@@ -0,0 +1,83 @@
1
+ import argparse
2
+ import sys
3
+ from importlib.metadata import version
4
+ from typing import Protocol, TextIO
5
+
6
+ from pyrotcrypt.files import slurp, write_file
7
+ from pyrotcrypt.rot import normalize_rotnum, rot, rotleft_equivalent
8
+
9
+ __version__ = version("pyrotcrypt")
10
+
11
+
12
+ class Reader(Protocol):
13
+ def readline(self) -> str: ...
14
+
15
+
16
+ parser = argparse.ArgumentParser(
17
+ prog="pyrotcrypt",
18
+ description="Encrypt/Decrypt text by rotating the letters of the alphabet",
19
+ )
20
+ parser.add_argument(
21
+ "-n",
22
+ "--num",
23
+ type=int,
24
+ default=13,
25
+ dest="num",
26
+ help="the number of positions to rotate each letter",
27
+ )
28
+ parser.add_argument(
29
+ "-d",
30
+ "--decrypt",
31
+ default=False,
32
+ action="store_true",
33
+ dest="decrypt",
34
+ help="decrypt the ciphertext (instead of encrypting the plaintext)",
35
+ )
36
+ parser.add_argument(
37
+ "-w",
38
+ "--write",
39
+ default=False,
40
+ action="store_true",
41
+ dest="write_files",
42
+ help="write cyperthext to files (instead of stdout)",
43
+ )
44
+ parser.add_argument(
45
+ "-v", "--version", action="version", version=f"%(prog)s {__version__}"
46
+ )
47
+ parser.add_argument(
48
+ "in_files", nargs="*", help="paths to files to be encrypted/decrypted"
49
+ )
50
+
51
+
52
+ def run(argv: list[str], stdin: Reader, stdout: TextIO, stderr: TextIO) -> int:
53
+ args = parser.parse_args(argv)
54
+ num: int = normalize_rotnum(args.num)
55
+ in_files: list[str] = args.in_files
56
+ decrypt: bool = args.decrypt
57
+ write_files: bool = args.write_files
58
+
59
+ if decrypt:
60
+ num = rotleft_equivalent(num)
61
+
62
+ if len(in_files) > 0:
63
+ if write_files:
64
+ for file in in_files:
65
+ filename = f"{file.removesuffix('.txt')}.{'plain' if decrypt else 'cipher'}.rot{args.num}.txt"
66
+ content = rot(slurp(file), num)
67
+ write_file(filename, content)
68
+ else:
69
+ stdout.writelines(rot(slurp(file), num) for file in in_files)
70
+ else:
71
+ if write_files:
72
+ filename = f"{'plain' if decrypt else 'cipher'}.rot{args.num}.txt"
73
+ content = rot("".join(list(iter(stdin.readline, ""))), num)
74
+ write_file(filename, content)
75
+ else:
76
+ while line := stdin.readline():
77
+ stdout.write(rot(line, num))
78
+
79
+ return 0
80
+
81
+
82
+ def main() -> None:
83
+ sys.exit(run(sys.argv[1:], sys.stdin, sys.stdout, sys.stderr))
pyrotcrypt/files.py ADDED
@@ -0,0 +1,8 @@
1
+ def slurp(path: str) -> str:
2
+ with open(path, encoding="utf-8") as w:
3
+ return w.read()
4
+
5
+
6
+ def write_file(path: str, content: str) -> None:
7
+ with open(path, "w", encoding="utf-8") as w:
8
+ w.write(content)
pyrotcrypt/rot.py ADDED
@@ -0,0 +1,28 @@
1
+ _alpha_size = ord("z") - ord("a") + 1
2
+ """The number of characters in the english alphabet."""
3
+
4
+
5
+ def normalize_rotnum(num: int) -> int:
6
+ """Rotating _alpha_size times is equivalent to not rotating at all.
7
+ This function ensures the rotation count stays in the [0, _alpha_size) interval.
8
+ """
9
+ return num % _alpha_size
10
+
11
+
12
+ def rotleft_equivalent(num: int) -> int:
13
+ """If the text is going to be decrypted, this function calculates the number
14
+ of rotations equivalent to rotating num times to the left.
15
+ """
16
+ return _alpha_size - normalize_rotnum(num)
17
+
18
+
19
+ def rot(text: str, n: int) -> str:
20
+ return "".join(rotate_char(c, n) for c in text)
21
+
22
+
23
+ def rotate_char(c: str, n: int) -> str:
24
+ """Rotate a single character by n positions, preserving case."""
25
+ if c.isalpha():
26
+ base = ord("a") if c.islower() else ord("A")
27
+ return chr((ord(c) - base + n) % 26 + base)
28
+ return c
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.3
2
+ Name: pyrotcrypt
3
+ Version: 0.1.0
4
+ Summary: Encrypt and decrypt a text by rotating letters of the alphpabet.
5
+ Author: angel
6
+ Author-email: angel <gitsoor@proton.me>
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+
10
+ # Pyrotcrypt
11
+
12
+ A CLI to encrypt and decrypt text using [Caesar's cipher](https://en.wikipedia.org/wiki/Caesar_cipher).
13
+ (Don't use it to encrypt secrets, only for fun!)
14
+
15
+ # Usage
16
+
17
+ Encrypt text from stdin, using the default 13 rotations:
18
+
19
+ ```bash
20
+ $ pyrotcrypt < example.txt
21
+ ```
22
+
23
+ Decrypt text from stdin using the `--decrypt` flag:
24
+
25
+ ```bash
26
+ $ pyrotcrypt --decrypt < example.encrypted.txt
27
+ ```
28
+
29
+ Encrypt and decrypt usign a different number of rotations:
30
+
31
+ ```bash
32
+ $ pyrotcrypt --num 10 < example.txt
33
+ $ pyrotcrypt --num 10 --decrypt < example.encrypted.txt
34
+ ```
35
+
36
+ Encrypt files, writing the ciphertext to stdout:
37
+
38
+ ```bash
39
+ $ pyrotcrypt example.txt another_example.txt
40
+ ```
41
+
42
+ Encrypt files, writing the ciphertext to files:
43
+
44
+ ```bash
45
+ $ pyrotcrypt --write example.txt another_example.txt
46
+ ```
47
+
48
+ Writes the result of encrypting _example.txt_ to _example.cipher.rot13.txt_ and _another_example.txt_ to _another_example.cipher.rot13.txt_.
49
+
50
+ Encrypt from stin to a file called _cipher.rot7.txt_:
51
+
52
+ ```bash
53
+ $ pyrotcrypt --num 7 --write < example.txt
54
+ ```
@@ -0,0 +1,7 @@
1
+ pyrotcrypt/__init__.py,sha256=cc62GOuhnjCBjNORUdWzn_Mseza7HqSsYXou9xgvM-s,2304
2
+ pyrotcrypt/files.py,sha256=-C1AGrKsiaj_5UWJAebPCt-p-a1WwO_MWKTYAWCyGxc,222
3
+ pyrotcrypt/rot.py,sha256=LsY09Sn6y6t2yBTFkNGZH_2hUHKAYLvjAnUSLH37XsI,909
4
+ pyrotcrypt-0.1.0.dist-info/WHEEL,sha256=e4_1dyBeezi8ZjfxrZ3bnVOxFDa3ksqVqH0jTHkUZ3k,81
5
+ pyrotcrypt-0.1.0.dist-info/entry_points.txt,sha256=DkE-og9XwVFLqNAXVWPsEPIi7xdIOL_QAZX-G3wjzGk,48
6
+ pyrotcrypt-0.1.0.dist-info/METADATA,sha256=LEjXB_xrYfeazbeGhSbhWF3X4zoYWky71fbjVT7V7Ew,1275
7
+ pyrotcrypt-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.12.19
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ pyrotcrypt = pyrotcrypt:main
3
+