Giải mã mật mã Caesar Python bằng khóa
Mật mã Caesar là một loại mật mã thay thế, trong đó mỗi chữ cái trong văn bản thuần túy được thay thế bằng một chữ cái khác ở một số vị trí cố định từ chữ cái hiện tại trong bảng chữ cái Show
Ví dụ: nếu chúng ta dịch chuyển mỗi chữ cái sang bên phải ba vị trí, mỗi chữ cái trong văn bản thuần túy của chúng ta sẽ được thay thế bằng một chữ cái ở ba vị trí bên phải của chữ cái trong văn bản thuần túy.
Vì vậy, chữ H sẽ được thay thế bằng K, E sẽ được thay thế bằng H, v.v. Tin nhắn được mã hóa cuối cùng cho HELLO WORLD sẽ là KHOOR ZRUOG. Điều vô nghĩa đó không có ý nghĩa, phải không? Lưu ý rằng các chữ cái trên cạnh i. e. , X, Y, Z quấn quanh và lần lượt được thay thế bởi A, B, C trong trường hợp dịch chuyển phải. Tương tự, các chữ cái ở đầu – A, B, C, v.v. sẽ được quấn xung quanh trong trường hợp thay đổi trái Quy tắc mã hóa Mật mã Caesar có thể được biểu diễn bằng toán học dưới dạng c = (x + n) % 26 Trong đó c là ký tự được mã hóa, x là ký tự thực và n là số vị trí chúng tôi muốn dịch chuyển ký tự x theo. Chúng tôi đang dùng mod với 26 vì có 26 chữ cái trong bảng chữ cái tiếng Anh Mật mã Caesar trong PythonTrước khi đi sâu vào việc xác định các hàm cho quy trình mã hóa và giải mã của Mật mã Caesar trong Python, trước tiên chúng ta sẽ xem xét hai hàm quan trọng mà chúng ta sẽ sử dụng rộng rãi trong quá trình này – chr() và ord(). Mỗi ký tự này được thể hiện trong bộ nhớ máy tính bằng một số gọi là mã ASCII (hoặc phần mở rộng của nó – Unicode) của ký tự, là một số 8 bit và mã hóa hầu hết tất cả các ký tự, chữ số của ngôn ngữ tiếng Anh, . Do nhu cầu kết hợp nhiều ký hiệu và ký tự của các ngôn ngữ khác phát sinh, 8 bit là không đủ nên tiêu chuẩn mới – Unicode – đã được thông qua, đại diện cho tất cả các ký tự được sử dụng trên thế giới bằng 16 bit. Chúng ta sẽ xem xét hai hàm tích hợp trong Python được sử dụng để tìm biểu diễn Unicode của một ký tự và ngược lại Hàm ord()Bạn có thể sử dụng phương thức ord() để chuyển đổi một ký tự thành biểu diễn số của nó trong Unicode. Nó chấp nhận một ký tự đơn và trả về số đại diện cho Unicode của nó. Hãy xem một ví dụ c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode) đầu ra Hàm chr()Giống như cách chúng ta có thể chuyển đổi một ký tự thành số Unicode của nó bằng phương thức ord(), chúng ta thực hiện nghịch đảo i. e. , tìm ký tự được đại diện bởi một số bằng phương thức chr(). character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360) đầu ra Lưu ý cách chữ cái tiếng Đức Ü (U sắc) cũng được biểu thị bằng số 360 trong Unicode Chúng ta cũng có thể áp dụng thao tác xâu chuỗi (ord theo sau là chr) để lấy lại ký tự ban đầu c = chr(ord("Ũ")) print(c) đầu ra. Ũ
Mã hóa cho chữ in hoaBây giờ chúng ta đã hiểu hai phương pháp cơ bản mà chúng ta sẽ sử dụng, hãy triển khai kỹ thuật mã hóa cho các chữ in hoa trong Python. Chúng tôi sẽ chỉ mã hóa các ký tự in hoa trong văn bản và sẽ giữ nguyên các ký tự còn lại.
Bây giờ chúng ta hãy nhìn vào mã shift = 3 # defining the shift count text = "HELLO WORLD" encryption = "" for c in text: # check if character is an uppercase letter if c.isupper(): # find the position in 0-25 c_unicode = ord(c) c_index = ord(c) - ord("A") # perform the shift new_index = (c_index + shift) % 26 # convert to new character new_unicode = new_index + ord("A") new_character = chr(new_unicode) # append to encrypted string encryption = encryption + new_character else: # since character is not uppercase, leave it as it is encryption += c print("Plain text:",text) print("Encrypted text:",encryption) đầu ra Như chúng ta có thể thấy, văn bản được mã hóa cho “HELLO WORLD” là “KHOOR ZRUOG” và nó khớp với văn bản mà chúng tôi đã truy cập theo cách thủ công trong phần Giới thiệu.
Giải mã cho chữ in hoaBây giờ chúng ta đã tìm ra cách mã hóa cho các chữ in hoa của văn bản thuần túy bằng Ceaser Cipher, hãy xem cách chúng ta sẽ giải mã bản mã thành văn bản thuần túy Trước đó, chúng ta đã xem xét công thức toán học của quá trình mã hóa. Bây giờ chúng ta hãy kiểm tra tương tự cho quá trình giải mã x = (c - n) % 26 Ý nghĩa của các ký hiệu vẫn giống như trong công thức trước. Chúng ta hãy xem quá trình thực hiện từng bước của quá trình giải mã, điều này ít nhiều sẽ ngược lại với quá trình mã hóa
Viết code cho thủ tục trên shift = 3 # defining the shift count encrypted_text = "KHOOR ZRUOG" plain_text = "" for c in encrypted_text: # check if character is an uppercase letter if c.isupper(): # find the position in 0-25 c_unicode = ord(c) c_index = ord(c) - ord("A") # perform the negative shift new_index = (c_index - shift) % 26 # convert to new character new_unicode = new_index + ord("A") new_character = chr(new_unicode) # append to plain string plain_text = plain_text + new_character else: # since character is not uppercase, leave it as it is plain_text += c print("Encrypted text:",encrypted_text) print("Decrypted text:",plain_text) đầu ra Lưu ý cách chúng tôi đã khôi phục thành công văn bản gốc “HELLO WORLD” từ dạng mã hóa của nó
Mã hóa số và dấu câuBây giờ chúng ta đã thấy cách chúng ta có thể mã hóa và giải mã các chữ in hoa của bảng chữ cái tiếng Anh bằng Mật mã Caesar, một câu hỏi quan trọng được đặt ra – Còn các ký tự khác thì sao? Chà, thuật toán Mật mã Caesar ban đầu không được phép xử lý bất kỳ thứ gì khác ngoài 26 chữ cái của bảng chữ cái – dù là chữ hoa hay chữ thường. Nhưng chúng ta luôn có thể mở rộng giải pháp tốt hiện có và điều chỉnh chúng cho phù hợp với nhu cầu của mình – điều đó đúng với bất kỳ loại thử thách nào trong công nghệ phần mềm. Đối với các số, chúng tôi có thể thực hiện mã hóa theo một trong hai cách
Chúng tôi sẽ triển khai giải pháp của mình bằng chiến lược đầu tiên. Ngoài ra, lần này, chúng tôi sẽ triển khai giải pháp của mình dưới dạng một hàm chấp nhận giá trị shift (đóng vai trò là khóa trong Mật mã Caesar) làm tham số. Giải pháp# The Encryption Function def cipher_encrypt(plain_text, key): encrypted = "" for c in plain_text: if c.isupper(): #check if it's an uppercase character c_index = ord(c) - ord('A') # shift the current character by key positions c_shifted = (c_index + key) % 26 + ord('A') c_new = chr(c_shifted) encrypted += c_new elif c.islower(): #check if its a lowecase character # subtract the unicode of 'a' to get index in [0-25) range c_index = ord(c) - ord('a') c_shifted = (c_index + key) % 26 + ord('a') c_new = chr(c_shifted) encrypted += c_new elif c.isdigit(): # if it's a number,shift its actual value c_new = (int(c) + key) % 10 encrypted += str(c_new) else: # if its neither alphabetical nor a number, just leave it like that encrypted += c return encrypted # The Decryption Function def cipher_decrypt(ciphertext, key): decrypted = "" for c in ciphertext: if c.isupper(): c_index = ord(c) - ord('A') # shift the current character to left by key positions to get its original position c_og_pos = (c_index - key) % 26 + ord('A') c_og = chr(c_og_pos) decrypted += c_og elif c.islower(): c_index = ord(c) - ord('a') c_og_pos = (c_index - key) % 26 + ord('a') c_og = chr(c_og_pos) decrypted += c_og elif c.isdigit(): # if it's a number,shift its actual value c_og = (int(c) - key) % 10 decrypted += str(c_og) else: # if its neither alphabetical nor a number, just leave it like that decrypted += c return decrypted Bây giờ chúng ta đã xác định hai chức năng của mình, trước tiên hãy sử dụng chức năng mã hóa để mã hóa một tin nhắn bí mật mà một người bạn đang chia sẻ qua tin nhắn văn bản cho bạn của anh ấy ________số 8đầu ra Lưu ý cách mọi thứ trừ dấu chấm câu và dấu cách đã được mã hóa Bây giờ chúng ta hãy xem một bản mã mà Đại tá Nick Fury đã gửi trên máy nhắn tin của anh ấy. ‘Sr xli gsyrx sj 7, 6, 5 – Ezirkivw Ewwiqfpi. ‘ ciphertext = "Sr xli gsyrx sj 7, 6, 5 - Ezirkivw Ewwiqfpi!" decrypted_msg = cipher_decrypt(ciphertext, 4) print("The cipher text:\n", ciphertext) print("The decrypted message is:\n",decrypted_msg) đầu ra Tốt lắm, Avengers Sử dụng bảng tra cứuỞ giai đoạn này, chúng tôi đã hiểu quy trình mã hóa và giải mã của Mật mã Caesar và đã triển khai tương tự trong Python Bây giờ chúng ta sẽ xem xét cách làm cho nó hiệu quả hơn và linh hoạt hơn. Chúng tôi cũng sẽ xem xét cách chúng tôi có thể điều chỉnh bất kỳ tập hợp ký hiệu nào do người dùng xác định chứ không chỉ các chữ cái trong bảng chữ cái trong quy trình mã hóa của chúng tôi. Bảng tra cứu là gì?Bảng tra cứu chỉ đơn giản là ánh xạ của các ký tự gốc và các ký tự mà chúng sẽ dịch sang dạng được mã hóa. Chúng ta có thể tránh điều này bằng cách tính toán vị trí thay đổi của từng ký tự trong bộ ký tự của chúng ta chỉ một lần trước khi bắt đầu quá trình mã hóa. Tạo bảng tra cứuMô-đun chuỗi của Python cung cấp một cách dễ dàng không chỉ để tạo bảng tra cứu mà còn để dịch bất kỳ chuỗi mới nào dựa trên bảng này Hãy lấy một ví dụ mà chúng ta muốn tạo một bảng gồm năm chữ cái viết thường đầu tiên và chỉ số của chúng trong bảng chữ cái. Chúng ta sẽ sử dụng hàm maketrans() của mô-đun str để tạo bảng. Hãy tạo một bảng cho một ví dụ đơn giản c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)0 Bảng là một từ điển Python có giá trị Unicode của các ký tự làm khóa và ánh xạ tương ứng của chúng làm giá trị. Hãy sử dụng phương pháp này để chuyển đổi văn bản của chúng tôi bằng bảng của chúng tôi c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)1 đầu ra Như bạn có thể thấy, mỗi trường hợp của năm chữ cái viết thường đầu tiên đã được thay thế bằng các chỉ số tương đối của chúng Bây giờ chúng ta sẽ sử dụng kỹ thuật tương tự để tạo bảng tra cứu cho Mật mã Caesar, dựa trên khóa được cung cấp Triển khai mã hóaHãy tạo một hàm caesar_cipher() chấp nhận một chuỗi sẽ được mã hóa/giải mã, 'bộ ký tự' cho biết ký tự nào trong chuỗi sẽ được mã hóa (hàm này sẽ mặc định là chữ thường), c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)2 Bây giờ đó là một chức năng mạnh mẽ ngoài kia Toàn bộ thao tác dịch chuyển đã được rút gọn thành thao tác cắt. Hãy xác thực xem điều này có hiệu quả hay không bằng cách sử dụng một ví dụ trước đó. c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)3 đầu ra Kiểm tra xem phần “KHOOR ZRUOG” khớp với mã hóa “HELLO WORLD” bằng khóa 3 như thế nào trong ví dụ đầu tiên của chúng tôi. Chúng tôi có thể kiểm tra xem quá trình giải mã có hoạt động bình thường hay không bằng cách sử dụng cùng một văn bản được mã hóa mà chúng tôi nhận được trong kết quả trước đó. c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)4 đầu ra Lưu ý cách chúng tôi đã đặt tham số 'giải mã' trong chức năng của mình thành True. Bây giờ, hãy xem liệu chúng ta có thể mở rộng bộ ký tự để bao gồm không chỉ các ký tự chữ thường/chữ hoa mà còn cả các chữ số và dấu chấm câu c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)5 đầu ra Ở đây chúng tôi đã bao gồm tất cả các ký tự mà chúng tôi đã thảo luận cho đến nay (bao gồm cả ký tự khoảng trắng) trong bộ ký tự sẽ được mã hóa.
chuyển dịch âmCho đến nay, chúng tôi đã thực hiện chuyển đổi 'tích cực' hoặc 'chuyển đổi phải' của các ký tự trong quy trình mã hóa. Và quá trình giải mã cho điều tương tự liên quan đến việc thực hiện dịch chuyển 'âm' hoặc 'dịch trái' của các ký tự. Hãy để chúng tôi thử điều này bằng cách sửa đổi chức năng trước đó của chúng tôi bằng cách thêm một tham số khác – ‘shift_type’ vào chức năng của chúng tôi cipher_cipher_using_lookup() c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)6 Hãy để chúng tôi kiểm tra phương pháp sửa đổi này trên một văn bản đơn giản c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)7 đầu ra Lưu ý cách mỗi ký tự trong văn bản thuần túy của chúng ta đã được dịch chuyển sang trái ba vị trí. c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)8 đầu ra Vì vậy, chúng tôi có thể mã hóa và giải mã văn bản bằng bảng tra cứu và khóa phủ định
mã hóa tập tinTrong phần này, chúng ta sẽ xem xét sử dụng Mật mã Caesar để mã hóa tệp.
Chúng ta sẽ sử dụng phương pháp thứ hai vì phương pháp đầu tiên chỉ khả thi đối với các tệp nhỏ có nội dung có thể dễ dàng phù hợp với bộ nhớ. c_unicode = ord("c") A_unicode = ord("A") print("Unicode of 'c' =", c_unicode) print("Unicode of 'A' =", A_unicode)9 Hàm chấp nhận tên tệp đầu vào, tên tệp đầu ra và các tham số mã hóa/giải mã mà chúng ta đã thấy trong phần trước Hãy mã hóa một tập tin ‘milky_way. txt‘ (có đoạn giới thiệu trang ‘Milky Way’ trên Wikipedia). Hãy mã hóa nó bằng chức năng chúng tôi đã xác định ở trên character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)0 đầu ra Hãy kiểm tra xem tệp được mã hóa của bạn 'milky_way được mã hóa như thế nào. txt‘ trông giống như bây giờ character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)1 Vì vậy, chức năng của chúng tôi mã hóa chính xác tệp. Đảm bảo rằng bạn không chuyển cùng một đường dẫn tệp cho cả đầu vào và đầu ra, điều này sẽ dẫn đến kết quả không mong muốn vì chương trình sẽ thực hiện đồng thời thao tác đọc và ghi trên cùng một tệp
Nhiều ca (Mật mã Vigenère)Cho đến nay, chúng tôi đã sử dụng một giá trị dịch chuyển duy nhất (phím) để dịch chuyển tất cả các ký tự của chuỗi theo cùng một số. của các vị trí. Ví dụ: giả sử chúng ta sử dụng một chuỗi gồm 4 phím. [1,5,2,3] Với phương pháp này, ký tự đầu tiên của chúng ta trong văn bản sẽ bị dịch chuyển một vị trí, ký tự thứ hai sẽ bị dịch chuyển năm vị trí, Hãy để chúng tôi thực hiện Mật mã Vigenère character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)2 Hàm thực hiện cả mã hóa và giải mã, tùy thuộc vào giá trị của tham số boolean 'decrypt'. Hãy để chúng tôi kiểm tra chức năng này bằng một văn bản thuần túy khác character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)3 đầu ra Ở đây, chúng tôi đang thực hiện mã hóa bằng các phím [1,2,3] và như mong đợi, ký tự đầu tiên 'w' đã được dịch chuyển một vị trí thành 'x',
Tại sao Mật mã Caesar lại yếu?Việc hiểu và triển khai Mật mã Caesar đơn giản như vậy, nó giúp mọi người dễ dàng tìm ra cách giải mã mà không tốn nhiều công sức. Nếu ai đó xác định tính đều đặn và khuôn mẫu trong sự xuất hiện của một số ký tự nhất định trong bản mã, họ sẽ nhanh chóng xác định rằng Mật mã Caesar đã được sử dụng để mã hóa văn bản.
Tấn công vũ phuViệc phá một bản mã được mã hóa bằng Mật mã Caesar chỉ là thử tất cả các khóa có thể. Ví dụ, nếu bản mã có tất cả chữ thường được mã hóa, tất cả những gì chúng ta phải làm là chạy bước giải mã với các giá trị khóa từ 0 đến 25. Hãy kiểm tra một bản mã có tất cả các ký tự chữ thường được mã hóa và xem liệu chúng ta có thể trích xuất một văn bản hợp lý từ nó bằng cách sử dụng một cuộc tấn công BruteForce hay không. character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)4 Trước tiên, hãy xác định chức năng giải mã chấp nhận bản mã và khóa, đồng thời giải mã tất cả các chữ cái viết thường của nó character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)5 Bây giờ chúng tôi có văn bản của mình, nhưng chúng tôi không biết phím i. e. , giá trị dịch chuyển. Hãy viết một cuộc tấn công Brute force, thử tất cả các khóa từ 0 đến 25 và hiển thị từng chuỗi được giải mã character_65 = chr(65) character_100 = chr(100) print("Unicode 65 represents", character_65) print("Unicode 100 represents", character_100) character_360 = chr(360) print("Unicode 360 represents", character_360)6 đầu ra Đầu ra liệt kê tất cả các chuỗi bạn có thể tạo từ quá trình giải mã. Bây giờ bạn đã biết cách phá văn bản mã hóa Caesar Cipher. Phần kết luậnTrong hướng dẫn này, chúng ta đã tìm hiểu Mật mã Caesar là gì, cách triển khai mã này trong Python dễ dàng như thế nào và cách triển khai mã này có thể được tối ưu hóa hơn nữa bằng cách sử dụng cái mà chúng tôi gọi là 'bảng tra cứu'. Sau đó, chúng tôi đã xem xét cách chúng tôi có thể mã hóa tệp bằng Mật mã Caesar và sau đó là cách Mật mã Caesar có thể được tăng cường bằng cách sử dụng nhiều ca.
Mokhtar Ebrahim Mokhtar là người sáng lập LikeGeek. com. Anh ấy làm quản trị viên hệ thống Linux từ năm 2010. Ông chịu trách nhiệm duy trì, bảo mật và khắc phục sự cố máy chủ Linux cho nhiều khách hàng trên khắp thế giới. Anh ấy thích viết các tập lệnh shell và Python để tự động hóa công việc của mình Làm cách nào để giải mã bản mã bằng Python?Mật mã với Python - Mật mã ngược . Mã hóa ngược sử dụng mô hình đảo ngược chuỗi văn bản thuần túy để chuyển thành văn bản mật mã Quá trình mã hóa và giải mã giống nhau Để giải mã bản mã, người dùng chỉ cần đảo ngược bản mã để lấy văn bản thuần túy Làm thế nào mật mã Caesar có thể bị bẻ khóa?Bởi vì chỉ có 25 khóa có thể, mật mã Caesar rất dễ bị tấn công "brute force", trong đó bộ giải mã chỉ cần thử từng tổ hợp chữ cái có thể có.
Bạn có thể brute force Caesar mật mã?Tấn công Brute-Force
. Đây không phải là một vụ hack phức tạp, nhưng thông qua nỗ lực tuyệt đối (mà máy tính sẽ làm thay chúng ta), mật mã Caesar có thể bị phá . |