Bài tập mã hóa vigenere chi bản rõ năm 2024
https://reference.cs50.net/ - giải thích các chức năng thư viện được sử dụng trong quá trình đào tạo. Bằng tiếng Anh. http://computer.howstuffworks.com/c.htm trang 11 – 14 và 39 Sự chuẩn bị Đăng nhập vào cs50.io mkdir ~/workspace/pset2 Lưu ý rằng có khoảng cách giữa mkdir và ~/workspace/pset2 . Tóm lại, ~ có nghĩa là thư mục gốc, ~/workspace là một thư mục có tên là không gian làm việc bên trong thư mục gốc, ~/workspace/pset2 là một thư mục có tên pset2 bên trong ~/workspace . Bây giờ hãy chạy: cd ~/workspace/pset2 để thay đổi thư mục mới. Dòng lệnh trông giống như thế này: username:~/workspace/pset2 $ Nếu có gì sai, hãy lặp lại các bước. Bạn cũng có thể gọi một lệnh history để xem một số lệnh cuối cùng theo thứ tự thời gian. Bạn cũng có thể đặt con trỏ lên dòng lệnh và nhấn mũi tên lên trên bàn phím để xem tất cả các lệnh theo thứ tự từ lệnh được nhập cuối cùng đến lệnh đầu tiên. Sử dụng nút xuống, bạn có thể quay lại. Nhân tiện, thay vì mỗi lần gõ cùng một lệnh, bạn có thể cuộn qua các lệnh bạn đã gõ và thực hiện lại chúng bằng cách nhấn Enter. Bạn có thể nhận thấy rằng David thực hiện chính xác điều này trong các bài giảng của mình. Nhiệm vụ của tuần thứ hai sẽ được lưu trong pset2 . Nhiệm vụ 0. Khởi tạo Chúng ta hãy xem xét kỹ hơn các dòng. Trong tệpinits.c , hãy viết chương trình yêu cầu tên người dùng (sử dụng hàm GetString, chúng tôi lấy tên dưới dạng chuỗi) và sau đó hiển thị các chữ cái đầu tiên của tên (hoặc tên) và họ bằng chữ hoa không có dấu cách, dấu chấm hoặc các ký tự khác, chỉ với nguồn cấp dữ liệu dòng ( \n ). Chúng tôi giả định rằng người dùng chỉ nhập các chữ cái (chữ thường hoặc chữ hoa hoặc cả hai) cộng với một khoảng trắng giữa các từ. Hãy xem xét những kẻ tên Joseph Gordon-Levitt, Conan O'Brien hoặc David J. Malan sẽ không sử dụng chương trình. Để kiểm tra hoạt động chính xác của chương trình, hãy gọi check50: Bạn có muốn chơi thử việc thực hiện chương trình do nhân viên CS50 chuẩn bị không? Nhập dòng: mật mãMật mã học, môn khoa học về mã hóa và giải mã thông tin... Trên thực tế, tin nhắn được mã hóa đã tồn tại từ xa xưa và được quân đội sử dụng để truyền tải những tin nhắn bí mật. Chà, giờ đây mật khẩu của bạn trên Facebook và các mạng khác được lưu trữ ở dạng mã hóa. Nhiệm vụ 1. Kính chào Caesar!Thông tin lý thuyết Chúng ta sẽ nghiên cứu một trong những mật mã đơn giản nhất - mật mã Caesar, được đặt theo tên của hoàng đế La Mã. Trong mật mã này, mỗi chữ cái của văn bản được thay thế bằng một chữ cái khác, đó là một số chữ cái cố định thấp hơn trong bảng chữ cái. Số lượng chữ cái cố định này được gọi là khóa . Vì vậy, khóa 1 biến chữ C Latinh thành chữ D và Z qua chu trình thành A. Nếu khóa là 3 thì chữ C sẽ chuyển thành F và Z thành C. Ví dụ: chúng ta sử dụng mật mã Caesar với phím 5 trên chữ mèo. Tình trạngViết vào tệp caesar.c một chương trình mã hóa văn bản bằng mật mã Caesar. Cung cấp một đối số dòng lệnh làm đầu vào cho chương trình: một số nguyên không âm. Để đơn giản, hãy gọi nó là k. Nếu người dùng thực thi chương trình mà không có đối số dòng lệnh hoặc có nhiều hơn một đối số, ứng dụng sẽ khiếu nại và trả về giá trị 1 (đây là cách biểu thị lỗi): `mkdir /workspace/pset2`2 Trong tất cả các trường hợp khác, chương trình sẽ nhắc người dùng nhập văn bản để mã hóa, sau đó hiển thị văn bản được mã hóa bằng khóa k (tức là dịch chuyển k vị trí sang phải trong suốt chu trình). Nếu văn bản chứa các ký tự nằm ngoài bảng chữ cái tiếng Anh thì chương trình sẽ không thay đổi chúng. Sau khi in bản mã, ứng dụng thoát ra, main trả về 0: `mkdir /workspace/pset2`3 Nếu main không trả về 0 một cách rõ ràng, nó sẽ tự động trả về (int thực sự là kiểu trả về của main, nhưng sẽ nói nhiều hơn vào lúc khác). Theo quy ước (các quy tắc về hình thức tốt trong lập trình), nếu bạn trả về 1 một cách rõ ràng để chỉ ra lỗi thì bạn cũng nên trả về 0 làm con trỏ để hoàn thành thành công chương trình. Mặc dù bảng chữ cái tiếng Anh chỉ có 26 chữ cái nhưng k có thể lớn hơn 26. Về cơ bản, khóa k = 27 sẽ cho kết quả tương tự như k = 1, tuy nhiên bạn cần cho phép người dùng nhập bất kỳ số không âm nào không vượt quá 2^31 – 26 (phải vừa với int). Chương trình cũng phải tính đến việc các chữ cái viết thường được mã hóa thành chữ thường và chữ cái viết hoa được mã hóa thành chữ hoa. Chúng ta bắt đầu từ đâu? Vì ứng dụng phải chấp nhận trực tiếp giá trị của k trong chuỗi đối số nên tiêu đề hàm chính của chúng ta trông như thế này: `mkdir /workspace/pset2`4 Từ Chương 6, bạn đã biết rằng argv là một mảng các chuỗi. Mảng này có thể được coi như một dãy tủ đựng đồ trong phòng tập thể dục. Mỗi người trong số họ có một số ý nghĩa ẩn giấu. Trong trường hợp của chúng tôi, bên trong mỗi ô có một đối số như `mkdir /workspace/pset2`5 Để mở tủ đầu tiên, chúng tôi sử dụng argv[0], thứ hai - argv[1], v.v. Nếu chúng ta có n khóa thì chúng ta cần dừng lại ở argv[n - 1], vì argv[n] không còn tồn tại (hoặc tồn tại nhưng thuộc về người khác, tốt nhất chúng ta không nên chạm vào nó). Vì vậy, bạn có thể truy cập đối số k như thế này: `mkdir /workspace/pset2`6 Chúng tôi tin rằng thực sự có một cái gì đó ở đó! Hãy nhớ lại rằng argc là một biến int bằng số hàng trong argv. Điều này có nghĩa là tốt hơn hết bạn nên kiểm tra giá trị của argc trước khi thử mở ô, vì có thể nó không tồn tại. Lý tưởng nhất là argc = 2. Tại sao lại như vậy? Bên trong argv[0] thường là tên của chương trình. Nghĩa là, argc luôn ít nhất là 1. Nhưng chương trình của chúng ta cần người dùng cung cấp đối số dòng lệnh k, do đó, argc = 2. Đương nhiên, nếu người dùng nhập nhiều hơn một đối số trên dòng lệnh, argc cũng phát triển và có thể lớn hơn 2 Nếu người dùng nhập một số nguyên vào một chuỗi, điều này không có nghĩa là giá trị đã nhập sẽ tự động được lưu dưới dạng int. Chính xác hơn là KHÔNG. Nó sẽ là một chuỗi, ngay cả khi nó trông giống hệt một int! Vì vậy chúng ta cần phải tự chuyển đổi chuỗi thành int. May mắn thay, có một chức năng gọi là atoi được thiết kế cho mục đích này. Cú pháp của nó là: `mkdir /workspace/pset2`7 Lưu ý rằng k có kiểu int, vì vậy bạn có thể thực hiện phép tính với nó. Với hàm này, bạn không phải lo lắng về việc người dùng nhập số nguyên hay, chẳng hạn như foo: trong trường hợp đó, atoi sẽ trả về 0. Hàm atoi được khai báo trong thư viện stdlib.h , vì vậy hãy chắc chắn # đưa nó vào đầu chương trình. Mã sẽ biên dịch mà không cần hàm này vì chúng tôi đã đưa hàm này vào thư viện cs50.h. Tuy nhiên, tốt hơn là nên tin tưởng vào các thư viện gốc. Vì vậy, bạn đã lưu k dưới dạng int. Bây giờ hãy yêu cầu nhập văn bản. Nếu bạn đã làm bài tập của tuần đầu tiên thì bạn đã quen với hàm GetString trong thư viện CS50. Cô ấy sẽ giúp chúng tôi. Sau khi bạn đã nhận được k và văn bản ban đầu, hãy bắt đầu mã hóa. Tóm lại, bạn có thể lặp qua tất cả các ký tự của một chuỗi và in chúng bằng vòng lặp sau: `mkdir /workspace/pset2`8 Nói cách khác, giống như argv là một mảng các chuỗi, chuỗi là một mảng các ký tự. Do đó, chúng ta có thể sử dụng dấu ngoặc vuông để truy cập các phần tử chuỗi riêng lẻ giống như cách lấy các chuỗi riêng lẻ trong argv. Tất nhiên, không có gì mật mã khi in từng ký tự. Hoặc, về mặt kỹ thuật, khi k = 0. Nhưng chúng ta phải giúp Caesar mã hóa văn bản của anh ấy! Xin chào, Caesar! Để sử dụng strlen, bạn cần thêm một thư viện khác . Vì chúng tôi đang tự động hóa một số thử nghiệm xác thực nên chương trình sẽ hoạt động chính xác như thế này: `mkdir /workspace/pset2`9 Ngoài atoi , bạn có thể tìm thấy các hàm thú vị khác trong thư viện ctype.h và stdlib.h . Để làm điều này, hãy theo liên kết và lục lọi xung quanh đó một chút. Ví dụ, isdigit rõ ràng là một cái gì đó thú vị =). Khi đi từ Z đến A (hoặc từ z đến a), đừng quên toán tử modulo %bằng ngôn ngữ C. Ngoài ra, hãy nghiên cứu bảng , nó hiển thị các ký tự ASCII không chỉ cho các chữ cái. Để kiểm tra xem chương trình có hoạt động chính xác với check50 hay không , hãy làm như sau: `cd /workspace/pset2`0 Và nếu bạn muốn chơi với mã do nhân viên CS50 tạo, hãy chạy lệnh: `cd /workspace/pset2`1 Nhân tiện, uggc://jjj.lbhghor.pbz/jngpu ?i=bUt5FWLEUN0 . Phân tích nhiệm vụ
1. Chúng ta tạo hàm main để người dùng nhập key trên dòng lệnh và kiểm tra key xem có đúng không. `mkdir /workspace/pset2`4 argc: • int • số đối số được nhập trên dòng lệnh • nếu argc = 2 thì mọi thứ đều ổn. Nếu không, hãy in hướng dẫn và đóng chương trình. • Nếu argc = 2 chúng ta kiểm tra xem khóa có phải là số nguyên hay không • Argv là một mảng các chuỗi, một danh sách có các đối số được nhập vào. Mảng là cấu trúc dữ liệu chứa các dữ liệu khác nhau cùng loại trong các ô khác nhau. Nhiệm vụ 2. Parlez-vous français?Lý thuyết Mật mã Vigenère có phần an toàn hơn mật mã Caesar: nó sử dụng một từ làm khóa và rất khó bẻ khóa thủ công chỉ bằng cách sử dụng phân tích tần số hoặc dùng vũ lực. Mỗi chữ cái của khóa tạo ra một số và kết quả là chúng ta nhận được một số phím để dịch chuyển các chữ cái. Ví dụ: `cd /workspace/pset2`7 Bài tậpĐiều kiện Viết chương trình vigenere.c mã hóa tin nhắn bằng mật mã Vigenere. Chúng tôi cung cấp một đối số dòng lệnh cho đầu vào của chương trình: từ khóa k, bao gồm các chữ cái trong bảng chữ cái tiếng Anh. Nếu ứng dụng được khởi chạy với nhiều hơn một đối số hoặc có một đối số không có trong bảng chữ cái, thì cần phải hiển thị thông tin lỗi và kết thúc chương trình. Nghĩa là, main sẽ trả về 1 - trong trường hợp này, các bài kiểm tra tự động của chúng tôi sẽ hiểu rằng mọi thứ ở đây đều ổn và điều kiện này sẽ được tính đến. Nếu mọi việc đều ổn, chương trình sẽ tiến hành yêu cầu một chuỗi văn bản p mà chúng ta mã hóa bằng khóa k thu được ở trên, in kết quả và hoàn thành chương trình, trả về giá trị 0. Làm rõ Cần phải đảm bảo rằng trong khóa k ký tự A và a được ký hiệu là 0, B và b là 1, ..., Z và z là 25. Chương trình chỉ phải áp dụng mật mã Vigenère cho các chữ cái của văn bản p. Các ký tự còn lại (số, dấu chấm câu, dấu cách) phải được xuất ra mà không thay đổi. Nếu thuật toán áp dụng ký tự thứ j k cho ký tự thứ i p không có trong bảng chữ cái, hãy áp dụng ký tự khóa thứ j đó cho ký tự chữ cái tiếp theo trong văn bản; bạn không thể bỏ nó và chuyển sang một ký tự khác trong k. Cuối cùng, chương trình phải bảo toàn kiểu chữ của từng chữ cái trong p . Bạn không biết bắt đầu từ đâu?Dưới đây là một số lời khuyên từ Zamilya, trợ lý khóa học CS50 May mắn thay, chương trình này rất giống với mật mã Caesar, chỉ có khóa là một chuỗi chứ không phải số nguyên. Nếu bạn đã thực hiện thành công mật mã tên của người cai trị La Mã, đó có thể là bước khởi đầu tuyệt vời cho nhiệm vụ thứ hai. Có thể bạn đã nhận ra rằng mật mã Vigenère với một chữ cái làm khóa cũng giống như mật mã Caesar. Thuật toán Vigenère sử dụng các bước tương tự như Caesar:
Vì vậy, hãy kiểm tra đối số dòng lệnh thứ hai argv[1] để xem liệu nó có thuộc các ký tự chữ cái hay không. Chúng tôi thực hiện việc này bằng cách sử dụng isalpha vốn đã quen thuộc . Nếu khóa đúng, chúng tôi nhận được một chuỗi từ người dùng và bắt đầu mã hóa. Công thức mật mã Vigenère tương tự như công thức mật mã Caesar. Làm thế nào để bạn chuyển đổi một chữ cái sang độ lệch mật mã tương ứng? Hãy thử so sánh các giá trị bằng bảng ASCII. Cách xác thực mã của bạn và nhận điểmChú ý! Nếu điều quan trọng là bạn chỉ kiểm tra tính chính xác của các tác vụ thì hãy sử dụng cs50check. Nếu bạn muốn đạt điểm trên nền tảng edx, hãy làm theo quy trình được mô tả bên dưới. Hãy nhớ rằng quy trình này sử dụng cùng một cs50check để kiểm tra các tác vụ. Điểm khác biệt duy nhất là nó ghi nhớ kết quả và tính tổng điểm. |