├── iss.pptx ├── DNA FINAL.docx ├── DNA-Genetic-Encryption-Technique-master ├── __pycache__ │ ├── dna block.png │ └── utils.cpython-38.pyc ├── original.txt ├── enc_dec_exec.py ├── encrypted.txt ├── utils.py ├── dna_gdt.py ├── dna_get.py └── key.txt ├── Project Implementation └── README.md /iss.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitya123-github/DNA-Genetic-Encryption/HEAD/iss.pptx -------------------------------------------------------------------------------- /DNA FINAL.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitya123-github/DNA-Genetic-Encryption/HEAD/DNA FINAL.docx -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/__pycache__/dna block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitya123-github/DNA-Genetic-Encryption/HEAD/DNA-Genetic-Encryption-Technique-master/__pycache__/dna block.png -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/__pycache__/utils.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitya123-github/DNA-Genetic-Encryption/HEAD/DNA-Genetic-Encryption-Technique-master/__pycache__/utils.cpython-38.pyc -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/original.txt: -------------------------------------------------------------------------------- 1 | In computer science and operations research, a genetic algorithm (GA) is a metaheuristic inspired by the process of natural selection that belongs to the larger class of evolutionary algorithms (EA). -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/enc_dec_exec.py: -------------------------------------------------------------------------------- 1 | from dna_get import main as encrypt 2 | from dna_gdt import main as decrypt 3 | 4 | if __name__ == '__main__': 5 | # run encryption 6 | print("\n######## ENCRYPTION ########") 7 | encrypt() 8 | 9 | # run decryption 10 | print("\n######## DECRYPTION ########") 11 | decrypt() 12 | -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/encrypted.txt: -------------------------------------------------------------------------------- 1 | TACAAGGGGTGCGGGAAGCTCCTATATCTATAGATACACTCCTGATCGCTCTCTCATAAGTTATAACAGTCTGGAAGGCCCCTCCAGTACTTGCAACATCTTTCGCGCGCTGCTACTCTTGAGGTACAGGCATCGCCCACTGTACGGTCACTGCGGCCTGACCCGTGGGCACTACCGTGGTTGCTGAACCATTGCACACACTTCAGCCCGCGGAAGGCTTTTGTAAACAGTAGTCACATCTGGGAACGTGTAGCATACAGTAACAGAAGCCGCGGAAATTGGTCCCTGCTGAGCTGTAGACATCAGCTACTGGCATTTGTTTGCTATATAGTTTCTCATTAGCAGAAGCAGAGCCCTAGGGGTAACGAGTCTTGTGCAGCCCAATTACTGTCCCCCCATCAAATGAACTCGACGCCTGTGACTTGTGGAAGCTATCCGCCTATGTCGGAAGTCGGCACTAGTCTCATGAGCTGTCGGTCCTCCTGCAGTGTCCCACACACGCCTGGAGCAAGGTATATCTGAATTGCACAGGCGGGGAGTCCGTCCCCGGAGTTCGGGGGATCCGAAATGTCAGGATCGCCTTCAAGCGCACTTTCCAAACTTTGGACCGGTGCAAGGAGCTCCCACTCGCGAGATACTGTTTGCTAGGCGTTCCCGTCAGTGCGCTCCCGTCGCATAATAGTGAACCTGGCAAAGCAACCCAAGCTAATTGTTTGTCTTTGCGAGTTGTCGACGTGAGAAGGTACTAGTCTAACCCTTGTATATAGACCGTCCATCACTGCCCTGAGGGACAACG -------------------------------------------------------------------------------- /Project Implementation: -------------------------------------------------------------------------------- 1 | #TOOLS USED: PYTHON 2 | 3 | #MODULES: 4 | Pre processing 5 | Encryption 6 | Re shaping 7 | Cross over 8 | Mutation 9 | 10 | #ABSTRACT: 11 | In this technique,we take binaries of any type of digital data and convert it to DNA sequencing, reshape, encrypt, crossover, mutate and then reshape. The main stages of D-GET are repeated three times or more. Transmit the encrypted data in text/image format file. In other side, the receiver uses the D-GET to decrypt the received data and reshape it to original format. This Technique multiple key sequences to increase the degree of diffusion and confusion, which makes resulting cipher data difficult to decipher and makes to realize a perfect secrecy system. Experimental results demonstrate that proposed technique has multilayer protection stages against different attacks and higher level of security based on the multi-stages and genetic operations. Decrypted data are acceptable because of there is absolutely difference between it and secret data. 12 | 13 | STAGES: 14 | 15 | Pre-processing Stage 16 | After reading secret data, this data must be preparing depending into its type. In case text file, it is converted into ASCII values. Group them into 8-bits Binary data. Every two adjacent bits are transferred to the four bases; adenine (A), cytosine (C), guanine (G) and thymine (T), found in DNA 17 | 18 | Encryption stage: 19 | After conversion binary data to DNA sequencing then encrypt using key. The key may be DNA sequence or binary string. The key has variable length. If one or both of data and DNA sequence key DNA sequence, it will convert to binary form then, perform an exclusive OR operation on the corresponding elements of them and convert back to DNA sequence. 20 | 21 | Reshaping Stage 22 | After Encryption, A basic genetic algorithm is 23 | composed of three operators; reproduction, crossover and mutation. To produce genetic material that pass to the next operation and iteration in the form of chromosome population, the Reshaping stage is used. In this stage, first number and length of chromosome are determined. These values may be constant are varied for every round. Reshape it by align the DNA sequence into rows to construct parents’ chromosomes (chromosome population) with pre-defined length. 24 | 25 | Crossover Stage 26 | After constructing parents’ chromosomes, the next operation is crossover. There are two types of crossover. These may be sequentially used in technique rounds. In the first one, the parents are selected in the mating pool. A single-point crossover point is selected between the first and last bits of the parents’ chromosomes then, creating two new offspring by exchanging the heads of parent1 and parent2. Consequently the offspring containportions of the DNA codes of both parents 27 | 28 | Mutation Stage 29 | After crossover process, the chromosomes are 30 | subjected to mutation. Mutation is the alteration of string elements. Two types of mutation are used. In the first one, convert data to binary vector and define two mutation points between the first and last bits then complement bits in between i.e. single point mutation changes a 1 to a 0, and vice versa. In the second mutation type, convert each four bits to two bases of DNA (1010 -> CG). After conversion, reshape it to DNA bases vector and define two points between the first and last bases then alter DNA bases to another one (i.e., C -> G). 31 | 32 | INPUT: A DNA sequence 33 | OUTPUT: Encryption and decryption of data using DNA-Genetic Encryption Technique 34 | 35 | A SIMPLE EXPLAINATION OF PROJECT: 36 | 37 | Setglobal: 38 | Used to set no of rounds 39 | No. Is Determined randomly 40 | No of rounds: no of times genetic algo is applied 41 | Encryptkey: 42 | Get data 43 | Key ( dna form or binary form) 44 | Convert both to same form and do xor only if key size 0.5 shift right by generation of another random no 66 | Eg: 67 | P = 0.8 68 | 1111 0000 69 | Random no = 4 70 | Then shift right by 4 71 | 0000 1111 72 | 73 | If p<0.5 shift left 74 | Single pt cross over 75 | Get a random no 76 | And shift up with down 77 | Eg: 78 | Random no is 5 79 | 1111 0 1111 80 | 0000 1 0000 81 | 0,1 is at position 5 82 | So, 83 | 1111 1 1111 84 | 0000. 0 0000 85 | Crossover : 86 | Find 3 random no and based on it decide single pt or rotate or both 87 | Complement 88 | Find random no 89 | At tat point convert 0 to 1 90 | 1 to 0 91 | Alter dna 92 | Find 2 random dna item and swap them 93 | Eg: abcd 94 | Pt:2,3 so b becomes c and c becomes b 95 | So 96 | Acbd 97 | Mutation : 98 | Calls complement and alter dna 99 | + 100 | Convert every 4 bit into a DNA 101 | Eg : 1111 is g 102 | 1011 is a 103 | Like ta 104 | Get dna : 105 | Calls all d above mentioned modules one by one 106 | Main: 107 | Get text 108 | Write in a file 109 | Convert Text to dna seq and do encryption as mentioned above. 110 | -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/utils.py: -------------------------------------------------------------------------------- 1 | import re 2 | import random 3 | import math 4 | import binascii 5 | 6 | # delimiters 7 | # use smaller delimiters encoding for saving space (e.g. -> ) 8 | key_del = "" 9 | no_rounds_del = "" 10 | round_del = "" 11 | reshape_del = "" 12 | crossover_del = "" 13 | crossover_type_del = "" 14 | single_point_crossover_del = "" 15 | rotate_crossover_del = "" 16 | rotation_offset_del = "" 17 | rotation_types_del = "" 18 | mutation_del = "" 19 | complement_mutation_del = "" 20 | alter_mutation_del = "" 21 | mutation_table_del = "" 22 | chromosome_del = "" 23 | 24 | # generate encoding tables domains 25 | two_bit_list = ['00', '01', '10', '11'] 26 | dna_bases = ['A', 'C', 'G', 'T'] 27 | 28 | four_bit_list = ['0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', 29 | '1101', '1110', '1111'] 30 | two_dna_bases = ['TA', 'TC', 'TG', 'TT', 'GA', 'GC', 'GG', 'GT', 'CA', 'CC', 'CG', 'CT', 'AA', 'AC', 'AG', 'AT'] 31 | 32 | # encoding tables and their reversal 33 | two_bits_to_dna_base_table = None 34 | dna_base_to_two_bits_table = None 35 | 36 | four_bits_to_two_dna_base_table = None 37 | two_dna_base_to_four_bits_table = None 38 | 39 | key_filename = "key.txt" 40 | original_filename = "original.txt" 41 | encrypted_filename = "encrypted.txt" 42 | decrypted_filename = "decrypted.txt" 43 | 44 | 45 | def str2bin(sstring): 46 | """ 47 | Transform a string (e.g. 'Hello') into a string of bits 48 | """ 49 | bs = '' 50 | for c in sstring: 51 | bs = bs + bin(ord(c))[2:].zfill(8) 52 | return bs 53 | 54 | 55 | def bin2str(bs): 56 | """ 57 | Transform a binary string into an ASCII string 58 | """ 59 | n = int(bs, 2) 60 | return binascii.unhexlify('%x' % n) 61 | 62 | 63 | def byte2bin(byte_val): 64 | """ 65 | Transform a byte (8-bit) value into a bitstring 66 | """ 67 | return bin(byte_val)[2:].zfill(8) 68 | 69 | 70 | def bitxor(a, b): 71 | """ 72 | Xor two bit strings (trims the longer input) 73 | """ 74 | return "".join([str(int(x) ^ int(y)) for (x, y) in zip(a, b)]) 75 | 76 | 77 | def divisors(n): 78 | """ 79 | Get the divisors of a natural number. 80 | :param n: the number 81 | :return: list of divisors 82 | """ 83 | divs = [] 84 | for i in range(2, int(math.sqrt(n)) + 1): 85 | if n % i == 0: 86 | divs.extend([i, n / i]) 87 | 88 | divs = [int(d) for d in divs] 89 | return list(set(divs)) 90 | 91 | 92 | def generate_pre_processing_tables(): 93 | """ 94 | Generate the 2 bits to dna bases encoding table (e.g. '01'->C) 95 | """ 96 | global two_bits_to_dna_base_table 97 | global dna_base_to_two_bits_table 98 | 99 | # if you want random table 100 | # random.shuffle(dna_bases) 101 | two_bits_to_dna_base_table = dict(zip(two_bit_list, dna_bases)) 102 | dna_base_to_two_bits_table = dict(zip(two_bits_to_dna_base_table.values(), two_bits_to_dna_base_table.keys())) 103 | 104 | 105 | def generate_mutation_tables(): 106 | """ 107 | Generate the 4 bits to 2 dna bases encoding table (e.g. '0101'->CG) 108 | """ 109 | global four_bits_to_two_dna_base_table 110 | global two_dna_base_to_four_bits_table 111 | 112 | # if you want random table 113 | # random.shuffle(two_dna_bases) 114 | four_bits_to_two_dna_base_table = dict(zip(four_bit_list, two_dna_bases)) 115 | two_dna_base_to_four_bits_table = dict( 116 | zip(four_bits_to_two_dna_base_table.values(), four_bits_to_two_dna_base_table.keys())) 117 | 118 | 119 | def group_bits(byte, step=2): 120 | """ 121 | Group the bits from a byte / bigger sequence of bits into groups by length "step" 122 | :return: a list of groups 123 | """ 124 | bits_groups = [] 125 | for i in range(0, len(byte), step): 126 | bits_groups.append(byte[i:i + step]) 127 | return bits_groups 128 | 129 | 130 | def group_bases(dna_seq, step=2): 131 | """ 132 | Group the DNA base from a sequence into groups by length "step" 133 | :return: a list of groups 134 | """ 135 | bases_groups = [] 136 | for i in range(0, len(dna_seq), step): 137 | bases_groups.append(dna_seq[i:i + step]) 138 | return bases_groups 139 | 140 | 141 | def generate_bits(byte_data): 142 | """ 143 | Take every byte for sequence and group its bits 144 | :return: 145 | """ 146 | grouped_bits_data = [] 147 | 148 | for byte in byte_data: 149 | grouped_bits_data.extend(group_bits(byte)) 150 | 151 | return grouped_bits_data 152 | 153 | 154 | def binarized_data(data): 155 | # convert every char to ASCII and then to binary 156 | byte_data = [byte2bin(ord(c)) for c in data] 157 | 158 | return generate_bits(byte_data) 159 | 160 | 161 | def bits_to_dna(data, conversion_table): 162 | # convert binary sequence to DNA sequence 163 | return "".join([conversion_table[bits] for bits in data]) 164 | 165 | 166 | def dna_to_bits(data, conversion_table): 167 | # convert DNA sequence to binary sequence 168 | return "".join([conversion_table[dna_base] for dna_base in data]) 169 | 170 | 171 | def get_pattern(delimiter, s): 172 | """ 173 | Get the pattern info between delimiters from the string 174 | """ 175 | regex = "%s(.*?)%s" % (delimiter, delimiter) 176 | return re.findall(regex, s) 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DNA GENETIC ENCRYPTION 2 |

COMPLETED A RESEARCH PAPER AND ATTACHED IT IN FOLDER AS "DNA-FINAL DOC"

3 | In this project we implement a DNA-Genetic Encryption Technique (D-GET) in order to make the DNA SEQUENCE more secure and less predictable. 4 | 5 |

TOOLS USED:

6 | 7 | PYTHON 8 | 9 |

MODULES:

10 | 11 | Pre processing, 12 | Encryption, 13 | Re shaping, 14 | Cross over, 15 | Mutation, 16 | 17 |

ABSTRACT:

18 | 19 | In this technique,we take binaries of any type of digital data and convert it to DNA sequencing, reshape, encrypt, crossover, mutate and then reshape. The main stages of D-GET are repeated three times or more. Transmit the encrypted data in text/image format file. In other side, the receiver uses the D-GET to decrypt the received data and reshape it to original format. This Technique multiple key sequences to increase the degree of diffusion and confusion, which makes resulting cipher data difficult to decipher and makes to realize a perfect secrecy system. Experimental results demonstrate that proposed technique has multilayer protection stages against different attacks and higher level of security based on the multi-stages and genetic operations. And a symentric key cryptography is implemented in this project.And also a random key will be generated.Decrypted data are acceptable because of there is absolutely difference between it and secret data. 20 | 21 |

ARCHITECTURE DIAGRAM:

22 | 23 | ![dna](https://user-images.githubusercontent.com/53599318/99866986-d4071c00-2bdb-11eb-9a57-fbf35ead9adf.jpg) 24 | 25 |

STAGES:

26 | 27 |

Pre-processing Stage:

28 | 29 | After reading secret data, this data must be preparing depending into its type. In case text file, it is converted into ASCII values. Group them into 8-bits Binary data. Every two adjacent bits are transferred to the four bases; adenine (A), cytosine (C), guanine (G) and thymine (T), found in DNA 30 | 31 |

Encryption stage:

32 | 33 | After conversion binary data to DNA sequencing then encrypt using key. The key may be DNA sequence or binary string. The key has variable length. If one or both of data and DNA sequence key DNA sequence, it will convert to binary form then, perform an exclusive OR operation on the corresponding elements of them and convert back to DNA sequence. 34 | 35 |

Reshaping Stage:

36 | 37 | After Encryption, A basic genetic algorithm is 38 | composed of three operators; reproduction, crossover and mutation. To produce genetic material that pass to the next operation and iteration in the form of chromosome population, the Reshaping stage is used. In this stage, first number and length of chromosome are determined. These values may be constant are varied for every round. Reshape it by align the DNA sequence into rows to construct parents’ chromosomes (chromosome population) with pre-defined length. 39 | 40 |

Crossover Stage:

41 | 42 | After constructing parents’ chromosomes, the next operation is crossover. There are two types of crossover. These may be sequentially used in technique rounds. In the first one, the parents are selected in the mating pool. A single-point crossover point is selected between the first and last bits of the parents’ chromosomes then, creating two new offspring by exchanging the heads of parent1 and parent2. Consequently the offspring containportions of the DNA codes of both parents 43 | 44 |

Mutation Stage:

45 | 46 | After crossover process, the chromosomes are 47 | subjected to mutation. Mutation is the alteration of string elements. Two types of mutation are used. In the first one, convert data to binary vector and define two mutation points between the first and last bits then complement bits in between i.e. single point mutation changes a 1 to a 0, and vice versa. In the second mutation type, convert each four bits to two bases of DNA (1010 -> CG). After conversion, reshape it to DNA bases vector and define two points between the first and last bases then alter DNA bases to another one (i.e., C -> G). 48 | 49 | INPUT: A normal text 50 | 51 | OUTPUT: Encryption and decryption of data using DNA-Genetic Encryption Technique 52 | 53 |

EVALUATION RESULTS:

54 | 55 | The D-GET is implemented in the AMD Athlon(tm) II X2 220 Processor, 2.80GHz and 4 GB RAM on Windows 8.1 64-BIT operating system. We conduct experiments to test the efficacy of the proposed technique and run it with various types of secret data. 56 | Using all manner of cryptanalytic, mathematical and brute-force attacks, cryptanalysts attack any encrypted data to discover its contents. A successful encryption technique against them should be robust. So, there are some features that need to be achieved. Here There is no relationship between, before encryption, sensitive data values and, after encryption, encrypted data values. Encryption should be blended around the various hidden data components so that nothing in its original position is presented. 57 | 58 | ![dna2](https://user-images.githubusercontent.com/53599318/99867007-f6993500-2bdb-11eb-96f6-4fbc7a878cf5.jpg) 59 | 60 |

CONCLUSIONS:

61 | 62 | D-GET is implemented in this project. The D-GET, based on multi-iteration and genetic activities, is a more stable encryption technique. Operations, encryption, rotation, crossover, mutation, and reshapes that improve the standard of encryption are also included. D-GET operations and modifications to the original data size and format. In addition, the negligible relationship in both the hidden data and its encrypted data decreases the possibilities of cryptanalysis and breaking the cypher. In addition, the technique has multilayer defence phases that achieve confidentiality and provide data with more security, productivity and robustness and protects against detection. We would standardise D-GET in future work and try to minimise transmission 63 | 64 | -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/dna_gdt.py: -------------------------------------------------------------------------------- 1 | """ 2 | DNA Genetic Decryption Technique 3 | """ 4 | from time import time 5 | import ast 6 | 7 | import utils 8 | from utils import * 9 | 10 | 11 | def encrypt_key(data, key): 12 | """ 13 | Encrypt data with key: data XOR key. 14 | """ 15 | 16 | # repeat key ONLY if data is longer than key and encrypt 17 | if len(data) > len(key): 18 | factor = int(len(data) / len(key)) 19 | key += key * factor 20 | 21 | return bitxor(data, key) 22 | 23 | return bitxor(data, key) 24 | 25 | 26 | def reshape(dna_sequence, reshape_info): 27 | """ 28 | Generate chromosome population. 29 | :param dna_sequence: a string sequence of DNA bases 30 | :param reshape_info: the length of each chromosome 31 | :return: an array of chromosomes, chromosome population 32 | """ 33 | 34 | chromosome_length = int(reshape_info[0]) 35 | chromosomes = [] 36 | 37 | # retrieve the population 38 | for i in range(0, len(dna_sequence), chromosome_length): 39 | chromosomes.append(dna_sequence[i:i + chromosome_length]) 40 | 41 | return chromosomes 42 | 43 | 44 | def reverse_reshape(population): 45 | # convert the chromosome population back to DNA sequence 46 | return "".join(population) 47 | 48 | 49 | def rotate_crossover(population, rotate_info): 50 | """ 51 | Rotate every chromosome in population left / right according to probability p. 52 | """ 53 | 54 | new_population = [] 55 | 56 | # get the rotation value 57 | rotation_offset = int(get_pattern(rotation_offset_del, rotate_info)[0]) 58 | 59 | rotations = get_pattern(rotation_types_del, rotate_info)[0].split("|")[:-1] 60 | 61 | for i in range(len(population)): 62 | chromosome = population[i] 63 | 64 | direction = rotations[i] 65 | 66 | if direction == "left": 67 | right_first = chromosome[0: len(chromosome) - rotation_offset] 68 | right_second = chromosome[len(chromosome) - rotation_offset:] 69 | new_population.append(right_second + right_first) 70 | elif direction == "right": 71 | left_first = chromosome[0: rotation_offset] 72 | left_second = chromosome[rotation_offset:] 73 | new_population.append(left_second + left_first) 74 | 75 | return new_population 76 | 77 | 78 | def single_point_crossover(population, single_point_info): 79 | """ 80 | Combine each two chromosomes in population by using single point crossover. 81 | """ 82 | crossover_points = [int(p) for p in single_point_info.split("|") if p != ''] 83 | 84 | new_population = [] 85 | for i in range(0, len(population) - 1, 2): 86 | candidate1 = population[i] 87 | candidate2 = population[i + 1] 88 | 89 | # get the crossover_point 90 | crossover_point = crossover_points[int(i / 2)] 91 | 92 | offspring1 = candidate2[0: crossover_point] + candidate1[crossover_point:] 93 | offspring2 = candidate1[0: crossover_point] + candidate2[crossover_point:] 94 | new_population.append(offspring1) 95 | new_population.append(offspring2) 96 | 97 | # append last chromosome if odd population size 98 | if len(population) % 2 == 1: 99 | new_population.append(population[len(population) - 1]) 100 | 101 | return new_population 102 | 103 | 104 | def crossover(population, crossover_info): 105 | # get the crossover type 106 | crossover_type = get_pattern(crossover_type_del, crossover_info)[0] 107 | 108 | if crossover_type == "rotate_crossover": 109 | rotate_info = get_pattern(rotate_crossover_del, crossover_info)[0] 110 | return rotate_crossover(population, rotate_info) 111 | elif crossover_type == "single_point_crossover": 112 | single_point_info = get_pattern(single_point_crossover_del, crossover_info)[0] 113 | return single_point_crossover(population, single_point_info) 114 | elif crossover_type == "both": 115 | rotate_info = get_pattern(rotate_crossover_del, crossover_info)[0] 116 | single_point_info = get_pattern(single_point_crossover_del, crossover_info)[0] 117 | population = single_point_crossover(population, single_point_info) 118 | return rotate_crossover(population, rotate_info) 119 | 120 | 121 | def complement(chromosome, point1, point2): 122 | """ 123 | Flip chromosome bits between point1 and point2. 124 | """ 125 | new_chromosome = "" 126 | 127 | for i in range(len(chromosome)): 128 | if i >= point1 and i <= point2: 129 | if chromosome[i] == '0': 130 | new_chromosome += '1' 131 | else: 132 | new_chromosome += '0' 133 | else: 134 | new_chromosome += chromosome[i] 135 | 136 | return new_chromosome 137 | 138 | 139 | def mutation(population, mutation_info): 140 | """ 141 | Apply mutation operator by using "complement" and "alter_dna_bases" 142 | """ 143 | 144 | # extract the alteration table 145 | alter_dna_table = ast.literal_eval(get_pattern(mutation_table_del, mutation_info[0])[0]) 146 | 147 | chromosomes_info = get_pattern(chromosome_del, mutation_info[0]) 148 | 149 | new_population = [] 150 | for i in range(len(population)): 151 | chromosome = population[i] 152 | chromosome_info = chromosomes_info[i] 153 | 154 | # alter back the dna bases between point1 and point2 155 | alter_info = get_pattern(alter_mutation_del, chromosome_info)[0] 156 | point1, point2 = ast.literal_eval(alter_info) 157 | new_chromosome = "" 158 | for i in range(len(chromosome)): 159 | if i >= point1 and i <= point2: 160 | new_chromosome += alter_dna_table[chromosome[i]] 161 | else: 162 | new_chromosome += chromosome[i] 163 | 164 | two_bases_vector = group_bases(new_chromosome) 165 | 166 | # last base was not converted using four_bits_to_two_dna_base_table 167 | # convert it to bits using dna_base_to_two_bits_table 168 | last_two_bits = None 169 | if len(new_chromosome) % 2 == 1: 170 | last_two_bits = utils.dna_base_to_two_bits_table[new_chromosome[-1]] 171 | 172 | two_bases_vector = two_bases_vector[:-1] 173 | 174 | bits_seq = dna_to_bits(two_bases_vector, utils.two_dna_base_to_four_bits_table) 175 | 176 | if last_two_bits is not None: 177 | bits_seq += last_two_bits 178 | 179 | complement_info = get_pattern(complement_mutation_del, chromosome_info)[0] 180 | point1, point2 = ast.literal_eval(complement_info) 181 | b_chromosome = complement(bits_seq, point1, point2) 182 | b_chromosome = group_bits(b_chromosome) 183 | new_chromosome = bits_to_dna(b_chromosome, utils.two_bits_to_dna_base_table) 184 | 185 | new_population.append(new_chromosome) 186 | 187 | return new_population 188 | 189 | 190 | def dna_gdt(text, key): 191 | print("\nDNA-GDT is running...\n") 192 | 193 | rounds_no = int(get_pattern(no_rounds_del, key)[0]) 194 | rounds = get_pattern(round_del, key) 195 | 196 | b_data = text 197 | print("Initial DNA sequence:", b_data) 198 | 199 | # run the algorithm "rounds_no" times 200 | while rounds_no > 0: 201 | round_info = rounds[rounds_no - 1] 202 | 203 | # create the chromosome population 204 | b_data = reshape(b_data, get_pattern(reshape_del, round_info)) 205 | # print("Population data:", b_data) 206 | 207 | # apply mutation on population 208 | b_data = mutation(b_data, get_pattern(mutation_del, round_info)) 209 | # print("Population data:", b_data) 210 | 211 | # apply crossover on population 212 | b_data = crossover(b_data, round_info) 213 | # print("Population data:", b_data) 214 | 215 | # decrypt data with key after reshaping it back to binary sequence and then convert it back to dna sequence 216 | # where decrypt = encrypt(encrypt(data, key), key) and encrypt => xor operation, because (a xor b) xor b = a 217 | encryption_key = get_pattern(key_del, key)[0] 218 | b_data = bits_to_dna( 219 | group_bits( 220 | encrypt_key(dna_to_bits(reverse_reshape(b_data), utils.dna_base_to_two_bits_table), encryption_key)), 221 | utils.two_bits_to_dna_base_table) 222 | # print("Decrypted data:", b_data) 223 | 224 | rounds_no -= 1 225 | 226 | return bin2str(dna_to_bits(b_data, utils.dna_base_to_two_bits_table)).decode() 227 | 228 | 229 | def main(): 230 | original_file = open(original_filename, "r") 231 | encrypted_file = open(encrypted_filename, "r") 232 | decrypted_file = open(decrypted_filename, "w") 233 | key_file = open(key_filename, "r") 234 | 235 | original_text = original_file.read() 236 | encrypted_text = encrypted_file.read() 237 | key = key_file.read() 238 | 239 | print("Encrypted text:", encrypted_text) 240 | print("Key:", key) 241 | 242 | # generate the encoding tables 243 | generate_pre_processing_tables() 244 | generate_mutation_tables() 245 | 246 | # get the decrypted text 247 | start = time() 248 | decrypted_text = dna_gdt(encrypted_text, key) 249 | print("Decrypted text:", decrypted_text) 250 | decrypted_file.write(decrypted_text) 251 | end = time() 252 | 253 | print("\nTotal execution time:", end - start) 254 | 255 | if original_text != decrypted_text: 256 | print("\nDecryption failed.") 257 | else: 258 | print("\nDecryption succeeded.") 259 | 260 | original_file.close() 261 | encrypted_file.close() 262 | decrypted_file.close() 263 | key_file.close() 264 | 265 | 266 | if __name__ == '__main__': 267 | main() 268 | -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/dna_get.py: -------------------------------------------------------------------------------- 1 | """ 2 | DNA Genetic Encryption Technique 3 | """ 4 | import string 5 | from time import time 6 | 7 | import utils 8 | from utils import * 9 | 10 | # number of rounds the algorithm is run, chosen randomly 11 | rounds_no = None 12 | 13 | chromosome_length = None 14 | 15 | # the key used in the decryption process 16 | decryption_key = None 17 | 18 | 19 | def set_globals(): 20 | global rounds_no 21 | global decryption_key 22 | # it is better to be odd random 23 | rounds_no = random.randrange(3, 12, 2) 24 | decryption_key = "" 25 | 26 | 27 | def encrypt_key(data, key): 28 | """ 29 | Encrypt data with key: data XOR key. 30 | """ 31 | 32 | # repeat key ONLY if data is longer than key and encrypt 33 | if len(data) > len(key): 34 | factor = int(len(data) / len(key)) 35 | key += key * factor 36 | 37 | return bitxor(data, key) 38 | 39 | return bitxor(data, key) 40 | 41 | 42 | def reshape(dna_sequence): 43 | """ 44 | Generate chromosome population. 45 | :param dna_sequence: a string sequence of DNA bases 46 | :return: an array of chromosomes, chromosome population 47 | """ 48 | global chromosome_length 49 | global decryption_key 50 | 51 | # choose population size and chromosome length 52 | divs = divisors(len(dna_sequence)) 53 | chromosome_no = divs[random.randint(0, len(divs) - 1)] 54 | chromosome_length = int(len(dna_sequence) / chromosome_no) 55 | chromosomes = [] 56 | 57 | decryption_key += reshape_del + str(chromosome_length) + reshape_del 58 | 59 | # retrieve the population 60 | for i in range(0, len(dna_sequence), chromosome_length): 61 | chromosomes.append(dna_sequence[i:i + chromosome_length]) 62 | 63 | return chromosomes 64 | 65 | 66 | def reverse_reshape(population): 67 | # convert the chromosome population back to DNA sequence 68 | return "".join(population) 69 | 70 | 71 | def rotate_crossover(population): 72 | """ 73 | Rotate every chromosome in population left / right according to probability p. 74 | """ 75 | global chromosome_length 76 | global decryption_key 77 | 78 | new_population = [] 79 | 80 | decryption_key += rotate_crossover_del 81 | 82 | # predefined rotation value, varied every round 83 | rotation_offset = random.randint(1, chromosome_length) 84 | 85 | decryption_key += rotation_offset_del + str(rotation_offset) + rotation_offset_del 86 | 87 | decryption_key += rotation_types_del 88 | 89 | for chromosome in population: 90 | 91 | p = random.uniform(0, 1) 92 | 93 | if p > 0.5: 94 | decryption_key += "right|" 95 | right_first = chromosome[0: len(chromosome) - rotation_offset] 96 | right_second = chromosome[len(chromosome) - rotation_offset:] 97 | new_population.append(right_second + right_first) 98 | else: 99 | decryption_key += "left|" 100 | left_first = chromosome[0: rotation_offset] 101 | left_second = chromosome[rotation_offset:] 102 | new_population.append(left_second + left_first) 103 | 104 | decryption_key += rotation_types_del 105 | 106 | decryption_key += rotate_crossover_del 107 | 108 | return new_population 109 | 110 | 111 | def single_point_crossover(population): 112 | """ 113 | Combine each two chromosomes in population by using single point crossover. 114 | """ 115 | global decryption_key 116 | 117 | decryption_key += single_point_crossover_del 118 | 119 | new_population = [] 120 | for i in range(0, len(population) - 1, 2): 121 | candidate1 = population[i] 122 | candidate2 = population[i + 1] 123 | 124 | # chromosomes have the same length 125 | # choose a random point 126 | length = len(candidate1) 127 | crossover_point = random.randint(0, length - 1) 128 | 129 | decryption_key += str(crossover_point) + "|" 130 | 131 | offspring1 = candidate2[0: crossover_point] + candidate1[crossover_point:] 132 | offspring2 = candidate1[0: crossover_point] + candidate2[crossover_point:] 133 | new_population.append(offspring1) 134 | new_population.append(offspring2) 135 | 136 | # append last chromosome if odd population size 137 | if len(population) % 2 == 1: 138 | new_population.append(population[len(population) - 1]) 139 | 140 | decryption_key += single_point_crossover_del 141 | 142 | return new_population 143 | 144 | 145 | def crossover(population): 146 | global decryption_key 147 | 148 | # choose crossover type according to p 149 | p = random.uniform(0, 1) 150 | 151 | if p < 0.33: 152 | decryption_key += crossover_type_del + "rotate_crossover" + crossover_type_del 153 | return rotate_crossover(population) 154 | elif p >= 0.33 and p < 0.66: 155 | decryption_key += crossover_type_del + "single_point_crossover" + crossover_type_del 156 | return single_point_crossover(population) 157 | else: 158 | decryption_key += crossover_type_del + "both" + crossover_type_del 159 | population = rotate_crossover(population) 160 | return single_point_crossover(population) 161 | 162 | 163 | def complement(chromosome, point1, point2): 164 | """ 165 | Flip chromosome bits between point1 and point2. 166 | """ 167 | new_chromosome = "" 168 | 169 | for i in range(len(chromosome)): 170 | if i >= point1 and i <= point2: 171 | if chromosome[i] == '0': 172 | new_chromosome += '1' 173 | else: 174 | new_chromosome += '0' 175 | else: 176 | new_chromosome += chromosome[i] 177 | 178 | return new_chromosome 179 | 180 | 181 | def alter_dna_bases(bases): 182 | """ 183 | Alter DNA bases to another one randomly.(e.g. C->G and A->T and viceversa) 184 | """ 185 | alter_dna_table = {} 186 | 187 | for _ in range(2): 188 | # choose one randomly then remove it from list 189 | base1 = bases[random.randint(0, len(bases) - 1)] 190 | bases.remove(base1) 191 | 192 | # choose one randomly then remove it from list 193 | base2 = bases[random.randint(0, len(bases) - 1)] 194 | bases.remove(base2) 195 | 196 | # assign the first to the other 197 | alter_dna_table[base1] = base2 198 | alter_dna_table[base2] = base1 199 | 200 | return alter_dna_table 201 | 202 | 203 | def mutation(population): 204 | """ 205 | Apply mutation operator by using "complement" and "alter_dna_bases" 206 | """ 207 | global decryption_key 208 | 209 | bases = ['A', 'C', 'G', 'T'] 210 | alter_dna_table = alter_dna_bases(bases) 211 | 212 | decryption_key += mutation_table_del + str(alter_dna_table) + mutation_table_del 213 | 214 | new_population = [] 215 | for chromosome in population: 216 | decryption_key += chromosome_del 217 | 218 | # apply the complement 219 | b_chromosome = dna_to_bits(chromosome, utils.dna_base_to_two_bits_table) 220 | decryption_key += complement_mutation_del 221 | point1 = random.randint(0, len(b_chromosome) - 1) 222 | point2 = random.randint(point1, len(b_chromosome) - 1) 223 | decryption_key += "(%s, %s)" % (point1, point2) 224 | decryption_key += complement_mutation_del 225 | b_chromosome = complement(b_chromosome, point1, point2) 226 | 227 | # convert each 4 bits in chromosome to two dna bases using four_bits_to_two_dna_base_table 228 | four_bits_vector = group_bits(b_chromosome, 4) 229 | 230 | last_dna_base = None 231 | # if the last element is of length 2, don't convert it 232 | if len(four_bits_vector[len(four_bits_vector) - 1]) == 2: 233 | last_dna_base = utils.two_bits_to_dna_base_table[four_bits_vector[len(four_bits_vector) - 1]] 234 | 235 | # convert only the 4 bits elements 236 | four_bits_vector = four_bits_vector[:-1] 237 | 238 | dna_seq = bits_to_dna(four_bits_vector, utils.four_bits_to_two_dna_base_table) 239 | if last_dna_base is not None: 240 | dna_seq += last_dna_base 241 | 242 | # and then alter the dna bases between point1 and point2 243 | decryption_key += alter_mutation_del 244 | point1 = random.randint(0, len(dna_seq) - 1) 245 | point2 = random.randint(point1, len(dna_seq) - 1) 246 | decryption_key += "(%s, %s)" % (point1, point2) 247 | decryption_key += alter_mutation_del 248 | new_chromosome = "" 249 | for i in range(len(dna_seq)): 250 | if i >= point1 and i <= point2: 251 | new_chromosome += alter_dna_table[dna_seq[i]] 252 | else: 253 | new_chromosome += dna_seq[i] 254 | 255 | new_population.append(new_chromosome) 256 | 257 | decryption_key += chromosome_del 258 | 259 | return new_population 260 | 261 | 262 | def dna_get(text, key): 263 | global rounds_no 264 | global decryption_key 265 | 266 | print("\nDNA-GET is running...\n") 267 | 268 | # binarize data and convert it to dna sequence 269 | b_data1 = binarized_data(text) 270 | dna_seq = bits_to_dna(b_data1, utils.two_bits_to_dna_base_table) 271 | # print(dna_seq) 272 | 273 | # there is no need for first reshape like in the pseudocode because my reverse_reshape can work on dna_seq, too 274 | # i.e. ("".join("ACGT") -> "ACGT") 275 | 276 | b_data2 = dna_seq 277 | print("Initial DNA sequence:", dna_seq) 278 | 279 | decryption_key += no_rounds_del + str(rounds_no) + no_rounds_del 280 | 281 | # run the algorithm "rounds_no" times 282 | while rounds_no > 0: 283 | decryption_key += round_del 284 | 285 | # encrypt data with key after reshaping it back to binary sequence and then convert it back to dna sequence 286 | b_data2 = bits_to_dna( 287 | group_bits(encrypt_key(dna_to_bits(reverse_reshape(b_data2), utils.dna_base_to_two_bits_table), key)), 288 | utils.two_bits_to_dna_base_table) 289 | # print("Encrypted data:", b_data2) 290 | 291 | # create the chromosome population 292 | b_data2 = reshape(b_data2) 293 | # print("Population data:", b_data2) 294 | 295 | # apply crossover on population 296 | decryption_key += crossover_del 297 | b_data2 = crossover(b_data2) 298 | decryption_key += crossover_del 299 | # print("Population data:", b_data2) 300 | 301 | # apply mutation on population 302 | decryption_key += mutation_del 303 | b_data2 = mutation(b_data2) 304 | decryption_key += mutation_del 305 | # print("Population data:", b_data2) 306 | 307 | rounds_no -= 1 308 | 309 | decryption_key += round_del 310 | 311 | return reverse_reshape(b_data2) 312 | 313 | 314 | def main(): 315 | global decryption_key 316 | 317 | original_file = open(original_filename, "w") 318 | 319 | text = "In computer science and operations research, a genetic algorithm (GA) is a metaheuristic inspired by the " \ 320 | "process of natural selection that belongs to the larger class of evolutionary algorithms (EA)." 321 | 322 | # used for evaluate performance to generate random text of any length 323 | # text = ''.join( 324 | # random.SystemRandom().choice(string.ascii_letters + string.digits + string.punctuation + string.whitespace) for 325 | # _ in range(5000)) 326 | 327 | print("Text:", text) 328 | 329 | original_file.write(text) 330 | 331 | # generate random key(it can have any length, could be the length of the plaintext) 332 | # in this case, I used 128 bit key 333 | key = str2bin(''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16))) 334 | 335 | print("Key:", len(key), key) 336 | 337 | # set initial values of global variables 338 | set_globals() 339 | 340 | # append the key first 341 | decryption_key += key_del + key + key_del 342 | 343 | # generate the encoding tables 344 | generate_pre_processing_tables() 345 | generate_mutation_tables() 346 | 347 | # get the ciphertext 348 | start = time() 349 | encrypted_text = dna_get(text, key) 350 | print("Final DNA sequence:", encrypted_text) 351 | end = time() 352 | 353 | print("\nTotal execution time:", end - start) 354 | 355 | key_file = open(key_filename, "w") 356 | encrypted_file = open(encrypted_filename, "w") 357 | 358 | # save the encryption to a file to be used in the decryption process 359 | encrypted_file.write(encrypted_text) 360 | 361 | # save key to a file to be read in the decryption process 362 | key_file.write(decryption_key) 363 | 364 | encrypted_file.close() 365 | original_file.close() 366 | key_file.close() 367 | 368 | 369 | if __name__ == '__main__': 370 | main() 371 | -------------------------------------------------------------------------------- /DNA-Genetic-Encryption-Technique-master/key.txt: -------------------------------------------------------------------------------- 1 | 010001100100111101110000011001010100100001001001010101110100100001010101001101110111000001100011011100110110010101101111010100115398both81right|right|281|{'C': 'G', 'G': 'C', 'A': 'T', 'T': 'A'}(58, 244)(193, 282)(306, 563)(132, 256)4both4left|left|left|right|left|left|right|left|left|left|right|left|right|left|right|right|right|left|left|left|left|left|left|left|left|right|right|left|right|left|right|left|left|right|right|right|left|left|right|left|right|right|left|right|right|right|left|right|left|left|right|left|right|left|right|left|left|right|right|left|right|right|right|right|left|right|left|right|left|left|right|left|right|left|right|right|left|right|right|left|right|left|right|right|left|left|right|left|right|right|left|left|right|left|left|right|right|right|left|left|left|right|right|right|left|right|right|right|right|right|right|right|right|right|right|left|left|left|right|right|left|left|right|right|right|right|right|left|left|left|left|left|right|right|right|right|left|right|left|right|left|right|right|left|right|left|left|right|left|right|left|left|left|right|right|right|right|left|right|right|right|right|right|right|right|right|left|right|left|left|right|left|right|right|right|right|left|right|right|right|left|left|right|right|right|right|left|left|right|right|left|left|left|left|left|left|right|left|right|3|3|3|3|1|3|2|1|3|3|0|1|3|3|1|2|2|0|3|3|1|1|0|0|3|1|0|1|2|0|2|3|1|2|1|1|0|1|0|0|1|1|2|0|1|3|0|1|3|0|1|2|3|0|0|0|2|1|2|3|3|1|1|3|2|0|2|2|0|0|0|1|2|0|0|3|1|2|1|1|1|2|3|1|3|0|1|2|2|0|2|0|1|0|1|0|2|2|1|{'A': 'C', 'C': 'A', 'T': 'G', 'G': 'T'}(6, 6)(3, 3)(5, 5)(3, 3)(4, 6)(1, 2)(4, 6)(0, 0)(1, 7)(2, 2)(3, 7)(1, 1)(2, 2)(2, 3)(7, 7)(1, 1)(4, 5)(1, 3)(5, 6)(3, 3)(7, 7)(2, 2)(3, 3)(1, 2)(4, 6)(0, 3)(3, 6)(0, 0)(4, 5)(0, 0)(4, 7)(1, 2)(3, 7)(2, 3)(5, 5)(1, 1)(3, 4)(0, 1)(6, 6)(3, 3)(1, 4)(1, 1)(5, 7)(1, 2)(3, 6)(2, 3)(2, 3)(0, 2)(1, 1)(3, 3)(5, 5)(3, 3)(4, 5)(3, 3)(4, 7)(0, 3)(5, 5)(1, 2)(5, 5)(3, 3)(7, 7)(2, 2)(1, 3)(3, 3)(6, 6)(1, 1)(6, 7)(1, 1)(6, 7)(2, 2)(7, 7)(3, 3)(0, 5)(2, 3)(3, 6)(3, 3)(0, 4)(1, 3)(1, 1)(1, 1)(1, 4)(2, 2)(0, 0)(3, 3)(6, 7)(2, 3)(3, 3)(1, 2)(7, 7)(0, 0)(7, 7)(3, 3)(1, 1)(1, 1)(3, 5)(1, 3)(1, 7)(2, 3)(6, 6)(2, 2)(4, 4)(3, 3)(7, 7)(2, 3)(6, 6)(2, 3)(0, 4)(1, 1)(1, 5)(3, 3)(5, 5)(3, 3)(1, 5)(3, 3)(2, 7)(1, 3)(5, 6)(2, 3)(1, 5)(1, 1)(2, 5)(0, 0)(7, 7)(2, 3)(7, 7)(2, 3)(1, 4)(3, 3)(6, 7)(0, 1)(0, 4)(3, 3)(0, 1)(1, 2)(3, 3)(1, 2)(1, 4)(1, 3)(3, 3)(3, 3)(7, 7)(1, 3)(6, 7)(1, 3)(7, 7)(1, 2)(1, 4)(1, 1)(4, 6)(2, 2)(7, 7)(0, 3)(1, 4)(1, 1)(5, 5)(3, 3)(4, 5)(3, 3)(4, 4)(2, 3)(3, 5)(0, 0)(7, 7)(1, 2)(5, 6)(1, 1)(6, 6)(2, 2)(3, 5)(2, 2)(5, 5)(3, 3)(6, 6)(1, 3)(3, 5)(2, 3)(3, 5)(0, 1)(0, 6)(0, 0)(3, 6)(2, 2)(4, 5)(0, 2)(4, 6)(3, 3)(6, 6)(2, 3)(3, 6)(3, 3)(7, 7)(1, 1)(7, 7)(0, 2)(5, 6)(0, 0)(3, 5)(0, 0)(6, 6)(1, 1)(0, 3)(3, 3)(5, 5)(0, 0)(0, 3)(2, 3)(1, 3)(0, 0)(4, 5)(1, 2)(7, 7)(0, 1)(6, 6)(2, 3)(2, 2)(2, 3)(4, 4)(3, 3)(1, 5)(1, 2)(2, 3)(0, 3)(5, 6)(0, 2)(4, 5)(2, 2)(4, 7)(3, 3)(2, 4)(1, 3)(5, 7)(0, 0)(4, 7)(2, 3)(5, 7)(1, 3)(4, 5)(1, 1)(7, 7)(1, 3)(6, 7)(0, 0)(2, 5)(1, 1)(6, 7)(1, 1)(5, 7)(0, 3)(0, 3)(3, 3)(4, 6)(3, 3)(7, 7)(2, 2)(4, 6)(3, 3)(1, 4)(1, 2)(1, 5)(0, 0)(7, 7)(3, 3)(0, 3)(1, 2)(1, 3)(2, 2)(1, 2)(1, 3)(7, 7)(3, 3)(0, 6)(1, 3)(2, 4)(1, 2)(7, 7)(2, 3)(5, 5)(2, 2)(7, 7)(1, 2)(3, 5)(3, 3)(4, 6)(1, 3)(4, 7)(3, 3)(3, 3)(0, 2)(4, 4)(2, 2)(7, 7)(0, 1)(1, 6)(3, 3)(0, 5)(1, 1)(7, 7)(0, 0)(3, 4)(3, 3)(3, 7)(2, 3)(3, 6)(1, 3)(0, 1)(1, 1)(6, 7)(3, 3)(2, 3)(3, 3)(7, 7)(2, 3)(6, 7)(3, 3)(5, 7)(1, 3)(1, 5)(1, 3)(6, 6)(0, 2)(2, 4)(0, 0)(6, 7)(2, 2)(5, 6)(1, 1)(0, 2)(0, 1)(7, 7)(0, 0)(1, 1)(3, 3)(6, 6)(1, 2)(2, 2)(2, 2)(3, 7)(1, 1)(2, 3)(1, 3)(6, 6)(0, 0)(2, 4)(3, 3)(3, 3)(3, 3)(5, 7)(3, 3)(3, 7)(2, 2)(4, 4)(1, 2)(2, 5)(2, 2)(6, 6)(2, 3)(3, 3)(3, 3)(1, 2)(3, 3)(5, 7)(0, 2)(6, 6)(0, 0)(6, 7)(1, 3)(2, 7)(1, 3)(1, 3)(1, 2)(2, 5)(3, 3)(4, 4)(0, 0)(5, 7)(3, 3)(4, 5)(2, 3)(5, 7)(1, 3)(0, 1)(1, 2)(1, 4)(2, 2)(6, 7)(2, 2)(3, 7)(2, 2)(6, 7)(2, 2)(7, 7)(0, 1)(0, 4)(1, 2)(6, 7)(3, 3)(4, 6)(1, 2)199both61right|left|right|left|36|84|{'A': 'G', 'G': 'A', 'C': 'T', 'T': 'C'}(377, 384)(31, 135)(125, 375)(145, 189)(248, 351)(23, 60)(73, 150)(15, 20)398single_point_crossover122|{'T': 'A', 'A': 'T', 'G': 'C', 'C': 'G'}(487, 607)(196, 294)(307, 706)(392, 396)2both1right|left|right|right|left|left|right|right|right|left|left|left|left|right|left|left|right|right|right|left|left|left|left|right|left|left|right|right|left|left|left|right|right|left|right|right|right|right|left|right|right|left|left|left|right|right|right|left|left|right|right|left|left|right|right|left|left|right|right|right|right|right|left|right|left|right|left|left|left|right|left|left|right|right|right|right|right|right|left|left|left|right|right|right|right|left|left|right|left|left|right|right|right|right|left|left|right|right|right|left|right|left|left|left|left|left|left|right|left|left|left|right|right|left|right|right|left|right|left|right|right|right|left|right|left|right|right|right|left|right|left|right|right|left|right|right|right|right|left|right|right|right|left|left|right|right|left|left|right|left|left|left|left|left|right|right|right|left|right|right|left|left|right|left|right|right|left|left|left|left|right|left|left|left|right|left|right|right|left|right|right|left|left|right|left|left|left|right|right|left|left|left|right|left|right|left|right|left|left|right|left|right|left|right|right|left|right|right|right|left|left|left|left|left|left|left|left|right|right|left|right|left|left|left|left|left|right|right|right|left|right|left|left|right|right|left|left|right|left|right|left|right|right|right|left|left|left|left|left|right|left|left|left|left|left|right|left|left|left|right|left|right|left|right|right|left|right|right|left|right|left|left|right|left|right|right|right|right|left|right|right|left|right|left|left|left|left|left|right|left|right|right|right|left|left|right|left|right|left|right|left|left|left|left|right|left|left|right|right|right|right|left|left|right|left|right|left|left|left|right|left|right|right|left|left|left|left|left|right|left|left|right|right|left|left|left|left|left|right|right|right|left|right|left|right|left|left|right|left|right|right|left|right|right|right|left|right|left|left|left|left|right|right|left|left|right|left|right|left|right|left|left|left|left|right|left|right|left|left|right|right|left|right|right|left|right|left|right|left|left|left|left|left|left|right|left|left|right|0|0|1|0|1|0|1|1|0|0|1|1|1|1|1|1|1|1|1|1|1|0|1|1|1|0|0|1|0|0|1|0|0|0|0|1|0|1|0|1|0|1|0|1|0|1|0|0|1|1|1|1|0|0|1|0|1|1|0|0|0|1|1|0|1|0|0|0|1|1|0|1|0|0|1|1|1|0|1|0|0|1|1|0|0|0|0|0|0|1|1|0|1|0|1|0|0|0|0|1|0|1|1|1|1|0|0|1|1|1|1|1|0|0|0|0|1|1|0|1|1|1|0|1|1|1|0|0|0|1|1|1|1|1|1|1|1|0|0|1|1|0|1|0|1|1|0|0|0|1|1|0|0|0|0|0|1|1|1|0|0|1|1|0|0|1|1|0|0|1|1|1|1|1|0|1|0|1|0|0|1|0|1|0|1|0|1|0|1|1|1|1|1|0|1|0|1|0|1|{'C': 'G', 'G': 'C', 'T': 'A', 'A': 'T'}(2, 3)(0, 0)(0, 1)(1, 1)(2, 2)(1, 1)(2, 3)(0, 1)(2, 2)(1, 1)(1, 3)(0, 0)(2, 3)(0, 1)(1, 3)(1, 1)(1, 3)(1, 1)(1, 3)(0, 1)(0, 3)(1, 1)(0, 2)(0, 0)(1, 3)(1, 1)(1, 3)(0, 1)(1, 1)(1, 1)(3, 3)(0, 0)(0, 1)(0, 0)(3, 3)(1, 1)(3, 3)(0, 1)(2, 2)(0, 1)(0, 3)(0, 1)(3, 3)(1, 1)(2, 3)(1, 1)(0, 0)(0, 0)(2, 2)(0, 0)(3, 3)(1, 1)(0, 1)(0, 0)(0, 3)(1, 1)(0, 3)(0, 1)(3, 3)(0, 0)(3, 3)(1, 1)(2, 2)(0, 1)(3, 3)(1, 1)(1, 3)(1, 1)(3, 3)(0, 1)(3, 3)(0, 0)(1, 2)(0, 1)(2, 2)(1, 1)(1, 1)(0, 0)(3, 3)(1, 1)(2, 3)(1, 1)(0, 0)(1, 1)(0, 3)(0, 0)(0, 0)(1, 1)(1, 2)(1, 1)(0, 1)(0, 1)(3, 3)(1, 1)(2, 3)(1, 1)(0, 1)(0, 0)(0, 2)(1, 1)(2, 3)(0, 1)(1, 2)(0, 0)(0, 1)(1, 1)(3, 3)(1, 1)(3, 3)(1, 1)(2, 2)(1, 1)(3, 3)(1, 1)(2, 3)(1, 1)(2, 2)(0, 1)(3, 3)(1, 1)(0, 3)(1, 1)(0, 0)(1, 1)(1, 3)(1, 1)(0, 3)(1, 1)(2, 2)(1, 1)(1, 3)(0, 1)(0, 2)(0, 0)(2, 3)(1, 1)(3, 3)(1, 1)(2, 2)(0, 0)(1, 3)(1, 1)(2, 2)(0, 0)(0, 3)(1, 1)(1, 1)(0, 1)(1, 1)(0, 0)(1, 2)(0, 0)(2, 2)(1, 1)(0, 1)(0, 0)(3, 3)(1, 1)(3, 3)(1, 1)(3, 3)(0, 1)(0, 0)(0, 1)(2, 3)(0, 1)(1, 1)(0, 0)(2, 3)(0, 0)(0, 0)(0, 1)(3, 3)(0, 0)(2, 3)(1, 1)(1, 3)(0, 1)(3, 3)(0, 0)(3, 3)(0, 0)(0, 2)(0, 1)(0, 0)(1, 1)(0, 1)(1, 1)(0, 2)(1, 1)(0, 1)(0, 0)(1, 3)(0, 0)(0, 2)(0, 1)(0, 3)(1, 1)(2, 3)(0, 1)(2, 3)(1, 1)(1, 3)(1, 1)(0, 1)(1, 1)(2, 3)(0, 0)(1, 3)(0, 0)(3, 3)(1, 1)(0, 1)(0, 1)(2, 2)(1, 1)(1, 1)(0, 0)(3, 3)(0, 0)(1, 1)(0, 1)(0, 1)(1, 1)(2, 3)(1, 1)(2, 3)(0, 1)(3, 3)(1, 1)(1, 2)(1, 1)(2, 2)(1, 1)(0, 0)(0, 1)(3, 3)(0, 0)(2, 2)(0, 0)(0, 1)(1, 1)(2, 3)(1, 1)(1, 2)(1, 1)(0, 3)(0, 0)(0, 3)(1, 1)(3, 3)(0, 1)(3, 3)(1, 1)(3, 3)(0, 1)(2, 2)(0, 0)(1, 3)(0, 1)(3, 3)(1, 1)(0, 0)(1, 1)(2, 3)(0, 0)(2, 2)(1, 1)(0, 1)(0, 0)(3, 3)(0, 0)(3, 3)(1, 1)(3, 3)(0, 0)(1, 3)(1, 1)(0, 2)(0, 0)(0, 0)(1, 1)(2, 2)(0, 1)(0, 0)(0, 0)(1, 3)(0, 1)(1, 2)(0, 0)(0, 3)(0, 1)(2, 3)(1, 1)(3, 3)(1, 1)(1, 2)(1, 1)(2, 3)(0, 0)(0, 0)(0, 1)(0, 0)(1, 1)(3, 3)(1, 1)(3, 3)(0, 0)(0, 3)(1, 1)(1, 3)(1, 1)(1, 3)(1, 1)(0, 2)(1, 1)(0, 0)(1, 1)(2, 3)(0, 1)(3, 3)(1, 1)(0, 0)(1, 1)(2, 2)(0, 1)(1, 1)(0, 0)(0, 3)(0, 1)(3, 3)(0, 0)(3, 3)(0, 1)(0, 3)(0, 1)(2, 2)(0, 1)(1, 2)(1, 1)(1, 3)(1, 1)(0, 3)(1, 1)(0, 2)(0, 1)(0, 3)(0, 0)(0, 2)(0, 0)(0, 3)(1, 1)(1, 3)(1, 1)(1, 1)(0, 1)(1, 1)(1, 1)(1, 2)(1, 1)(2, 2)(1, 1)(3, 3)(1, 1)(0, 1)(1, 1)(3, 3)(1, 1)(0, 3)(0, 1)(3, 3)(1, 1)(2, 3)(0, 1)(2, 3)(0, 0)(3, 3)(1, 1)(2, 3)(1, 1)(3, 3)(0, 1)(3, 3)(0, 0)(1, 2)(1, 1)(1, 3)(0, 1)(3, 3)(1, 1)(1, 1)(0, 0)(3, 3)(0, 0)(3, 3)(1, 1)(3, 3)(0, 0)(3, 3)(1, 1)(0, 3)(1, 1)(0, 2)(0, 1)(1, 3)(0, 1)(1, 2)(0, 0)(0, 2)(0, 0)(2, 3)(0, 1)(1, 1)(1, 1)(1, 3)(1, 1)(2, 2)(0, 1)(1, 3)(0, 0)(2, 3)(1, 1)(3, 3)(0, 1)(0, 1)(1, 1)(3, 3)(1, 1)(1, 3)(1, 1)(3, 3)(1, 1)(2, 2)(0, 0)(1, 2)(0, 0)(0, 2)(1, 1)(1, 3)(1, 1)(0, 1)(1, 1)(3, 3)(1, 1)(0, 0)(1, 1)(2, 2)(1, 1)(1, 1)(0, 1)(1, 3)(0, 1)(2, 3)(1, 1)(0, 1)(1, 1)(3, 3)(0, 1)(0, 2)(1, 1)(2, 3)(0, 1)(0, 1)(1, 1)(3, 3)(1, 1)(2, 3)(0, 1)(0, 1)(0, 1)(0, 3)(1, 1)(3, 3)(0, 0)(1, 1)(1, 1)(3, 3)(1, 1)(2, 2)(1, 1)(2, 3)(0, 1)(2, 3)(1, 1)(2, 2)(1, 1)(3, 3)(0, 0)(2, 2)(1, 1)(0, 0)(0, 1)(2, 2)(0, 0)(0, 3)(1, 1)(2, 3)(0, 1)(2, 2)(1, 1)(2, 2)(1, 1)(2, 3)(0, 0)(0, 0)(1, 1)(0, 3)(0, 1)(0, 1)(0, 0)(3, 3)(1, 1)(2, 3)(0, 0)(2, 2)(1, 1)(1, 1)(0, 1)(2, 3)(0, 0)(3, 3)(1, 1)(1, 3)(0, 1)(0, 1)(1, 1)(2, 2)(0, 0)(2, 2)(0, 1)(2, 3)(1, 1)(2, 3)(1, 1)(0, 2)(0, 1)(1, 1)(1, 1)(1, 3)(1, 1)(3, 3)(1, 1)(3, 3)(1, 1)(1, 2)(1, 1)(0, 2)(0, 1)(1, 3)(0, 1)(1, 3)(1, 1)(2, 3)(1, 1)(3, 3)(1, 1)(1, 1)(0, 0)(2, 3)(1, 1)(0, 2)(0, 0)(2, 3)(1, 1)(0, 0)(1, 1)(2, 3)(1, 1)(2, 3)(0, 0)(1, 3)(0, 0)(2, 2)(0, 1)(2, 2)(1, 1)(1, 1)(0, 1)(0, 2)(0, 1)(2, 3)(0, 1)(2, 2)(0, 0)(2, 2)(0, 0)(2, 3)(1, 1)(0, 2)(0, 0)(0, 0)(1, 1)(0, 0)(1, 1)(0, 2)(1, 1)(3, 3)(0, 1)(2, 3)(0, 0)(1, 3)(1, 1)(3, 3)(1, 1)(3, 3)(1, 1)(3, 3)(0, 1)(3, 3)(0, 0)(2, 3)(0, 0)(1, 3)(0, 0)(0, 1)(0, 1)(3, 3)(0, 0)(3, 3)(0, 1)(0, 2)(0, 0)(3, 3)(1, 1)(0, 2)(1, 1)(0, 1)(0, 1)(1, 2)(0, 1)(3, 3)(1, 1)(1, 2)(1, 1)(3, 3)(1, 1)(0, 2)(0, 0)(1, 1)(0, 0)(1, 2)(1, 1)(3, 3)(1, 1)(0, 2)(1, 1)(0, 3)(0, 0)(2, 2)(1, 1)(3, 3)(1, 1)(2, 2)(0, 0)(3, 3)(0, 1)(3, 3)(0, 0)(1, 3)(1, 1)(0, 3)(1, 1)(1, 3)(1, 1)(0, 1)(0, 0)(2, 3)(0, 1)(0, 1)(1, 1)(2, 2)(0, 1)(3, 3)(1, 1)(0, 0)(0, 0)(1, 2)(0, 0)(3, 3)(1, 1)(3, 3)(1, 1)(2, 2)(1, 1)(2, 2)(1, 1)(0, 3)(1, 1)(3, 3)(0, 1)(1, 2)(0, 0)(2, 3)(1, 1)(0, 0)(1, 1)(3, 3)(0, 0)(3, 3)(0, 1)(1, 1)(0, 0)(3, 3)(0, 0)(2, 2)(0, 0)(0, 2)(0, 1)(1, 1)(0, 1)(3, 3)(1, 1)(1, 2)(0, 0)(1, 1)(0, 1)(0, 3)(0, 1)(3, 3)(1, 1)(3, 3)(1, 1)(3, 3)(1, 1)(1, 1)(0, 0)(2, 3)(0, 1)(1, 1)(1, 1)(2, 3)(1, 1)(0, 3)(0, 1)(3, 3)(1, 1)(1, 1)(0, 1)(0, 3)(0, 0)(1, 1)(1, 1)(1, 1)(1, 1)(3, 3)(1, 1)(2, 2)(0, 1)(1, 1)(1, 1)(0, 3)(0, 1)(2, 3)(0, 0)(0, 0)(1, 1)(0, 3)(0, 1)(1, 3)(0, 1)(2, 2)(1, 1)(2, 3)(0, 1)(3, 3)(1, 1)(2, 2)(1, 1)(2, 3)(0, 1)(0, 3)(0, 0)(3, 3)(1, 1)(2, 2)(0, 0)(2, 3)(0, 0)(0, 3)(1, 1)(0, 1)(1, 1)(2, 3)(1, 1)(2, 3)(1, 1)(3, 3)(0, 0)(1, 3)(1, 1)(2, 2)(0, 0)(1, 1)(1, 1)(2, 3)(1, 1) --------------------------------------------------------------------------------