






'''simple docstring'''





from __future__ import annotations

import math
import random
from collections.abc import Collection
from typing import overload
class      UpperCamelCase :







		"""simple docstring"""



		def __init__(  self		:       Any						,_SCREAMING_SNAKE_CASE		:       Optional[Any] = None		)    ->   None:


						'''simple docstring'''
						if components is None:
										A	 =      []
						A	 =      list(lowerCAmelCase_		)
		def __len__(  self		:       str		)    ->   int:


						'''simple docstring'''
						return len(self.__components		)
		def __str__(  self		:       Optional[int]		)    ->   str:


						'''simple docstring'''
						return "(" + ",".join(map(lowerCAmelCase_						,self.__components		)		) + ")"
		def __add__(  self		:       List[str]						,_SCREAMING_SNAKE_CASE		:       Union[str, Any]		)    ->   Vector:


						'''simple docstring'''
						A	 =      len(self		)
						if size == len(lowerCAmelCase_		):
										A	 =      [self.__components[i] + other.component(lowerCAmelCase_		) for i in range(lowerCAmelCase_		)]
										return Vector(lowerCAmelCase_		)
						else:
										raise Exception('must have the same size'		)
		def __sub__(  self		:       int						,_SCREAMING_SNAKE_CASE		:       Dict		)    ->   Vector:


						'''simple docstring'''
						A	 =      len(self		)
						if size == len(lowerCAmelCase_		):
										A	 =      [self.__components[i] - other.component(lowerCAmelCase_		) for i in range(lowerCAmelCase_		)]
										return Vector(lowerCAmelCase_		)
						else:  # error case
										raise Exception('must have the same size'		)
		@overload
		def __mul__(  self		:       List[Any]						,_SCREAMING_SNAKE_CASE		:       List[Any]		)    ->   Vector:


						'''simple docstring'''
						...
		@overload
		def __mul__(  self		:       List[Any]						,_SCREAMING_SNAKE_CASE		:       int		)    ->   float:


						'''simple docstring'''
						...
		def __mul__(  self		:       List[Any]						,_SCREAMING_SNAKE_CASE		:       Dict		)    ->   float | Vector:


						'''simple docstring'''
						if isinstance(lowerCAmelCase_						,(float, int)		):
										A	 =      [c * other for c in self.__components]
										return Vector(lowerCAmelCase_		)
						elif isinstance(lowerCAmelCase_						,lowerCAmelCase_		) and len(self		) == len(lowerCAmelCase_		):
										A	 =      len(self		)
										A	 =      [self.__components[i] * other.component(lowerCAmelCase_		) for i in range(lowerCAmelCase_		)]
										return sum(lowerCAmelCase_		)
						else:  # error case
										raise Exception('invalid operand!'		)
		def       A(  self		:       str		)    ->   Vector:


						'''simple docstring'''
						return Vector(self.__components		)
		def       A(  self		:       Optional[Any]						,_SCREAMING_SNAKE_CASE		:       Tuple		)    ->   float:


						'''simple docstring'''
						if isinstance(lowerCAmelCase_						,lowerCAmelCase_		) and -len(self.__components		) <= i < len(self.__components		):
										return self.__components[i]
						else:
										raise Exception('index out of range'		)
		def       A(  self		:       List[str]						,_SCREAMING_SNAKE_CASE		:       Optional[int]						,_SCREAMING_SNAKE_CASE		:       Optional[int]		)    ->   None:


						'''simple docstring'''
						assert -len(self.__components		) <= pos < len(self.__components		)
						A	 =      value
		def       A(  self		:       int		)    ->   float:


						'''simple docstring'''
						if len(self.__components		) == 0:
										raise Exception('Vector is empty'		)
						A	 =      [c**2 for c in self.__components]
						return math.sqrt(sum(lowerCAmelCase_		)		)







		def       A(  self		:       Tuple						,_SCREAMING_SNAKE_CASE		:       Dict						,_SCREAMING_SNAKE_CASE		:       Dict = False		)    ->   float:


						'''simple docstring'''
						A	 =      self * other
						A	 =      self.euclidean_length() * other.euclidean_length()
						if deg:
										return math.degrees(math.acos(num / den		)		)
						else:
										return math.acos(num / den		)







def      snake_case		(							UpperCAmelCase	:       int   ):
				assert isinstance(snake_case__,						snake_case__   )
				return Vector([0] * dimension   )







def      snake_case		(							UpperCAmelCase	:       int,						UpperCAmelCase	:       int   ):
				assert isinstance(snake_case__,						snake_case__   ) and (isinstance(snake_case__,						snake_case__   ))
				A	 =      [0] * dimension
				A	 =      1
				return Vector(snake_case__   )







def      snake_case		(							UpperCAmelCase	:       float,						UpperCAmelCase	:       Vector,						UpperCAmelCase	:       Vector   ):
				assert (
				    isinstance(snake_case__,						snake_case__   )
				    and isinstance(snake_case__,						snake_case__   )
				    and (isinstance(snake_case__,						(int, float)   ))
				)
				return x * scalar + y







def      snake_case		(							UpperCAmelCase	:       int,						UpperCAmelCase	:       int,						UpperCAmelCase	:       int   ):
				random.seed(snake_case__   )
				A	 =      [random.randint(snake_case__,						snake_case__   ) for _ in range(snake_case__   )]
				return Vector(snake_case__   )
class      UpperCamelCase :







		"""simple docstring"""



		def __init__(  self		:       Dict						,_SCREAMING_SNAKE_CASE		:       Union[str, Any]						,_SCREAMING_SNAKE_CASE		:       Union[str, Any]						,_SCREAMING_SNAKE_CASE		:       Tuple		)    ->   None:


						'''simple docstring'''
						A	 =      matrix
						A	 =      w
						A	 =      h
		def __str__(  self		:       List[Any]		)    ->   str:


						'''simple docstring'''
						A	 =      ''
						for i in range(self.__height		):
										ans += "|"
										for j in range(self.__width		):
														if j < self.__width - 1:
																		ans += str(self.__matrix[i][j]		) + ","
														else:
																		ans += str(self.__matrix[i][j]		) + "|\n"
						return ans
		def __add__(  self		:       Union[str, Any]						,_SCREAMING_SNAKE_CASE		:       str		)    ->   Matrix:


						'''simple docstring'''
						if self.__width == other.width() and self.__height == other.height():
										A	 =      []
										for i in range(self.__height		):
														A	 =      [
														    self.__matrix[i][j] + other.component(lowerCAmelCase_						,lowerCAmelCase_		)
														    for j in range(self.__width		)
														]
														matrix.append(lowerCAmelCase_		)
										return Matrix(lowerCAmelCase_						,self.__width						,self.__height		)
						else:
										raise Exception('matrix must have the same dimension!'		)
		def __sub__(  self		:       str						,_SCREAMING_SNAKE_CASE		:       List[str]		)    ->   Matrix:


						'''simple docstring'''
						if self.__width == other.width() and self.__height == other.height():
										A	 =      []
										for i in range(self.__height		):
														A	 =      [
														    self.__matrix[i][j] - other.component(lowerCAmelCase_						,lowerCAmelCase_		)
														    for j in range(self.__width		)
														]
														matrix.append(lowerCAmelCase_		)
										return Matrix(lowerCAmelCase_						,self.__width						,self.__height		)
						else:
										raise Exception('matrices must have the same dimension!'		)
		@overload
		def __mul__(  self		:       Dict						,_SCREAMING_SNAKE_CASE		:       Dict		)    ->   Matrix:


						'''simple docstring'''
						...
		@overload
		def __mul__(  self		:       Any						,_SCREAMING_SNAKE_CASE		:       str		)    ->   Vector:


						'''simple docstring'''
						...
		def __mul__(  self		:       Optional[Any]						,_SCREAMING_SNAKE_CASE		:       List[str]		)    ->   Vector | Matrix:


						'''simple docstring'''
						if isinstance(lowerCAmelCase_						,lowerCAmelCase_		):  # matrix-vector
										if len(lowerCAmelCase_		) == self.__width:
														A	 =      zero_vector(self.__height		)
														for i in range(self.__height		):
																		A	 =      [
																		    self.__matrix[i][j] * other.component(lowerCAmelCase_		)
																		    for j in range(self.__width		)
																		]
																		ans.change_component(lowerCAmelCase_						,sum(lowerCAmelCase_		)		)
														return ans
										else:
														raise Exception(
														    'vector must have the same size as the '
														    'number of columns of the matrix!'		)
						elif isinstance(lowerCAmelCase_						,(int, float)		):  # matrix-scalar
										A	 =      [
										    [self.__matrix[i][j] * other for j in range(self.__width		)]
										    for i in range(self.__height		)
										]
										return Matrix(lowerCAmelCase_						,self.__width						,self.__height		)
						return None
		def       A(  self		:       Union[str, Any]		)    ->   int:


						'''simple docstring'''
						return self.__height
		def       A(  self		:       Optional[Any]		)    ->   int:


						'''simple docstring'''
						return self.__width
		def       A(  self		:       List[str]						,_SCREAMING_SNAKE_CASE		:       Tuple						,_SCREAMING_SNAKE_CASE		:       Union[str, Any]		)    ->   float:


						'''simple docstring'''
						if 0 <= x < self.__height and 0 <= y < self.__width:
										return self.__matrix[x][y]
						else:
										raise Exception('change_component: indices out of bounds'		)
		def       A(  self		:       Tuple						,_SCREAMING_SNAKE_CASE		:       Union[str, Any]						,_SCREAMING_SNAKE_CASE		:       Dict						,_SCREAMING_SNAKE_CASE		:       List[str]		)    ->   None:


						'''simple docstring'''
						if 0 <= x < self.__height and 0 <= y < self.__width:
										A	 =      value
						else:
										raise Exception('change_component: indices out of bounds'		)
		def       A(  self		:       Tuple						,_SCREAMING_SNAKE_CASE		:       Optional[int]						,_SCREAMING_SNAKE_CASE		:       Tuple		)    ->   float:


						'''simple docstring'''
						if self.__height != self.__width:
										raise Exception('Matrix is not square'		)
						A	 =      self.__matrix[:x] + self.__matrix[x + 1 :]
						for i in range(len(lowerCAmelCase_		)		):
										A	 =      minor[i][:y] + minor[i][y + 1 :]
						return Matrix(lowerCAmelCase_						,self.__width - 1						,self.__height - 1		).determinant()
		def       A(  self		:       Optional[int]						,_SCREAMING_SNAKE_CASE		:       List[Any]						,_SCREAMING_SNAKE_CASE		:       Optional[Any]		)    ->   float:


						'''simple docstring'''
						if self.__height != self.__width:
										raise Exception('Matrix is not square'		)
						if 0 <= x < self.__height and 0 <= y < self.__width:
										return (-1) ** (x + y) * self.minor(lowerCAmelCase_						,lowerCAmelCase_		)
						else:
										raise Exception('Indices out of bounds'		)







		def       A(  self		:       Tuple		)    ->   float:


						'''simple docstring'''
						if self.__height != self.__width:
										raise Exception('Matrix is not square'		)
						if self.__height < 1:
										raise Exception('Matrix has no element'		)
						elif self.__height == 1:
										return self.__matrix[0][0]
						elif self.__height == 2:
										return (
										    self.__matrix[0][0] * self.__matrix[1][1]
										    - self.__matrix[0][1] * self.__matrix[1][0]
										)
						else:
										A	 =      [
										    self.__matrix[0][y] * self.cofactor(0						,lowerCAmelCase_		) for y in range(self.__width		)
										]
										return sum(lowerCAmelCase_		)







def      snake_case		(							UpperCAmelCase	:       int   ):
				A	 =      [[0] * n for _ in range(snake_case__   )]
				return Matrix(snake_case__,						snake_case__,						snake_case__   )







def      snake_case		(							UpperCAmelCase	:       int,						UpperCAmelCase	:       int,						UpperCAmelCase	:       int,						UpperCAmelCase	:       int   ):
				random.seed(snake_case__   )
				A	 =      [
				    [random.randint(snake_case__,						snake_case__   ) for _ in range(snake_case__   )] for _ in range(snake_case__   )
				]
				return Matrix(snake_case__,						snake_case__,						snake_case__   )













def      snake_case		(							UpperCAmelCase	:       Optional[int],						UpperCAmelCase	:       Union[str, Any]   ):
				A	 =      ''
				for i in table:
								res += inp[i - 1]
				return res







def      snake_case		(							UpperCAmelCase	:       Union[str, Any]   ):
				return data[1:] + data[0]







def      snake_case		(							UpperCAmelCase	:       Union[str, Any],						UpperCAmelCase	:       Dict   ):
				A	 =      ''
				for i in range(len(UpperCAmelCase   )   ):
								if a[i] == b[i]:
												res += "0"
								else:
												res += "1"
				return res







def      snake_case		(							UpperCAmelCase	:       int,						UpperCAmelCase	:       Optional[Any]   ):
				A	 =      int('0b' + data[0] + data[-1],						2   )
				A	 =      int('0b' + data[1:3],						2   )
				return bin(s[row][col]   )[2:]







def      snake_case		(							UpperCAmelCase	:       Optional[Any],						UpperCAmelCase	:       Any,						UpperCAmelCase	:       Union[str, Any],						UpperCAmelCase	:       Optional[Any],						UpperCAmelCase	:       Optional[int]   ):
				A	 =      message[:4]
				A	 =      message[4:]
				A	 =      apply_table(UpperCAmelCase,						UpperCAmelCase   )
				A	 =      xor(UpperCAmelCase,						UpperCAmelCase   )
				A	 =      apply_sbox(UpperCAmelCase,						temp[:4]   )  # noqa: E741
				A	 =      apply_sbox(UpperCAmelCase,						temp[4:]   )
				A	 =      '0' * (2 - len(UpperCAmelCase   )) + l  # noqa: E741
				A	 =      '0' * (2 - len(UpperCAmelCase   )) + r
				A	 =      apply_table(l + r,						UpperCAmelCase   )
				A	 =      xor(UpperCAmelCase,						UpperCAmelCase   )
				return temp + right


if __name__ == "__main__":
					lowerCAmelCase_           = input('Enter 10 bit key: ')
					lowerCAmelCase_           = input('Enter 8 bit message: ')

					lowerCAmelCase_           = [6, 3, 7, 4, 8, 5, 10, 9]
					lowerCAmelCase_           = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
					lowerCAmelCase_           = [2, 4, 3, 1]
					lowerCAmelCase_           = [2, 6, 3, 1, 4, 8, 5, 7]
					lowerCAmelCase_           = [4, 1, 3, 5, 7, 2, 8, 6]
					lowerCAmelCase_           = [4, 1, 2, 3, 2, 3, 4, 1]
					lowerCAmelCase_           = [[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]]
					lowerCAmelCase_           = [[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]

					# key generation
					lowerCAmelCase_           = apply_table(key, paa_table)
					lowerCAmelCase_           = temp[:5]
					lowerCAmelCase_           = temp[5:]
					lowerCAmelCase_           = left_shift(left)
					lowerCAmelCase_           = left_shift(right)
					lowerCAmelCase_           = apply_table(left + right, pa_table)
					lowerCAmelCase_           = left_shift(left)
					lowerCAmelCase_           = left_shift(right)
					lowerCAmelCase_           = left_shift(left)
					lowerCAmelCase_           = left_shift(right)
					lowerCAmelCase_           = apply_table(left + right, pa_table)

					# encryption
					lowerCAmelCase_           = apply_table(message, IP)
					lowerCAmelCase_           = function(expansion, sa, sa, keya, temp)
					lowerCAmelCase_           = temp[4:] + temp[:4]
					lowerCAmelCase_           = function(expansion, sa, sa, keya, temp)
					lowerCAmelCase_           = apply_table(temp, IP_inv)
					print('Cipher text is:', CT)

					# decryption
					lowerCAmelCase_           = apply_table(CT, IP)
					lowerCAmelCase_           = function(expansion, sa, sa, keya, temp)
					lowerCAmelCase_           = temp[4:] + temp[:4]
					lowerCAmelCase_           = function(expansion, sa, sa, keya, temp)
					lowerCAmelCase_           = apply_table(temp, IP_inv)
					print('Plain text after decypting is:', PT)





