From 5d0a46814e5b69f79d623187912c0f81ab5ab7a7 Mon Sep 17 00:00:00 2001 From: aryan1165 <111041731+aryan1165@users.noreply.github.com> Date: Tue, 10 Oct 2023 01:08:04 +0530 Subject: [PATCH 1/2] Added ciphers/permutation_cipher.py. (#9163) * Added permutation_cipher.py * Added type hints for parameters * Added doctest in functions * Update ciphers/permutation_cipher.py Ya i felt the same but held back because there is a implementation of transposition_cipher.py. But that's is different from the one i have implemented here. Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * Update ciphers/permutation_cipher.py Co-authored-by: Tianyi Zheng * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Changes --------- Co-authored-by: Tianyi Zheng Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- ciphers/permutation_cipher.py | 142 ++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 ciphers/permutation_cipher.py diff --git a/ciphers/permutation_cipher.py b/ciphers/permutation_cipher.py new file mode 100644 index 000000000..c3f3fd1f7 --- /dev/null +++ b/ciphers/permutation_cipher.py @@ -0,0 +1,142 @@ +""" +The permutation cipher, also called the transposition cipher, is a simple encryption +technique that rearranges the characters in a message based on a secret key. It +divides the message into blocks and applies a permutation to the characters within +each block according to the key. The key is a sequence of unique integers that +determine the order of character rearrangement. + +For more info: https://www.nku.edu/~christensen/1402%20permutation%20ciphers.pdf +""" +import random + + +def generate_valid_block_size(message_length: int) -> int: + """ + Generate a valid block size that is a factor of the message length. + + Args: + message_length (int): The length of the message. + + Returns: + int: A valid block size. + + Example: + >>> random.seed(1) + >>> generate_valid_block_size(12) + 3 + """ + block_sizes = [ + block_size + for block_size in range(2, message_length + 1) + if message_length % block_size == 0 + ] + return random.choice(block_sizes) + + +def generate_permutation_key(block_size: int) -> list[int]: + """ + Generate a random permutation key of a specified block size. + + Args: + block_size (int): The size of each permutation block. + + Returns: + list[int]: A list containing a random permutation of digits. + + Example: + >>> random.seed(0) + >>> generate_permutation_key(4) + [2, 0, 1, 3] + """ + digits = list(range(block_size)) + random.shuffle(digits) + return digits + + +def encrypt( + message: str, key: list[int] | None = None, block_size: int | None = None +) -> tuple[str, list[int]]: + """ + Encrypt a message using a permutation cipher with block rearrangement using a key. + + Args: + message (str): The plaintext message to be encrypted. + key (list[int]): The permutation key for decryption. + block_size (int): The size of each permutation block. + + Returns: + tuple: A tuple containing the encrypted message and the encryption key. + + Example: + >>> encrypted_message, key = encrypt("HELLO WORLD") + >>> decrypted_message = decrypt(encrypted_message, key) + >>> decrypted_message + 'HELLO WORLD' + """ + message = message.upper() + message_length = len(message) + + if key is None or block_size is None: + block_size = generate_valid_block_size(message_length) + key = generate_permutation_key(block_size) + + encrypted_message = "" + + for i in range(0, message_length, block_size): + block = message[i : i + block_size] + rearranged_block = [block[digit] for digit in key] + encrypted_message += "".join(rearranged_block) + + return encrypted_message, key + + +def decrypt(encrypted_message: str, key: list[int]) -> str: + """ + Decrypt an encrypted message using a permutation cipher with block rearrangement. + + Args: + encrypted_message (str): The encrypted message. + key (list[int]): The permutation key for decryption. + + Returns: + str: The decrypted plaintext message. + + Example: + >>> encrypted_message, key = encrypt("HELLO WORLD") + >>> decrypted_message = decrypt(encrypted_message, key) + >>> decrypted_message + 'HELLO WORLD' + """ + key_length = len(key) + decrypted_message = "" + + for i in range(0, len(encrypted_message), key_length): + block = encrypted_message[i : i + key_length] + original_block = [""] * key_length + for j, digit in enumerate(key): + original_block[digit] = block[j] + decrypted_message += "".join(original_block) + + return decrypted_message + + +def main() -> None: + """ + Driver function to pass message to get encrypted, then decrypted. + + Example: + >>> main() + Decrypted message: HELLO WORLD + """ + message = "HELLO WORLD" + encrypted_message, key = encrypt(message) + + decrypted_message = decrypt(encrypted_message, key) + print(f"Decrypted message: {decrypted_message}") + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + main() From 6d3b58ea782ba430170a4b86028a595d9cba64e5 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 9 Oct 2023 19:52:12 +0000 Subject: [PATCH 2/2] updating DIRECTORY.md --- DIRECTORY.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index b1a23a239..c4ad4fc8e 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -54,13 +54,12 @@ * [Largest Pow Of Two Le Num](bit_manipulation/largest_pow_of_two_le_num.py) * [Missing Number](bit_manipulation/missing_number.py) * [Numbers Different Signs](bit_manipulation/numbers_different_signs.py) + * [Power Of 4](bit_manipulation/power_of_4.py) * [Reverse Bits](bit_manipulation/reverse_bits.py) * [Single Bit Manipulation Operations](bit_manipulation/single_bit_manipulation_operations.py) ## Blockchain - * [Chinese Remainder Theorem](blockchain/chinese_remainder_theorem.py) * [Diophantine Equation](blockchain/diophantine_equation.py) - * [Modular Division](blockchain/modular_division.py) ## Boolean Algebra * [And Gate](boolean_algebra/and_gate.py) @@ -101,11 +100,13 @@ * [Diffie Hellman](ciphers/diffie_hellman.py) * [Elgamal Key Generator](ciphers/elgamal_key_generator.py) * [Enigma Machine2](ciphers/enigma_machine2.py) + * [Fractionated Morse Cipher](ciphers/fractionated_morse_cipher.py) * [Hill Cipher](ciphers/hill_cipher.py) * [Mixed Keyword Cypher](ciphers/mixed_keyword_cypher.py) * [Mono Alphabetic Ciphers](ciphers/mono_alphabetic_ciphers.py) * [Morse Code](ciphers/morse_code.py) * [Onepad Cipher](ciphers/onepad_cipher.py) + * [Permutation Cipher](ciphers/permutation_cipher.py) * [Playfair Cipher](ciphers/playfair_cipher.py) * [Polybius](ciphers/polybius.py) * [Porta Cipher](ciphers/porta_cipher.py) @@ -172,6 +173,7 @@ ## Data Structures * Arrays + * [Equilibrium Index In Array](data_structures/arrays/equilibrium_index_in_array.py) * [Median Two Array](data_structures/arrays/median_two_array.py) * [Permutations](data_structures/arrays/permutations.py) * [Prefix Sum](data_structures/arrays/prefix_sum.py) @@ -352,6 +354,7 @@ * [Smith Waterman](dynamic_programming/smith_waterman.py) * [Subset Generation](dynamic_programming/subset_generation.py) * [Sum Of Subset](dynamic_programming/sum_of_subset.py) + * [Trapped Water](dynamic_programming/trapped_water.py) * [Tribonacci](dynamic_programming/tribonacci.py) * [Viterbi](dynamic_programming/viterbi.py) * [Word Break](dynamic_programming/word_break.py) @@ -360,6 +363,7 @@ * [Apparent Power](electronics/apparent_power.py) * [Builtin Voltage](electronics/builtin_voltage.py) * [Carrier Concentration](electronics/carrier_concentration.py) + * [Charging Capacitor](electronics/charging_capacitor.py) * [Circular Convolution](electronics/circular_convolution.py) * [Coulombs Law](electronics/coulombs_law.py) * [Electric Conductivity](electronics/electric_conductivity.py) @@ -466,6 +470,8 @@ * [Test Min Spanning Tree Prim](graphs/tests/test_min_spanning_tree_prim.py) ## Greedy Methods + * [Best Time To Buy And Sell Stock](greedy_methods/best_time_to_buy_and_sell_stock.py) + * [Fractional Cover Problem](greedy_methods/fractional_cover_problem.py) * [Fractional Knapsack](greedy_methods/fractional_knapsack.py) * [Fractional Knapsack 2](greedy_methods/fractional_knapsack_2.py) * [Gas Station](greedy_methods/gas_station.py) @@ -524,6 +530,10 @@ * Local Weighted Learning * [Local Weighted Learning](machine_learning/local_weighted_learning/local_weighted_learning.py) * [Logistic Regression](machine_learning/logistic_regression.py) + * Loss Functions + * [Binary Cross Entropy](machine_learning/loss_functions/binary_cross_entropy.py) + * [Huber Loss](machine_learning/loss_functions/huber_loss.py) + * [Mean Squared Error](machine_learning/loss_functions/mean_squared_error.py) * [Mfcc](machine_learning/mfcc.py) * [Multilayer Perceptron Classifier](machine_learning/multilayer_perceptron_classifier.py) * [Polynomial Regression](machine_learning/polynomial_regression.py) @@ -565,6 +575,7 @@ * [Catalan Number](maths/catalan_number.py) * [Ceil](maths/ceil.py) * [Check Polygon](maths/check_polygon.py) + * [Chinese Remainder Theorem](maths/chinese_remainder_theorem.py) * [Chudnovsky Algorithm](maths/chudnovsky_algorithm.py) * [Collatz Sequence](maths/collatz_sequence.py) * [Combinations](maths/combinations.py) @@ -591,6 +602,7 @@ * [Gaussian](maths/gaussian.py) * [Gaussian Error Linear Unit](maths/gaussian_error_linear_unit.py) * [Gcd Of N Numbers](maths/gcd_of_n_numbers.py) + * [Germain Primes](maths/germain_primes.py) * [Greatest Common Divisor](maths/greatest_common_divisor.py) * [Greedy Coin Change](maths/greedy_coin_change.py) * [Hamming Numbers](maths/hamming_numbers.py) @@ -619,6 +631,7 @@ * [Max Sum Sliding Window](maths/max_sum_sliding_window.py) * [Median Of Two Arrays](maths/median_of_two_arrays.py) * [Mobius Function](maths/mobius_function.py) + * [Modular Division](maths/modular_division.py) * [Modular Exponential](maths/modular_exponential.py) * [Monte Carlo](maths/monte_carlo.py) * [Monte Carlo Dice](maths/monte_carlo_dice.py) @@ -720,12 +733,16 @@ ## Neural Network * [2 Hidden Layers Neural Network](neural_network/2_hidden_layers_neural_network.py) * Activation Functions + * [Binary Step](neural_network/activation_functions/binary_step.py) * [Exponential Linear Unit](neural_network/activation_functions/exponential_linear_unit.py) * [Leaky Rectified Linear Unit](neural_network/activation_functions/leaky_rectified_linear_unit.py) * [Mish](neural_network/activation_functions/mish.py) * [Rectified Linear Unit](neural_network/activation_functions/rectified_linear_unit.py) * [Scaled Exponential Linear Unit](neural_network/activation_functions/scaled_exponential_linear_unit.py) * [Sigmoid Linear Unit](neural_network/activation_functions/sigmoid_linear_unit.py) + * [Soboleva Modified Hyperbolic Tangent](neural_network/activation_functions/soboleva_modified_hyperbolic_tangent.py) + * [Softplus](neural_network/activation_functions/softplus.py) + * [Squareplus](neural_network/activation_functions/squareplus.py) * [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py) * [Convolution Neural Network](neural_network/convolution_neural_network.py) * [Perceptron](neural_network/perceptron.py) @@ -1101,6 +1118,7 @@ * [Interpolation Search](searches/interpolation_search.py) * [Jump Search](searches/jump_search.py) * [Linear Search](searches/linear_search.py) + * [Median Of Medians](searches/median_of_medians.py) * [Quick Select](searches/quick_select.py) * [Sentinel Linear Search](searches/sentinel_linear_search.py) * [Simple Binary Search](searches/simple_binary_search.py) @@ -1201,6 +1219,7 @@ * [Snake Case To Camel Pascal Case](strings/snake_case_to_camel_pascal_case.py) * [Split](strings/split.py) * [String Switch Case](strings/string_switch_case.py) + * [Strip](strings/strip.py) * [Text Justification](strings/text_justification.py) * [Top K Frequent Words](strings/top_k_frequent_words.py) * [Upper](strings/upper.py)