-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecode.py
More file actions
64 lines (50 loc) · 1.98 KB
/
decode.py
File metadata and controls
64 lines (50 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import numpy as np
import re
import sys
from utils import get_encoding_matrix, ord_to_char, list_chunk
def decode(n, msg):
"""Decodes a given encoded string into the original message
Args:
n (int): Size of the encoding matrix
msg (str): Space-delimited string of encoded ordinals
"""
validate_encoded_message(msg)
encoded_ords = encoded_ords_to_matrix(n, msg)
A = get_encoding_matrix(n)
print(f"Input message:", encoded_ords, sep="\n")
# Transpose yA=b to get A^t*y^t=b^t, which can be solved using numpy
decoded_ords = np.linalg.solve(np.transpose(A), np.transpose(encoded_ords))
decoded_msg = decoded_ord_matrix_to_msg(decoded_ords)
print(f"Decoded Message: {decoded_msg}")
def decoded_ord_matrix_to_msg(matrix):
"""Converts a matrix of ordinals into the original message.
Args:
matrix (np.ndarray): Matrix of decoded ordinals
Returns:
str: Message corresponding to the matrix of orbitals
"""
decoded_msg = (
"".join([ord_to_char(round(i)) for i in matrix.flatten(order="F")])
.upper()
.strip()
)
return decoded_msg
def encoded_ords_to_matrix(n, ords):
"""Converts a list of encoded ordinals into a matrix of encoded ordinals.
Args:
n (int): Width of the encoded ordinal matrix
ords (str): Space-delimited string of encoded ordinals
Returns:
np.ndarray: Matrix of encoded ordinals corresponding to `ords`.
"""
ords = ords.strip().split(" ")
chunks = list(list_chunk(ords, n))
return np.asarray(chunks, dtype=float).reshape(len(chunks), n)
def validate_encoded_message(msg):
"""Ensures that the encoded message only contains integers and spaces
Args:
msg (str): Space-delimited string of encoded orbitals
"""
NUMERIC_AND_SPACE_ONLY_REGEX = re.compile("^(?:(?:-?\d)?\s?)*$")
if not (NUMERIC_AND_SPACE_ONLY_REGEX.match(msg)):
sys.exit(f"The encoded message may only contain integers and spaces.")