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 +83 -0
- pyrotcrypt/files.py +8 -0
- pyrotcrypt/rot.py +28 -0
- pyrotcrypt-0.1.0.dist-info/METADATA +54 -0
- pyrotcrypt-0.1.0.dist-info/RECORD +7 -0
- pyrotcrypt-0.1.0.dist-info/WHEEL +4 -0
- pyrotcrypt-0.1.0.dist-info/entry_points.txt +3 -0
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
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,,
|