Skip to content

Commit

Permalink
πŸ—“ Aug 7, 2023 9:05:32 PM
Browse files Browse the repository at this point in the history
✨ shuffle
✨ to/from letter_number_code
πŸ§ͺ tests added/updated
πŸ™ show warning on cli when output may be unexpected
πŸ™ add numbers, dots and dash to nato
πŸ€– types added/updated
  • Loading branch information
securisec committed Aug 8, 2023
1 parent 615bac8 commit 23c03e5
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 5 deletions.
3 changes: 2 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ New ideas:
☐ ✨ amf encode/decode
☐ ✨ rabbit encryption
☐ ✨ aes cmac
☐ ✨ shuffle
☐ ✨ cetacean encode/decode
☐ ✨ ls47 enc/dec
☐ ✨ Letter Number Code (A1Z26) A=1, B=2, C=3 encoder/decoder T4 l16 _36 510 _27 s26 _11 320 414 {6 }39 C2 T0 m28 317 y35 d31 F1 m22 g19 d38 z34 423 l15 329 c12 ;37 19 h13 _30 F5 t7 C3 325 z33 _21 h8 n18 132 k24 = TFCCTF{th15_ch4ll3ng3_m4k3s_m3_d1zzy_;d}

Bug:

Expand Down Expand Up @@ -62,6 +62,7 @@ Misc:
☐ cyberchef recipe to chepy recipe converter

Archive:
βœ” ✨ shuffle
βœ” πŸš€ add crib for xor bruteforce
βœ” ✨ twin hex encoder/decoder
βœ” ✨ base36 encoder decoder
Expand Down
2 changes: 2 additions & 0 deletions chepy/core.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ ChepyCoreT = TypeVar('ChepyCoreT', bound='ChepyCore')
class ChepyDecorators:
@staticmethod
def call_stack(func: Any, *args: Any, **kwargs: Any): ...
@staticmethod
def is_stdout(func: Any, *args: Any, **kwargs: Any): ...

class ChepyCore:
states: Any = ...
Expand Down
4 changes: 2 additions & 2 deletions chepy/modules/dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ def to_nato(self, join_by: str = " ") -> DataFormatT:
data: str = self._convert_to_str()
for d in data:
if d.isalpha():
hold.append(nato_chars[d.upper()])
hold.append(nato_chars.get(d.upper(), d.upper()))
else:
hold.append(d)
self.state = join_by.join(hold)
Expand All @@ -1244,7 +1244,7 @@ def from_nato(self, delimiter: str = " ", join_by: str = "") -> DataFormatT:
"""
data = self._convert_to_str().split(delimiter)
d = {v: k for k, v in Encoding.NATO_CONSTANTS_DICT.items()}
self.state = join_by.join([d.get(p, "") for p in data])
self.state = join_by.join([d.get(p, p) for p in data])
return self

@ChepyDecorators.call_stack
Expand Down
45 changes: 45 additions & 0 deletions chepy/modules/encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import codecs
import itertools
import string
import random
from typing import Literal, TypeVar, Dict, Any, Union

import lazy_import
Expand Down Expand Up @@ -1424,3 +1425,47 @@ def monoalphabetic_substitution(
hold += mapping.get(c.lower(), c)
self.state = hold
return self

@ChepyDecorators.call_stack
def to_letter_number_code(
self, join_by: Union[str, bytes] = b" "
) -> EncryptionEncodingT:
"""Encode to A1Z26
Args:
join_by (Union[str, bytes], optional): join output by. Defaults to b' '.
Returns:
Chepy: The Chepy object.
"""
join_by = self._str_to_bytes(join_by)
data = list(self._convert_to_str())
hold = []
for i, d in enumerate(data):
hold.append(f"{d}{i}".encode())
random.shuffle(hold)
self.state = join_by.join(hold)
return self

@ChepyDecorators.call_stack
def from_letter_number_code(
self, delimiter: Union[str, bytes] = " ", join_by: Union[str, bytes] = ""
) -> EncryptionEncodingT:
"""Decode A1Z26
Args:
delimiter (Union[str, bytes], optional): Split on. Defaults to ' '.
join_by (Union[str, bytes], optional): Join output by. Defaults to ''.
Returns:
Chepy: The Chepy object.
"""
data = self._convert_to_str().split(delimiter)
hold = ["Β§" for _ in range(len(data))]
for d in data:
try:
hold[int(d[1:])] = d[0]
except: # pragma: no cover
continue
self.state = join_by.join(hold).encode()
return self
2 changes: 2 additions & 0 deletions chepy/modules/encryptionencoding.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ class EncryptionEncoding(ChepyCore):
def rsa_private_pem_to_jwk(self: EncryptionEncodingT) -> EncryptionEncodingT: ...
def rsa_public_key_from_jwk(self: EncryptionEncodingT) -> EncryptionEncodingT: ...
def monoalphabetic_substitution(self: EncryptionEncodingT, mapping: Dict[str, str]=...): ...
def to_letter_number_code(self: EncryptionEncodingT, join_by: Union[str, bytes]=...) -> EncryptionEncodingT: ...
def from_letter_number_code(self: EncryptionEncodingT, delimiter: Union[str, bytes]=..., join_by: Union[str, bytes]=...) -> EncryptionEncodingT: ...
12 changes: 12 additions & 0 deletions chepy/modules/internal/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ class Encoding(object):
"X": "Xray",
"Y": "Yankee",
"Z": "Zulu",
"-": "Dash",
".": "Dot",
"0": "Zero",
"1": "One",
"2": "Two",
"3": "Three",
"4": "Four",
"5": "Five",
"6": "Six",
"7": "Seven",
"8": "Eight",
"9": "Nine",
}

py_encodings = [
Expand Down
31 changes: 31 additions & 0 deletions chepy/modules/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import lazy_import
import random
import difflib
from collections import OrderedDict
from typing import TypeVar, Union
Expand Down Expand Up @@ -663,3 +664,33 @@ def regex_to_str(self, all_combo: bool = False) -> UtilsT:
else:
self.state = exrex.getone(self._convert_to_str())
return self

@ChepyDecorators.call_stack
def shuffle(self) -> UtilsT:
"""Shuffle the state if it is a list, string or bytes. The state is
unchanged if any other types.
Returns:
Chepy: _description_
"""
data = self.state
if not isinstance(
data,
(
bytes,
str,
list,
),
):
return self
if isinstance(
data,
(
bytes,
str,
),
):
data = list(data)
random.shuffle(data)
self.state = data
return self
3 changes: 2 additions & 1 deletion chepy/modules/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class Utils(ChepyCore):
def escape_string(self: UtilsT) -> UtilsT: ...
def unescape_string(self: UtilsT) -> UtilsT: ...
def color_hex_to_rgb(self: UtilsT) -> UtilsT: ...
def diff(self: UtilsT, state: int=..., buffer: int=..., colors: bool=..., swap: bool=...) -> Any: ...
def diff(self: UtilsT, state: int=..., buffer: int=..., colors: bool=..., swap: bool=...) -> UtilsT: ...
def pad(self: UtilsT, width: int, direction: Literal['left', 'right']=..., char: str=...) -> UtilsT: ...
def count(self: UtilsT) -> UtilsT: ...
def set(self: UtilsT) -> UtilsT: ...
def regex_to_str(self: UtilsT, all_combo: bool=...) -> UtilsT: ...
def shuffle(self: UtilsT) -> UtilsT: ...
6 changes: 6 additions & 0 deletions tests/test_dataformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,12 @@ def test_nato_convert():
.o
== b"LAKEMICHIGAN"
)
assert (
Chepy(
"Whiskey Hotel Four Tango Dash Alpha Romeo Three Dash Yankee Oscar Uniform Dash Sierra One November Kilo India November Golf Dash Four Bravo Zero Uniform Seven"
).from_nato().o
== b"WH4T-AR3-YOU-S1NKING-4B0U7"
)


def test_swap_strings():
Expand Down
15 changes: 15 additions & 0 deletions tests/test_encryptionencoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,3 +729,18 @@ def test_rsa_public_key_from_jwk():
.o
== b"""-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bxlRFYk+nczolmssgXI\nsQo9TTRyLpNKDE0hg4ViZNxOQ63jjCTqSSsmZb/4Pt326n0NzJxEeaJ9I3JwpYFr\nmjkbB+/mk5CyAEL75cMUDyWO3I9DnYR2tHHI4zhd/VQIaIn48A6AjMFHTiTYxM6B\n03EWSb7U7FqJmUlxTAjuOkeMSQQrMtD8cptJAKHtiYSRPEfN77q3Hr6zx0pXeQnE\nG+P/fassID6MeJjMAA9xHc1yG8Oc2hnGSvS9Ao6usIIvuShk7lxHjbPyZ2uuC1eN\nc7qkGiwq2KTX/Huy4cARHt3g/zdGO9nF+ONaUc7yHgzV6Rwch7li25uc9uYS5rYm\nOwIDAQAB\n-----END PUBLIC KEY-----"""
)


def test_from_letter_number_code():
assert (
Chepy(
"T4 l16 _36 510 _27 s26 _11 320 414 {6 }39 C2 T0 m28 317 y35 d31 F1 m22 g19 d38 z34 423 l15 329 c12 ;37 19 h13 _30 F5 t7 C3 325 z33 _21 h8 n18 132 k24"
)
.from_letter_number_code()
.o
== b"TFCCTF{th15_ch4ll3ng3_m4k3s_m3_d1zzy_;d}"
)


def test_to_letter_number_code():
assert len(Chepy("test").to_letter_number_code().o.split()) == 4
9 changes: 8 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def test_slice():


def test_strip_ansi():
assert Chepy("[38;2;92;207;230m;-- main:[0m").strip_ansi().o == b";-- main:"
assert Chepy("\x1b[38;2;92;207;230m;-- main:\x1b[0m").strip_ansi().o == b";-- main:"


def test_strip():
Expand Down Expand Up @@ -221,3 +221,10 @@ def test_filter_list_by_length():
def test_regex_to_str():
assert len(Chepy("lol([a-c])").regex_to_str().o) == 4
assert len(Chepy("lol([a-c])").regex_to_str(all_combo=True).o) == 3


def test_shuffle():
assert Chepy({"a": 1}).shuffle().o == {"a": 1}
assert len(Chepy([1, 2, 3]).shuffle().o) == 3
assert len(Chepy("abc").shuffle().o) == 3
assert len(Chepy(b"abdc").shuffle().o) != 3

0 comments on commit 23c03e5

Please sign in to comment.