def _merge_commute_key_list(commute_key: List[Key]) -> Optional[List[Key]]: """Given a list of commute keys, merge keys with same move and index. :param commute_key: A list of commute keys. :return: The reduced list of keys. """ # Set the starting index to 0 and initialize the key index list. start_index = 0 # Keep checking keys until all are checked. while start_index < len(commute_key): # Check all keys after the starting key. for each_key in commute_key[start_index + 1:]: # If the key share same index and move with the starting key. if each_key.move == commute_key[start_index].move \ and each_key.index == commute_key[start_index].index: # Do the merge and replace start key. commute_key[start_index] = Key( move=commute_key[start_index].move, index=commute_key[start_index].index, angle=commute_key[start_index].angle + each_key.angle) # Remove the merged key. commute_key.remove(each_key) # Move to the next key. start_index += 1 # Only return the keys whose move angle is not a multiple of 360. return [ Key(move=each_key.move, index=each_key.index, angle=each_key.angle % 360) for each_key in commute_key if each_key.angle % 360 != 0 ]
def test_encryption(self): # Test redundant keys give the same result. self.protocol.encrypt(key=[Key(move="right", angle=360, index=1)]) first_content = self.protocol.get_current_binary() self.protocol.decrypt() self.protocol.encrypt(key=[Key(move="left", angle=360, index=1)]) second_content = self.protocol.get_current_binary() assert first_content == second_content
def test_location_tracker(self): # Set up analyzer and the key to perform checking. analyzer = CubieLocationAnalyzer( cube_side_length=3, track_item_location=0 ) keys = [ Key(move="left", angle=90, index=1), Key(move="top", angle=90, index=1), Key(move="down", angle=90, index=1) ] np.testing.assert_array_equal( analyzer.location_tracker(keys=keys), [0, 37, 110, 183] )
def test_key_table(self): pd.testing.assert_frame_equal( utility.get_key_table( key=[ Key(move="right", index=1, angle=180), Key(move="top", index=2, angle=90), Key(move="back", index=1, angle=270), ] ), pd.DataFrame( data=[["right", 1, 180], ["top", 2, 90], ["back", 1, 270]], index=[1, 2, 3], columns=["Movement", "Index", "Angle"] ) )
def test_down_90(self): # Create the cube. cube = Cube(cube_input=self.cube_input, cube_side_length=2) cube.shift(Key(move=CubeMove.down.value, angle=90, index=1)) assert cube.content == \ "123456789012345678901234123456783456789056789012" \ "290141236345856778901234123456783456789056789012"
def test_back_90(self): # Create the cube. cube = Cube(cube_input=self.cube_input, cube_side_length=2) cube.shift(Key(move=CubeMove.back.value, angle=90, index=1)) assert cube.content == \ "890767859012345678901234567890123456456312340129" \ "123456784563234185670789290141236785789023415678"
def test_front_90(self): # Create the cube. cube = Cube(cube_input=self.cube_input, cube_side_length=2) cube.shift(Key(move=CubeMove.front.value, angle=90, index=1)) assert cube.content == \ "123456788567078985670789290141232901789063455678" \ "412363459012345678901234567890123456412312348567"
def test_left_90(self): # Create the cube. cube = Cube(cube_input=self.cube_input, cube_side_length=2) cube.shift(Key(move=CubeMove.left.value, angle=90, index=1)) assert cube.content == \ "129056783412345612341234901290123456789012345678" \ "789056785678345678901290567834124123634585670789"
def test_special(self): # Create the cube. cube = Cube(cube_input=self.cube_input, cube_side_length=2) try: cube.shift(Key(move="abracadabra", angle=90, index=0)) raise AssertionError("Error message did not raise.") except ValueError as error: assert str(error) == WRONG_CUBE_MOVE
def _get_basic_key(self) -> List[Key]: """Get all the possible keys with fixed 90 degrees. :return: A list of basic keys. """ return [ Key(move=move, angle=90, index=index) for move in CUBE_MOVE for index in range(1, math.floor(self._side_length / 2) + 1) ]
def test_merge_key(self): self.analyzer._merge_key() assert self.analyzer._key == [ Key(move="left", angle=90, index=0), Key(move="top", angle=90, index=0), Key(move="down", angle=90, index=2), Key(move="top", angle=90, index=0), Key(move="left", angle=90, index=0), Key(move="front", angle=180, index=2), Key(move="back", angle=90, index=0), Key(move="right", angle=180, index=2) ]
def test_analyze(self): assert self.analyzer.analyze() == [ Key(move="left", angle=90, index=0), Key(move="top", angle=180, index=0), Key(move="down", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="front", angle=180, index=2), Key(move="back", angle=90, index=0), Key(move="right", angle=180, index=2) ]
def decrypt(self): """Decrypt the message to plain text.""" # While there are still keys, keep running. while self._key: # Pop the key from saved keys. each_key = self._key.pop() for cube in self._cubes: # Reverse the cube shift move. cube.shift(key=Key(move=each_key.move, angle=360 - each_key.angle, index=each_key.index)) # Shift content backward. cube.shift_content_back()
def decrypt(self): """Decrypt the message to plain text.""" while self._key: # Pop the key from saved keys. each_key = self._key.pop() for cube in self._cubes: # Reverse the cube shift move. cube.shift(key=Key(move=each_key.move, angle=360 - each_key.angle, index=each_key.index)) # Shift content backward by one space. cube.shift_cubie_content_back() # Xor the cube. cube.xor()
def generate_random_keys(length: int, max_index: int) -> List[Key]: """Generate a random key with cube moves for a certain size cube. :param length: Desired number of moves of the key. :param max_index: Max index of the cube side. :return: A list of random keys. """ return [ Key( move=random.choice(CUBE_MOVE), angle=random.choice(MOVE_ANGLE), index=random.randint(1, max_index) ) for _ in range(length) ]
def test_merge_commute_key_list(self): # This is the first test case. test_key = [ Key(move="right", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="right", angle=180, index=2), Key(move="right", angle=90, index=2) ] assert \ self.analyzer._merge_commute_key_list(commute_key=test_key) == \ [Key(move="left", angle=90, index=0)] # This is the second test case. test_key = [ Key(move="right", angle=90, index=2), Key(move="right", angle=90, index=1), Key(move="right", angle=90, index=0) ] assert \ self.analyzer._merge_commute_key_list(commute_key=test_key) == \ test_key
def test_get_all_effective_key(self): assert self.analyzer._get_all_effective_key() == [ Key(move=move, angle=angle, index=1) for move in ["left", "top", "back"] for angle in MOVE_ANGLE ]
def test_get_effective_key(self): assert self.analyzer._get_effective_key() == [ Key(move=move, angle=90, index=1) for move in ["left", "top", "back"] ]
def test_check_effective_key(self): assert self.analyzer._check_effective_key( key=Key(move="left", angle=90, index=1) )
def test_get_all_basic_key(self): assert self.analyzer._get_basic_key() == [ Key(move=move, angle=90, index=1) for move in CUBE_MOVE ]
def test_encryption(self): self.protocol.encrypt(key=[Key(move="right", angle=360, index=1)]) assert self.protocol.get_current_content()[1:11] == \ self.protocol.process_string(self.message)
def test_get_location(self): assert self.analyzer._get_location( key=Key(move="left", angle=90, index=1)) == 37
def test_get_commute_key_list(self): assert self.analyzer._get_commute_key_list() == [[ Key(move="right", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="right", angle=270, index=2) ], [Key(move="top", angle=90, index=0)], [ Key(move="right", angle=90, index=2), Key(move="right", angle=270, index=2), ], [ Key(move="down", angle=90, index=2), Key(move="top", angle=90, index=0) ], [ Key(move="left", angle=90, index=0) ], [ Key(move="front", angle=90, index=2), Key(move="back", angle=90, index=0), Key(move="front", angle=90, index=2) ], [ Key(move="right", angle=90, index=2), Key(move="right", angle=90, index=2) ]]
class TestKeyAnalyzer: # Set up the test key. key = [ Key(move="right", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="right", angle=270, index=2), Key(move="top", angle=90, index=0), Key(move="right", angle=90, index=2), Key(move="right", angle=270, index=2), Key(move="down", angle=90, index=2), Key(move="top", angle=90, index=0), Key(move="left", angle=90, index=0), Key(move="front", angle=90, index=2), Key(move="back", angle=90, index=0), Key(move="front", angle=90, index=2), Key(move="right", angle=90, index=2), Key(move="right", angle=90, index=2) ] # Set up the key analyzer object. analyzer = KeyAnalyzer(key=key) def test_check_commute(self): assert self.analyzer._commute(move_one="left", move_two="left") assert self.analyzer._commute(move_one="right", move_two="left") assert not self.analyzer._commute(move_one="top", move_two="left") def test_get_commute_key_list(self): assert self.analyzer._get_commute_key_list() == [[ Key(move="right", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="right", angle=270, index=2) ], [Key(move="top", angle=90, index=0)], [ Key(move="right", angle=90, index=2), Key(move="right", angle=270, index=2), ], [ Key(move="down", angle=90, index=2), Key(move="top", angle=90, index=0) ], [ Key(move="left", angle=90, index=0) ], [ Key(move="front", angle=90, index=2), Key(move="back", angle=90, index=0), Key(move="front", angle=90, index=2) ], [ Key(move="right", angle=90, index=2), Key(move="right", angle=90, index=2) ]] def test_merge_commute_key_list(self): # This is the first test case. test_key = [ Key(move="right", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="right", angle=180, index=2), Key(move="right", angle=90, index=2) ] assert \ self.analyzer._merge_commute_key_list(commute_key=test_key) == \ [Key(move="left", angle=90, index=0)] # This is the second test case. test_key = [ Key(move="right", angle=90, index=2), Key(move="right", angle=90, index=1), Key(move="right", angle=90, index=0) ] assert \ self.analyzer._merge_commute_key_list(commute_key=test_key) == \ test_key def test_merge_key(self): self.analyzer._merge_key() assert self.analyzer._key == [ Key(move="left", angle=90, index=0), Key(move="top", angle=90, index=0), Key(move="down", angle=90, index=2), Key(move="top", angle=90, index=0), Key(move="left", angle=90, index=0), Key(move="front", angle=180, index=2), Key(move="back", angle=90, index=0), Key(move="right", angle=180, index=2) ] def test_analyze(self): assert self.analyzer.analyze() == [ Key(move="left", angle=90, index=0), Key(move="top", angle=180, index=0), Key(move="down", angle=90, index=2), Key(move="left", angle=90, index=0), Key(move="front", angle=180, index=2), Key(move="back", angle=90, index=0), Key(move="right", angle=180, index=2) ]