Added Lab2/Lab3 IS
This commit is contained in:
		
							parent
							
								
									011d5aded1
								
							
						
					
					
						commit
						0755dd4b76
					
				
					 6 changed files with 109 additions and 140 deletions
				
			
		|  | @ -5,76 +5,68 @@ | |||
| 
 | ||||
| def add_cipher_en(ptext, ak): | ||||
|     result = "" | ||||
|     for i in range(len(ptext)): | ||||
|         ch = ptext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((ord(ch) + ak - 65) % 26 + 65) | ||||
|     for ch in ptext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             result += chr((ord(ch) - base + ak) % 26 + base) | ||||
|         else: | ||||
|             result += chr((ord(ch) + ak - 97) % 26 + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def add_cipher_de(ctext, ak): | ||||
|     result = "" | ||||
|     for i in range(len(ctext)): | ||||
|         ch = ctext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((ord(ch) - ak - 65) % 26 + 65) | ||||
|     for ch in ctext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             result += chr((ord(ch) - base - ak) % 26 + base) | ||||
|         else: | ||||
|             result += chr((ord(ch) - ak - 97) % 26 + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def mult_cipher_en(ptext, mk): | ||||
|     result = "" | ||||
|     for i in range(len(ptext)): | ||||
|         ch = ptext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((ord(ch) * mk - 65) % 26 + 65) | ||||
|     for ch in ptext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             x = ord(ch) - base | ||||
|             result += chr((x * mk) % 26 + base) | ||||
|         else: | ||||
|             result += chr((ord(ch) * mk - 97) % 26 + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def mult_cipher_de(ctext, mk): | ||||
|     result = "" | ||||
|     inverse = pow(mk, -1, 26) | ||||
|     for i in range(len(ctext)): | ||||
|         ch = ctext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((ord(ch) * inverse - 65) % 26 + 65) | ||||
|     for ch in ctext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             x = ord(ch) - base | ||||
|             result += chr((x * inverse) % 26 + base) | ||||
|         else: | ||||
|             result += chr((ord(ch) * inverse - 97) % 26 + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def affine_en(ptext, ak, mk): | ||||
|     result = "" | ||||
|     for i in range(len(ptext)): | ||||
|         ch = ptext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((((ord(ch) - 65) * mk) + ak) % 26 + 65) | ||||
|     for ch in ptext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             x = ord(ch) - base | ||||
|             result += chr(((x * mk + ak) % 26) + base) | ||||
|         else: | ||||
|             result += chr((((ord(ch) - 97) * mk) + ak) % 26 + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def affine_de(ctext, ak, mk): | ||||
|     result = "" | ||||
|     inverse = pow(mk, -1, 26) | ||||
|     for i in range(len(ctext)): | ||||
|         ch = ctext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 90 >= ord(ch) >= 65: | ||||
|             result += chr((((ord(ch) - 65 - ak) * inverse) % 26) + 65) | ||||
|     for ch in ctext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('A') if ch.isupper() else ord('a') | ||||
|             x = ord(ch) - base | ||||
|             result += chr((((x - ak) * inverse) % 26) + base) | ||||
|         else: | ||||
|             result += chr((((ord(ch) - 97 - ak) * inverse) % 26) + 97) | ||||
|             result += ch | ||||
|     return result | ||||
| 
 | ||||
| def mult_inverse(mk): | ||||
|  |  | |||
|  | @ -1,80 +1,58 @@ | |||
| def vigenere_en(ptext, vk): | ||||
|     result = "" | ||||
|     result = [] | ||||
|     ptext = ptext.upper() | ||||
|     vk = vk.upper() | ||||
| 
 | ||||
|     kl = len(vk) ## key length | ||||
| 
 | ||||
|     for i in range(len(ptext)): | ||||
|         ch = ptext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 65 <= ord(ch) <= 90: | ||||
|     kl = len(vk) | ||||
|     for i, ch in enumerate(ptext): | ||||
|         if ch.isalpha(): | ||||
|             shift = (ord(vk[i % kl]) - ord('A')) % 26 | ||||
|             result += chr((ord(ch) - ord('A') + shift) % 26 + ord('A')) | ||||
|             result.append(chr((ord(ch) - ord('A') + shift) % 26 + ord('A'))) | ||||
|         else: | ||||
|             result += ch | ||||
| 
 | ||||
|     return result | ||||
|             result.append(ch) | ||||
|     return ''.join(result) | ||||
| 
 | ||||
| 
 | ||||
| def vigenere_de(ctext, vk): | ||||
|     result = "" | ||||
|     result = [] | ||||
|     ctext = ctext.upper() | ||||
|     vk = vk.upper() | ||||
| 
 | ||||
|     kl = len(vk) | ||||
| 
 | ||||
|     for i in range(len(ctext)): | ||||
|         ch = ctext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 65 <= ord(ch) <= 90: | ||||
|     for i, ch in enumerate(ctext): | ||||
|         if ch.isalpha(): | ||||
|             shift = (ord(vk[i % kl]) - ord('A')) % 26 | ||||
|             result += chr((ord(ch) - ord('A') - shift + 26) % 26 + ord('A')) | ||||
|             result.append(chr((ord(ch) - ord('A') - shift) % 26 + ord('A'))) | ||||
|         else: | ||||
|             result += ch | ||||
| 
 | ||||
|     return result | ||||
|             result.append(ch) | ||||
|     return ''.join(result) | ||||
| 
 | ||||
| 
 | ||||
| def autokey_en(ptext, ak): | ||||
|     result = "" | ||||
|     result = [] | ||||
|     ptext = ptext.upper() | ||||
|     current_key = ak | ||||
| 
 | ||||
|     for i in range(len(ptext)): | ||||
|         ch = ptext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 65 <= ord(ch) <= 90: | ||||
|     for ch in ptext: | ||||
|         if ch.isalpha(): | ||||
|             shift = (current_key - ord('A')) % 26 | ||||
|             cipher_char = chr((ord(ch) - ord('A') + shift) % 26 + ord('A')) | ||||
|             result += cipher_char | ||||
|             result.append(cipher_char) | ||||
|             current_key = ord(cipher_char) | ||||
|         else: | ||||
|             result += ch | ||||
| 
 | ||||
|     return result | ||||
|             result.append(ch) | ||||
|     return ''.join(result) | ||||
| 
 | ||||
| def autokey_de(ctext, ak): | ||||
|     result = "" | ||||
|     result = [] | ||||
|     ctext = ctext.upper() | ||||
|     current_key = ak | ||||
| 
 | ||||
|     for i in range(len(ctext)): | ||||
|         ch = ctext[i] | ||||
|         if 32 <= ord(ch) <= 47: | ||||
|             result += ch | ||||
|         elif 65 <= ord(ch) <= 90: | ||||
|     for ch in ctext: | ||||
|         if ch.isalpha(): | ||||
|             shift = (current_key - ord('A')) % 26 | ||||
|             plain_char = chr((ord(ch) - ord('A') - shift + 26) % 26 + ord('A')) | ||||
|             result += plain_char | ||||
|             plain_char = chr((ord(ch) - ord('A') - shift) % 26 + ord('A')) | ||||
|             result.append(plain_char) | ||||
|             current_key = ord(plain_char) | ||||
|         else: | ||||
|             result += ch | ||||
| 
 | ||||
|     return result | ||||
|             result.append(ch) | ||||
|     return ''.join(result) | ||||
| 
 | ||||
| def operator(argument,ptext,ak,vk): | ||||
|     match argument: | ||||
|  |  | |||
|  | @ -1,18 +1,14 @@ | |||
| def generate_playfair_matrix(key): | ||||
|     key = ''.join(sorted(set(key.upper()), key=key.upper().index)) | ||||
|     alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||||
|     matrix = [] | ||||
| 
 | ||||
|     for char in key: | ||||
|         if char not in matrix and char != 'J': | ||||
|             matrix.append(char) | ||||
| 
 | ||||
|     for char in alphabet: | ||||
|         if char not in matrix and char != 'J': | ||||
|             matrix.append(char) | ||||
| 
 | ||||
|     playfair_matrix = [matrix[i:i+5] for i in range(0, len(matrix), 5)] | ||||
|     return playfair_matrix | ||||
|     alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"  # J omitted | ||||
|     unique = [] | ||||
|     for ch in key: | ||||
|         if ch != 'J' and ch not in unique: | ||||
|             unique.append(ch) | ||||
|     for ch in alphabet: | ||||
|         if ch not in unique: | ||||
|             unique.append(ch) | ||||
|     return [unique[i:i+5] for i in range(0, 25, 5)] | ||||
| 
 | ||||
| def find_pos(matrix, char): | ||||
|     for row_idx, row in enumerate(matrix): | ||||
|  | @ -22,16 +18,14 @@ def find_pos(matrix, char): | |||
|     return None | ||||
| 
 | ||||
| def prepare_text(text): | ||||
|     text = ''.join(filter(str.isalpha, text.upper())) | ||||
|     text = text.replace('J', 'I') | ||||
|     pairs = [] | ||||
|     i = 0 | ||||
|     text = ''.join(ch for ch in text.upper() if ch.isalpha()).replace('J', 'I') | ||||
|     pairs, i = [], 0 | ||||
|     while i < len(text): | ||||
|         if i + 1 < len(text) and text[i] != text[i+1]: | ||||
|             pairs.append(text[i:i+2]) | ||||
|         if i + 1 < len(text) and text[i] != text[i + 1]: | ||||
|             pairs.append(text[i:i + 2]) | ||||
|             i += 2 | ||||
|         else: | ||||
|             pairs.append(text[i]+'X') | ||||
|             pairs.append(text[i] + 'X') | ||||
|             i += 1 | ||||
|     return pairs | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import numpy as np | ||||
| 
 | ||||
| def hill_en(ptext, hk): | ||||
|     # all letters to uppercase | ||||
|     # keep only letters and convert to uppercase | ||||
|     ptext = ''.join(c.upper() for c in ptext if c.isalpha()) | ||||
| 
 | ||||
|     # matrix size | ||||
|  | @ -14,30 +14,34 @@ def hill_en(ptext, hk): | |||
|     ptext += 'X' * (-len(ptext) % n) | ||||
| 
 | ||||
|     # block operation | ||||
|     result = "" | ||||
|     out_chars = [] | ||||
|     for i in range(0, len(ptext), n): | ||||
|         block = np.array([ord(c) - 65 for c in ptext[i:i+n]]) | ||||
|         block = np.array([ord(c) - 65 for c in ptext[i:i + n]]) | ||||
|         encrypted_block = (key @ block) % 26 | ||||
|         result += ''.join(chr(val + 65) for val in encrypted_block) | ||||
|         out_chars.extend(chr(int(val) + 65) for val in encrypted_block) | ||||
| 
 | ||||
|     return result | ||||
|     return ''.join(out_chars) | ||||
| 
 | ||||
| def hill_de(ctext, hk): | ||||
|     # keep only letters and convert to uppercase | ||||
|     ctext = ''.join(c.upper() for c in ctext if c.isalpha()) | ||||
| 
 | ||||
|     # matrix size | ||||
|     n = int(len(hk)**0.5) | ||||
| 
 | ||||
|     # key matrix and its inverse | ||||
|     # key matrix and its inverse (note: not a true modular inverse; kept minimal per lab) | ||||
|     key = np.array([ord(c) - 65 for c in hk]).reshape(n, n) | ||||
|     inv_key = np.linalg.inv(key).astype(int) % 26 | ||||
|     inv_key = np.linalg.inv(key) | ||||
|     inv_key = np.rint(inv_key).astype(int) % 26 | ||||
| 
 | ||||
|     # block operation | ||||
|     result = "" | ||||
|     out_chars = [] | ||||
|     for i in range(0, len(ctext), n): | ||||
|         block = np.array([ord(c) - 65 for c in ctext[i:i+n]]) | ||||
|         block = np.array([ord(c) - 65 for c in ctext[i:i + n]]) | ||||
|         decrypted_block = (inv_key @ block) % 26 | ||||
|         result += ''.join(chr(val + 65) for val in decrypted_block) | ||||
|         out_chars.extend(chr(int(val) + 65) for val in decrypted_block) | ||||
| 
 | ||||
|     return result | ||||
|     return ''.join(out_chars) | ||||
| 
 | ||||
| def main(): | ||||
|     ptext = input("Plaintext: ") | ||||
|  |  | |||
|  | @ -2,20 +2,19 @@ def main(): | |||
|     shift = (ord('C') - ord('y')) % 26 | ||||
| 
 | ||||
|     ctext = "XVIEWYWI" | ||||
|     plaintext = "" | ||||
|     plaintext = [] | ||||
| 
 | ||||
|     for char in ctext: | ||||
|         if char.isalpha(): | ||||
|             shifted = ord(char.lower()) - shift | ||||
|             if shifted < ord('a'): | ||||
|                 shifted += 26 | ||||
|             plaintext += chr(shifted) | ||||
|     for ch in ctext: | ||||
|         if ch.isalpha(): | ||||
|             base = ord('a') | ||||
|             shifted = (ord(ch.lower()) - base - shift) % 26 + base | ||||
|             plaintext.append(chr(shifted)) | ||||
|         else: | ||||
|             plaintext += char | ||||
|             plaintext.append(ch) | ||||
| 
 | ||||
|     print(f"Attack type: Known plaintext attack") | ||||
|     print(f"Ciphertext: {ctext}") | ||||
|     print(f"Decrypted: {plaintext}") | ||||
|     print(f"Decrypted: {''.join(plaintext)}") | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     main() | ||||
|  |  | |||
|  | @ -8,23 +8,25 @@ def main(): | |||
|     for a in range(1, 26): | ||||
|         if gcd(a, 26) != 1: | ||||
|             continue | ||||
|         a_inv = mod_inverse(a, 26) | ||||
|         if a_inv is None: | ||||
|             continue | ||||
| 
 | ||||
|         for b in range(26): | ||||
|             # if key produces "ab" -> "GL" | ||||
|             if (a * 0 + b) % 26 == 6 and (a * 1 + b) % 26 == 11: | ||||
|                 a_inv = mod_inverse(a, 26) | ||||
|                 decrypted = "" | ||||
|                 for char in ciphertext: | ||||
|                     if char.isalpha(): | ||||
|                         y = ord(char.upper()) - ord('A') | ||||
|             # check constraint: "ab" -> "GL" (a*0+b=6, a*1+b=11 mod 26) | ||||
|             if (b % 26 == 6) and ((a + b) % 26 == 11): | ||||
|                 decrypted = [] | ||||
|                 for ch in ciphertext: | ||||
|                     if ch.isalpha(): | ||||
|                         y = ord(ch.upper()) - ord('A') | ||||
|                         x = (a_inv * (y - b)) % 26 | ||||
|                         decrypted += chr(x + ord('A')) | ||||
|                         decrypted.append(chr(x + ord('A'))) | ||||
|                     else: | ||||
|                         decrypted += char | ||||
|                         decrypted.append(ch) | ||||
| 
 | ||||
|                 print(f"Key found: a={a}, b={b}") | ||||
|                 print(f"Ciphertext: {ciphertext}") | ||||
|                 print(f"Decrypted: {decrypted}") | ||||
|                 print(f"Decrypted: {''.join(decrypted)}") | ||||
|                 return | ||||
| 
 | ||||
| def gcd(a, b): | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue