

'''simple docstring'''

SCREAMING_SNAKE_CASE							:				List[Any]     	=			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"




def 							_UpperCamelCase				(   lowerCAmelCase__:					bytes   )      -> bytes:
							# Make sure the supplied data is a bytes-like object
							if not isinstance(lowerCAmelCase__		,lowerCAmelCase__   ):
														SCREAMING_SNAKE_CASE_				=				F"""a bytes-like object is required, not '{data.__class__.__name__}'"""
														raise TypeError(lowerCAmelCase__   )

							SCREAMING_SNAKE_CASE_				=				''.join(bin(lowerCAmelCase__   )[2:].zfill(8   ) for byte in data   )

							SCREAMING_SNAKE_CASE_				=				len(lowerCAmelCase__   ) % 6 != 0

							if padding_needed:
														# The padding that will be added later
														SCREAMING_SNAKE_CASE_				=				B'=' * ((6 - len(lowerCAmelCase__   ) % 6) // 2)

														# Append binary_stream with arbitrary binary digits (0's by default) to make its
														# length a multiple of 6.
														binary_stream += "0" * (6 - len(lowerCAmelCase__   ) % 6)
							else:
														SCREAMING_SNAKE_CASE_				=				B''

							# Encode every 6 binary digits to their corresponding Base64 character
							return (
							    "".join(
							        B64_CHARSET[int(binary_stream[index : index + 6]		,2   )]
							        for index in range(0		,len(lowerCAmelCase__   )		,6   )   ).encode()
							    + padding
							)




def 							_UpperCamelCase				(   lowerCAmelCase__:					str   )      -> bytes:
							# Make sure encoded_data is either a string or a bytes-like object
							if not isinstance(lowerCAmelCase__		,lowerCAmelCase__   ) and not isinstance(lowerCAmelCase__		,lowerCAmelCase__   ):
														SCREAMING_SNAKE_CASE_				=				(
														    'argument should be a bytes-like object or ASCII string, '
														    F"""not '{encoded_data.__class__.__name__}'"""
														)
														raise TypeError(lowerCAmelCase__   )

							# In case encoded_data is a bytes-like object, make sure it contains only
							# ASCII characters so we convert it to a string object
							if isinstance(lowerCAmelCase__		,lowerCAmelCase__   ):
														try:
																					SCREAMING_SNAKE_CASE_				=				encoded_data.decode('utf-8'   )
														except UnicodeDecodeError:
																					raise ValueError('base64 encoded data should only contain ASCII characters'   )

							SCREAMING_SNAKE_CASE_				=				encoded_data.count('='   )

							# Check if the encoded string contains non base64 characters
							if padding:
														assert all(
														    char in B64_CHARSET for char in encoded_data[:-padding]   ), "Invalid base64 character(s) found."
							else:
														assert all(
														    char in B64_CHARSET for char in encoded_data   ), "Invalid base64 character(s) found."

							# Check the padding
							assert len(lowerCAmelCase__   ) % 4 == 0 and padding < 3, "Incorrect padding"

							if padding:
														# Remove padding if there is one
														SCREAMING_SNAKE_CASE_				=				encoded_data[:-padding]

														SCREAMING_SNAKE_CASE_				=				''.join(
														    bin(B64_CHARSET.index(lowerCAmelCase__   )   )[2:].zfill(6   ) for char in encoded_data   )[: -padding * 2]
							else:
														SCREAMING_SNAKE_CASE_				=				''.join(
														    bin(B64_CHARSET.index(lowerCAmelCase__   )   )[2:].zfill(6   ) for char in encoded_data   )

							SCREAMING_SNAKE_CASE_				=				[
							    int(binary_stream[index : index + 8]		,2   )
							    for index in range(0		,len(lowerCAmelCase__   )		,8   )
							]

							return bytes(lowerCAmelCase__   )


if __name__ == "__main__":
							import doctest

							doctest.testmod()








'''simple docstring'''

def 							_UpperCamelCase				(   lowerCAmelCase__:					int		,lowerCAmelCase__:					bool = False   )      -> bool:
							if n == 2:
														return True
							if not n % 2 or n < 2:
														return False
							if n > 5 and n % 10 not in (1, 3, 7, 9):  # can quickly check last digit
														return False
							if n > 3_3170_4406_4679_8873_8596_1981 and not allow_probable:
														raise ValueError(
														    'Warning: upper bound of deterministic test is exceeded. '
														    'Pass allow_probable=True to allow probabilistic test. '
														    'A return value of True indicates a probable prime.'   )
							# array bounds provided by analysis
							SCREAMING_SNAKE_CASE_				=				[
							    2047,
							    137_3653,
							    2532_6001,
							    32_1503_1751,
							    2_1523_0289_8747,
							    3_4747_4966_0383,
							    341_5500_7172_8321,
							    1,
							    382_5123_0565_4641_3051,
							    1,
							    1,
							    3186_6585_7834_0311_5116_7461,
							    3_3170_4406_4679_8873_8596_1981,
							]

							SCREAMING_SNAKE_CASE_				=				[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
							for idx, _p in enumerate(lowerCAmelCase__		,1   ):
														if n < _p:
																					# then we have our last prime to check
																					SCREAMING_SNAKE_CASE_				=				primes[:idx]
																					break
							SCREAMING_SNAKE_CASE_				,    SCREAMING_SNAKE_CASE_				=				n - 1, 0
							# break up n -1 into a power of 2 (s) and
							# remaining odd component
							# essentially, solve for d * 2 ** s == n - 1
							while d % 2 == 0:
														d //= 2
														s += 1
							for prime in plist:
														SCREAMING_SNAKE_CASE_				=				False
														for r in range(lowerCAmelCase__   ):
																					SCREAMING_SNAKE_CASE_				=				pow(lowerCAmelCase__		,d * 2**r		,lowerCAmelCase__   )
																					# see article for analysis explanation for m
																					if (r == 0 and m == 1) or ((m + 1) % n == 0):
																												SCREAMING_SNAKE_CASE_				=				True
																												# this loop will not determine compositeness
																												break
														if pr:
																					continue
														# if pr is False, then the above loop never evaluated to true,
														# and the n MUST be composite
														return False
							return True




def 							_UpperCamelCase				(   )      -> None:
							assert not miller_rabin(561   )
							assert miller_rabin(563   )
							# 2047

							assert not miller_rabin(83_8201   )
							assert miller_rabin(83_8207   )
							# 1_373_653

							assert not miller_rabin(1731_6001   )
							assert miller_rabin(1731_6017   )
							# 25_326_001

							assert not miller_rabin(30_7838_6641   )
							assert miller_rabin(30_7838_6653   )
							# 3_215_031_751

							assert not miller_rabin(1_7130_4557_4801   )
							assert miller_rabin(1_7130_4557_4819   )
							# 2_152_302_898_747

							assert not miller_rabin(2_7797_9972_8307   )
							assert miller_rabin(2_7797_9972_8327   )
							# 3_474_749_660_383

							assert not miller_rabin(113_8500_2390_9441   )
							assert miller_rabin(113_8500_2390_9527   )
							# 341_550_071_728_321

							assert not miller_rabin(127_5041_0188_4880_4351   )
							assert miller_rabin(127_5041_0188_4880_4391   )
							# 3_825_123_056_546_413_051

							assert not miller_rabin(796_6646_4458_5077_8779_1867   )
							assert miller_rabin(796_6646_4458_5077_8779_1951   )
							# 318_665_857_834_031_151_167_461

							assert not miller_rabin(5528_4067_7446_6478_9766_0333   )
							assert miller_rabin(5528_4067_7446_6478_9766_0359   )
							# 3_317_044_064_679_887_385_961_981
							# upper limit for probabilistic test


if __name__ == "__main__":
							test_miller_rabin()





