Created
September 9, 2018 05:11
-
-
Save leonpanokarren/c7f494d579eaae04109fc9d097b60acf to your computer and use it in GitHub Desktop.
HackerLanguage Exercise solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import collections | |
class HackerLanguage: | |
def __init__(self, flag_character=':', **kwargs): | |
self.message = '' | |
self.flag_character = flag_character | |
def write(self, message): | |
self.message += message | |
def delete(self, delete_symbol_count): | |
self.message = self.message[: -1 * delete_symbol_count] | |
def clear(self): | |
self.message = '' | |
def send(self): | |
date_format = '[0-9]{2}.[0-9]{2}.[0-9]{4}' | |
time_format = '[0-9]{2}:[0-9]{2}[aApP][mM]' | |
pattern = '({})|({})'.format(date_format, time_format) | |
date_time_tokens = re.findall(pattern, self.message) | |
msg_fragment = collections.namedtuple('msg_fragment', 'text is_datetime') | |
message_fragments_to_encode = [] | |
message_copy = self.message | |
if date_time_tokens: | |
for date_token, time_token in date_time_tokens: | |
date_time_token = date_token if date_token else time_token | |
# date_time_token found at the beginning of the message | |
if message_copy.startswith(date_time_token): | |
message_fragments_to_encode.append(msg_fragment(date_time_token, True)) | |
message_copy = message_copy[len(date_time_token):] | |
# date_time_token found in the middle of the message | |
elif message_copy.index(date_time_token) > 0 and\ | |
message_copy.index(date_time_token) + len(date_time_token) < len(message_copy): | |
message_fragments_to_encode.extend([ | |
msg_fragment(message_copy[:message_copy.index(date_time_token)], False), | |
msg_fragment( | |
message_copy[ | |
message_copy.index(date_time_token): | |
message_copy.index(date_time_token) + len(date_time_token) | |
], | |
True | |
) | |
] | |
) | |
message_copy = message_copy[message_copy.index(date_time_token) + len(date_time_token):] | |
# date_time token at the end of the message | |
else: | |
message_fragments_to_encode.extend([ | |
msg_fragment(message_copy[:message_copy.index(date_time_token)], False), | |
msg_fragment( | |
message_copy[message_copy.index(date_time_token):], | |
True, | |
) | |
] | |
) | |
message_copy = '' | |
if not message_copy: | |
message_fragments_to_encode.append(msg_fragment(message_copy, False)) | |
else: | |
message_fragments_to_encode.append(msg_fragment(self.message, False)) | |
return ''.join([self.encode(fragment) for fragment in message_fragments_to_encode]) | |
def read(self, encrypted_message): | |
decoded_message = '' | |
while encrypted_message: | |
if encrypted_message[0] != self.flag_character: | |
decoded_message += encrypted_message[0] | |
if len(encrypted_message) == 1: | |
encrypted_message = '' | |
else: | |
encrypted_message = encrypted_message[1:] | |
elif encrypted_message[1] == self.flag_character: | |
decoded_message += self.flag_character | |
if len(encrypted_message) == 2: | |
encrypted_message = '' | |
else: | |
encrypted_message = encrypted_message[2:] | |
elif len(encrypted_message) >= 8 and encrypted_message[1:8] == '1000000': | |
decoded_message += ' ' | |
if len(encrypted_message) == 8: | |
encrypted_message = '' | |
else: | |
encrypted_message = encrypted_message[8:] | |
elif len(encrypted_message) >= 8 and re.match('^[0-9]+$', encrypted_message[1:8]): | |
decoded_message += chr(int(encrypted_message[1:8], 2)) | |
if len(encrypted_message) == 8: | |
encrypted_message = '' | |
else: | |
encrypted_message = encrypted_message[8:] | |
else: | |
decoded_message += self.flag_character | |
encrypted_message = encrypted_message[1:] | |
return decoded_message | |
def encode(self, msg_fragment): | |
if msg_fragment.is_datetime: | |
return msg_fragment.text | |
message_fragment = msg_fragment.text.replace(self.flag_character, self.flag_character * 2) | |
return ''.join( | |
[ | |
self.to_binary(char) if (char.isalpha() or char.isspace()) else char | |
for char in message_fragment | |
] | |
) | |
def to_binary(self, char): | |
return self.flag_character + (bin(ord(char))[2:] if char.isalpha() else '1000000') | |
if __name__ == '__main__': | |
#These "asserts" using only for self-checking and not necessary for auto-testing | |
message_1 = HackerLanguage() | |
message_1.write("secrit") | |
message_1.delete(2) | |
message_1.write("et") | |
message_2 = HackerLanguage() | |
assert message_1.send() == "111001111001011100011111001011001011110100" | |
assert message_2.read("11001011101101110000111010011101100") == "email" | |
print("Coding complete? Let's try tests!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment