JavaRush /จาวาบล็อก /Random-TH /Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6)
Masha
ระดับ

Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6)

เผยแพร่ในกลุ่ม
งาน cs50 สำหรับการบรรยาย 5 และ 6 การบรรยายของ CS50 อยู่ที่นี่: https://cdn.javarush.com/images/article/155cea79-acfd-4968-9361-ad585e939b82/Original.pngcs50.html เนื้อหานี้มี 3 งาน ข้อมูลเชิงทฤษฎีเกี่ยวกับงานเหล่านั้นและแนวทางปฏิบัติ

เป้าหมาย

• เจาะลึกเข้าไปในฟังก์ชันและไลบรารี • ทำความคุ้นเคยกับการเข้ารหัส ใช้รหัสง่ายๆ สองสามตัว

วัสดุเพิ่มเติม

https://reference.cs50.net/ - คำอธิบายฟังก์ชั่นห้องสมุดที่ใช้ในระหว่างการฝึกอบรม เป็นภาษาอังกฤษ. http://computer.howstuffworks.com/c.htmหน้า 11 – 14 และ 39

การตระเตรียม

เข้าสู่ระบบ cs50.io update50 เพื่อให้แน่ใจว่าเวอร์ชันพื้นที่ทำงานของคุณเป็นเวอร์ชันล่าสุด หากคุณปิดหน้าต่างเทอร์มินัลโดยไม่ได้ตั้งใจ ให้ไปที่เมนูมุมมองและตรวจสอบให้แน่ใจว่ามีเครื่องหมายถูกอยู่ถัดจากรายการคอนโซล (ตรวจสอบว่าไม่มี) Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 1 คลิกที่ (+) ภายในวงกลมสีเขียวบนกรอบหน้าต่างเทอร์มินัล เลือกNew Terminal Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 2 สร้างไดเร็กทอรีการทำงาน: mkdir ~/workspace/pset2 โปรดทราบว่ามีช่องว่างระหว่างmkdirและ~/workspace/ pset2 สรุปได้ว่า~หมายถึงไดเร็กทอรีราก~/workspaceเป็นโฟลเดอร์ที่เรียกว่า workspace ภายในไดเร็กทอรีราก~/workspace/pset2เป็นไดเร็กทอรีที่เรียกว่าpset2ภายใน~/ workspace รันตอนนี้: cd ~/workspace/pset2 เพื่อเปลี่ยนเป็นไดเร็กทอรีใหม่ บรรทัดคำสั่งมีลักษณะดังนี้: username:~/workspace/pset2 $ หากมีสิ่งใดผิดปกติ ให้ทำซ้ำขั้นตอนนี้ คุณยังสามารถเรียกใช้คำสั่ง history เพื่อดูคำสั่งสองสามคำสั่งสุดท้ายตามลำดับเวลาได้ คุณยังสามารถวางเคอร์เซอร์บนบรรทัดคำสั่งแล้วกดลูกศรขึ้นบนแป้นพิมพ์เพื่อดูคำสั่งทั้งหมดตามลำดับจากคำสั่งที่ป้อนล่าสุดไปยังคำสั่งแรก การใช้ปุ่มลงคุณสามารถย้อนกลับได้ อย่างไรก็ตาม แทนที่จะพิมพ์คำสั่งเดียวกันทุกครั้ง คุณสามารถเลื่อนดูคำสั่งที่คุณพิมพ์ไปแล้วและดำเนินการอีกครั้งโดยกด Enter คุณอาจสังเกตเห็นว่าเดวิดทำเช่นนี้ในการบรรยายของเขา งานของสัปดาห์ที่สองควรถูกบันทึกไว้ใน pset2

ภารกิจ 0 การเริ่มต้น

มาดูเส้นกันดีกว่า ใน ไฟล์ Initials.cให้เขียนโปรแกรมที่ขอชื่อผู้ใช้ (โดยใช้ฟังก์ชัน GetString เราจะได้ชื่อเป็นสตริง) จากนั้นแสดงตัวอักษรตัวแรกของชื่อ (หรือชื่อ) และนามสกุลเป็นตัวพิมพ์ใหญ่โดยไม่มีช่องว่าง จุดหรืออักขระอื่น ๆ เฉพาะที่มีการป้อนบรรทัด ( \n ) เราถือว่าผู้ใช้ป้อนเฉพาะตัวอักษร (ตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่หรือทั้งสองอย่าง) บวกหนึ่งช่องว่างระหว่างคำ พิจารณาว่าผู้ชายที่ชื่อ Joseph Gordon-Levitt, Conan O'Brien หรือ David J. Malan จะไม่ใช้โปรแกรมนี้ หากต้องการตรวจสอบการทำงานที่ถูกต้องของโปรแกรม ให้โทร check50: คุณต้องการเล่นกับการใช้งานโปรแกรมที่เจ้าหน้าที่ CS50 เตรียมไว้หรือไม่? พิมพ์บรรทัด: username:~/workspace/pset2 $ ./initials Zamyla Chan ZC username:~/workspace/pset2 $ ./initials robert thomas bowden RTBcheck50 2015.fall.pset2.initials initials.c~cs50/pset2/initials
การเข้ารหัส
วิทยาการเข้ารหัสลับ ศาสตร์แห่งการเข้ารหัสและถอดรหัสข้อมูล... อันที่จริง ข้อความที่เข้ารหัสนั้นมีมาตั้งแต่สมัยโบราณ และกองทัพใช้เพื่อส่งข้อความลับ ตอนนี้รหัสผ่านของคุณบน Facebook และเครือข่ายอื่น ๆ จะถูกจัดเก็บในรูปแบบที่เข้ารหัส

ภารกิจที่ 1 สวัสดีซีซาร์!

ข้อมูลทางทฤษฎี
เราจะศึกษารหัสที่ง่ายที่สุดตัวหนึ่ง - รหัสซีซาร์ซึ่งตั้งชื่อตามจักรพรรดิโรมัน ในรหัสนี้ ตัวอักษรแต่ละตัวในข้อความจะถูกแทนที่ด้วยตัวอักษรอื่น ซึ่งเป็นจำนวนตัวอักษรที่อยู่ต่ำกว่าในตัวอักษรคงที่ จำนวนตัว อักษรคงที่นี้เรียกว่าคีย์ ดังนั้น คีย์ 1 จะแปลงอักษรละติน C เป็นตัวอักษร D และ Z ผ่านวงจรเป็น A หากคีย์คือ 3 ตัวอักษร C จะเปลี่ยนเป็น F และ Z เป็น C ตัวอย่าง:เราใช้รหัสซีซาร์กับ คีย์ 5 บนคำว่าแมว c -> h a -> f t -> y Caesar (cat, 5) = hfy Key = 7, word = คอมพิวเตอร์ c->j o->v m->t p->w u->b t->a e->l r->y Caesar(computer,7) = jvtwbaly Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 3 รหัส Caesar นั้นง่าย แต่อนิจจาไม่น่าเชื่อถือ (สิ่งเหล่านี้เชื่อมโยงถึงกัน!): สำหรับตัวอักษรภาษาอังกฤษมีตัวเลือกการเข้ารหัสเพียง 25 ตัวมันง่ายที่จะผ่านตัวเลือกทั้งหมดแม้ไม่มีคอมพิวเตอร์ก็ตาม อย่างไรก็ตาม รหัสซีซาร์มักถูกใช้เป็นขั้นตอนในรหัสอื่นๆ เช่น รหัส Vigenère (เพิ่มเติมเกี่ยวกับเรื่องนั้นในย่อหน้าถัดไป) มา "คำนวณ" เลขศูนย์ซีซาร์กันดีกว่า ลองแสดงข้อความธรรมดาด้วยตัวอักษร p โดย pi คือตัวอักษรในข้อความ p ซึ่งอยู่ที่ตำแหน่งหมายเลข i ลองเรียกตัวอักษรคีย์ลับ k, c ว่าไซเฟอร์เท็กซ์ และ ci แทนตัวอักษรในไซเฟอร์เท็กซ์ซึ่งอยู่ที่ตำแหน่ง i จากนั้นคุณสามารถคำนวณตัวอักษรแต่ละตัวของตัวเลขโดยใช้สูตร: ci = (pi + k) % 26 ทำความคุ้นเคยกับการทำให้เป็นทางการนี้ช่วยให้คุณสามารถตั้งโปรแกรมอัลกอริทึมและแสดงความหมายของตัวเลขได้อย่างถูกต้องและรัดกุม หากคีย์ k = 13 และข้อความต้นฉบับ p คือ "อย่าลืมดื่มโอวัลตินของคุณ!" นี่คือรหัสที่เราได้รับ: Or fher gb qevax lbhe Binygvar! โปรดทราบว่า O (ตัวอักษรตัวแรกในข้อความไซเฟอร์) จะเลื่อนไป 13 ตำแหน่งจากตัวอักษร B ( อักษรตัวแรกในข้อความต้นฉบับ ) สิ่งเดียวกันกับตัวอักษร r (ตัวอักษรตัวที่สองในการเข้ารหัส) จะถูกเลื่อน 13 ตัวอักษรจาก e (ตัวอักษรตัวที่สองในต้นฉบับ) ตัวอักษรตัวที่สามในการเข้ารหัส f เลื่อนไป 13 ตัวอักษรจาก s (ตัวที่สามในต้นฉบับ) ที่นี่เราไปเป็นวงกลมจาก z ถึง a รหัสซีซาร์ที่มีคีย์ 13 มีชื่อพิเศษว่าROT13 มันสมมาตร: ใช้สองครั้งเราจะกลับไปที่ข้อความต้นฉบับ แน่นอนว่ายังมี ROT26 อีกด้วย ซึ่งโดยทั่วไปแล้วจะมีความปลอดภัยสูง แต่ถ้าคุณไม่ได้แสดงความคิดของคุณอย่างชัดเจน =)
เงื่อนไข
เขียน โปรแกรมที่เข้ารหัสข้อความใน ไฟล์caesar.c โดยใช้รหัส Caesar ระบุอาร์กิวเมนต์บรรทัดคำสั่งหนึ่งรายการเป็นอินพุตของโปรแกรม: จำนวนเต็มที่ไม่เป็นลบ เพื่อความง่าย ลองเรียกมันว่า k หากผู้ใช้รันโปรแกรมโดยไม่มีอาร์กิวเมนต์บรรทัดคำสั่งหรือมีมากกว่าหนึ่งอาร์กิวเมนต์ แอปพลิเคชันควรบ่นและส่งกลับค่า 1 (นี่คือวิธีการแสดงข้อผิดพลาด): return 1; ในกรณีอื่น ๆ ทั้งหมด โปรแกรมจะแจ้งให้ผู้ใช้ป้อนข้อความ เพื่อเข้ารหัส จากนั้นแสดงข้อความที่เข้ารหัสด้วยปุ่ม k (เช่น เลื่อนตำแหน่ง k ไปทางขวาตลอดวงจร) หากข้อความมีอักขระที่อยู่นอกตัวอักษรภาษาอังกฤษ โปรแกรมจะไม่เปลี่ยนแปลง หลังจากพิมพ์ไซเฟอร์เท็กซ์ แอปพลิเคชันจะออกmainจะส่งกลับ 0: return 0; หากmainไม่ส่งคืนศูนย์อย่างชัดเจน มันจะส่งคืนโดยอัตโนมัติ (int นั้นเป็นประเภทการส่งคืนของ main แต่จะมากกว่านั้นในครั้งต่อไป) ตามแบบแผน (กฎของรูปแบบที่ดีในการเขียนโปรแกรม) หากคุณคืนค่า 1 อย่างชัดเจนเพื่อระบุข้อผิดพลาด คุณควรส่งคืน 0 เป็นตัวชี้ไปยังความสำเร็จของโปรแกรม แม้ว่าตัวอักษรภาษาอังกฤษจะมีเพียง 26 ตัวอักษร แต่ k สามารถมีขนาดใหญ่กว่า 26 ได้ โดยพื้นฐานแล้วคีย์ k = 27 จะให้ผลลัพธ์เหมือนกับ k = 1 แต่คุณต้องอนุญาตให้ผู้ใช้ป้อนตัวเลขที่ไม่เป็นลบใด ๆ ที่ไม่ เกิน 2^31 – 26 (ต้องพอดีกับ int) โปรแกรมต้องคำนึงด้วยว่าตัวอักษรพิมพ์เล็กถูกเข้ารหัสด้วยตัวพิมพ์เล็ก และตัวอักษรตัวพิมพ์ใหญ่ถูกเข้ารหัสด้วยตัวพิมพ์ใหญ่ เราจะเริ่มต้นที่ไหน? เนื่องจากแอปพลิเคชันต้องยอมรับค่า k โดยตรงในสตริงอาร์กิวเมนต์ ส่วนหัวของฟังก์ชันหลักของเราจึงมีลักษณะดังนี้: int main(int argc, string argv[]) จากบทที่ 6 คุณจะรู้ว่าargvเป็นอาร์เรย์ของสตริง แถวนี้เปรียบเสมือนล็อกเกอร์เรียงกันเป็นแถวในห้องออกกำลังกาย แต่ละคนมีความหมายบางอย่างซ่อนอยู่ ในกรณีของเรา ภายในแต่ละเซลล์จะมีอาร์กิวเมนต์เช่น string หากต้องการเปิดตู้เก็บของแรก เราใช้ argv[0] ที่สอง - argv[1] และอื่นๆ หากเรามี n ล็อค เราต้องหยุดที่ argv[n - 1] เนื่องจาก argv[n] ไม่มีอยู่อีกต่อไป (หรือมีอยู่ แต่เป็นของคนอื่น เราไม่ควรแตะต้องมัน) ดังนั้นคุณจึงสามารถเข้าถึงอาร์กิวเมนต์ k ได้ดังนี้: string k = argv[1]; เราเชื่อว่ามีบางอย่างอยู่ที่นั่นจริงๆ! จำได้ว่า argc เป็นตัวแปร int เท่ากับจำนวนแถวใน argv ซึ่งหมายความว่า ควรตรวจสอบค่า argc ก่อนที่จะพยายามเปิดเซลล์จะดีกว่า เพราะอาจกลายเป็นว่าไม่มีอยู่จริง ตามหลักการแล้ว argc = 2 เหตุใดจึงเป็นเช่นนั้น ภายใน argv[0] มักจะเป็นชื่อของโปรแกรม นั่นคือ argc มีค่าอย่างน้อย 1 เสมอ แต่โปรแกรมของเราต้องการให้ผู้ใช้ระบุอาร์กิวเมนต์บรรทัดคำสั่ง k ดังนั้น argc = 2 โดยธรรมชาติแล้ว หากผู้ใช้ป้อนมากกว่าหนึ่งอาร์กิวเมนต์บนบรรทัดคำสั่ง argc ก็จะเพิ่มขึ้นและสามารถ มีค่ามากกว่า 2 หากผู้ใช้ป้อนจำนวนเต็มลงในสตริง ไม่ได้หมายความว่าค่าที่ป้อนจะถูกจัดเก็บเป็น int โดยอัตโนมัติ แม่นยำยิ่งขึ้นมันจะไม่ มันจะเป็นสตริงแม้ว่ามันจะดูเหมือน int ก็ตาม! ดังนั้นเราจึงต้องแปลงสตริงเป็น int ตัวเราเอง โชคดีที่มีฟังก์ชันที่เรียกว่า atoi ที่ออกแบบมาเพื่อจุดประสงค์นี้ ไวยากรณ์ของมันคือ: int k = atoi(argv[1]); โปรดทราบว่า k เป็นประเภท int ดังนั้นคุณจึงสามารถคำนวณได้ ด้วยฟังก์ชันนี้ คุณไม่ต้องกังวลว่าผู้ใช้จะป้อนจำนวนเต็มหรือเช่น foo: ในกรณีนี้ atoi จะส่งกลับ 0 ฟังก์ชัน atoi ได้รับการประกาศในไลบรารีstdlib.hดังนั้นอย่าลืม # รวมไว้ที่จุดเริ่มต้นของโปรแกรม โค้ดจะคอมไพล์โดยไม่มีสิ่งนี้ เนื่องจากเราได้รวมฟังก์ชันนี้ไว้ใน ไลบรารี cs50.hแล้ว อย่างไรก็ตาม เป็นการดีกว่าที่จะเชื่อถือไลบรารีดั้งเดิม คุณได้ k เก็บเป็น int ตอนนี้ขอป้อนข้อความ หากคุณทำงานที่ได้รับมอบหมายในสัปดาห์แรก คุณจะคุ้นเคยกับฟังก์ชันไลบรารี CS50 ที่เรียกว่า GetString อยู่แล้ว เธอจะช่วยเรา หลังจากที่คุณได้รับ k และข้อความเริ่มต้นแล้ว มาเริ่มการเข้ารหัสกันดีกว่า สรุป คุณสามารถวนซ้ำอักขระทั้งหมดของสตริงและพิมพ์โดยใช้การวนซ้ำต่อไปนี้ for (int i = 0, n = strlen(p); i < n; i++) { printf("%c", p[i]); } กล่าวอีกนัยหนึ่ง เช่นเดียวกับargvคืออาร์เรย์ของสตริงstringคืออาร์เรย์ของอักขระ ดังนั้นเราจึงสามารถใช้วงเล็บเหลี่ยมเพื่อเข้าถึงแต่ละองค์ประกอบสตริงในลักษณะเดียวกับการรับแต่ละสตริงใน argv แน่นอนว่าไม่มีการเข้ารหัสใดๆ เกี่ยวกับการพิมพ์อักขระแต่ละตัว หรือในทางเทคนิค เมื่อ k = 0 แต่เราต้องช่วยซีซาร์เข้ารหัสข้อความของเขา! สวัสดีซีซาร์! หากต้องการใช้ strlen คุณต้องรวมไลบรารี อื่นไว้ ด้วย เนื่องจากเรากำลังดำเนินการทดสอบการตรวจสอบความถูก ต้องโดยอัตโนมัติ โปรแกรมจึงควรมีลักษณะเช่นนี้: username:~/workspace/pset2 $ ./caesar 13 Be sure to drink your Ovaltine! Or fher gb qevax lbhe Binygvar! นอกจากatoi แล้ว คุณยังสามารถค้นหาฟังก์ชันเจ๋งๆ อื่นๆ ได้ใน ไลบรารี ctype.hและstdlib.h หากต้องการทำสิ่งนี้ ให้ไปที่ลิงก์และค้นหาบริเวณนั้นเล็กน้อย ตัวอย่างเช่นisdigit เป็นสิ่งที่น่าสนใจอย่างชัดเจน =) เมื่อเดินทางจาก Z ไป A (หรือจาก z ไป a) อย่าลืมตัวดำเนินการแบบโมดูโล%ในภาษา C นอกจากนี้ ศึกษาตาราง ด้วย โดยจะแสดงอักขระ ASCII ไม่ใช่แค่ตัวอักษรเท่านั้น หากต้องการตรวจสอบว่าโปรแกรมทำงานอย่างถูกต้องด้วยcheck50ให้ทำดังต่อไปนี้: check50 2015.fall.pset2.caesar caesar.c และหากคุณสนใจที่จะเล่นกับโค้ดที่สร้างโดยทีมงาน CS50 ให้รันคำสั่ง: ~cs50/pset2/caesar อย่างไรก็ตามuggc://jjj.lbhghor.pbz/jngpu ?i=bUt5FWLEUN0 .
การวิเคราะห์งาน
  1. รับกุญแจ
  2. รับข้อความ
  3. เข้ารหัส
  4. แสดงข้อความที่เข้ารหัส
1. เราสร้างฟังก์ชันหลักเพื่อให้ผู้ใช้ป้อนคีย์บนบรรทัดคำสั่งและตรวจสอบความถูกต้องของคีย์ int main(int argc, string argv[]) argc: • int • จำนวนอาร์กิวเมนต์ที่ป้อนบนบรรทัดคำสั่ง • ถ้า argc = 2 ทุกอย่างก็โอเค ถ้าไม่เช่นนั้น ให้พิมพ์คำสั่งแล้วปิดโปรแกรม • ถ้า argc = 2 เราจะตรวจสอบว่าคีย์เป็นจำนวนเต็มหรือไม่ • Argv คืออาร์เรย์ของสตริง รายการที่มีอาร์กิวเมนต์ที่ป้อนเข้าไป Array คือโครงสร้างข้อมูลที่มีข้อมูลประเภทเดียวกันต่างกันในเซลล์ต่างกัน Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 4 ตัวอย่างเช่น ผู้ใช้ป้อนสตริง blastoff Team Rocket จากนั้น: Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 5 การใช้ฟังก์ชัน atoi() เราจะแปลงตัวเลขผลลัพธ์ให้เป็นจำนวนเต็ม หากไม่สามารถทำได้ ฟังก์ชันจะส่งกลับ 0 Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 6 2. แจ้งให้ผู้ใช้ป้อนข้อความ ง่ายมาก: ทุกสิ่งที่ผู้ใช้ป้อนจะเป็นสตริง 3. การเข้ารหัส อัลกอริธึมนั้นง่าย แต่คุณจะอธิบายให้คอมพิวเตอร์ฟังได้อย่างไรว่าตัวอักษรใดมาเรียงกัน ถึงเวลาจำตาราง ASCII แล้ว! Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 7 อย่างไรก็ตาม ในสตริงอาจมีมากกว่าตัวอักษร... ก่อนที่จะเปลี่ยนสตริง ลองนึกภาพว่าคุณต้องเปลี่ยนอักขระเพียงตัวเดียว เราต้องการเปลี่ยนตัวอักษรจากข้อความเริ่มต้น ไม่ใช่เครื่องหมายหรือตัวเลข เราควรทำอย่างไร? ก่อนอื่นเราต้องตรวจสอบว่าอักขระนี้อยู่ในตัวอักษรหรือไม่ ซึ่งสามารถทำได้โดยใช้ ฟังก์ชัน isalpha() หากอักขระอยู่ในตัวอักษร ฟังก์ชันนี้จะคืนค่าเป็นจริงและเท็จ หากไม่เป็นเช่นนั้น ฟังก์ชันที่มีประโยชน์อีกสองฟังก์ชัน - isupper()และislower()จะคืนค่าเป็นจริงหากตัวอักษรเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กตามลำดับ ดังนั้น: Isalpha(‘Z’) -> true Isalpha(‘;’) -> false Isupper(‘Z’) ->true Isupper(‘z’) -> false Islower(‘Z’) -> false Islower(‘z’)->true หาก isalpha คืนค่าเป็นจริง เราจำเป็นต้องเปลี่ยนอักขระนี้โดยใช้คีย์ ลองพิจารณาและวิเคราะห์เป็นตัวอย่างโปรแกรมของ Zamili ผู้ช่วย CS50 คุณอาจสงสัยว่าทำไม 'A' จึงเป็นจำนวนเต็มทั้งๆ ที่มันเป็นตัวอักษรอย่างชัดเจน ปรากฎว่าสัญลักษณ์และจำนวนเต็มใช้แทนกันได้ ด้วยการใส่ตัวอักษร A ไว้ในเครื่องหมายคำพูดเดี่ยว คุณจะได้รหัส ASCII เป็น int ระวัง: คุณต้องมีเครื่องหมายคำพูดเดี่ยว หากไม่มี คอมไพเลอร์จะค้นหาตัวแปรชื่อ A ไม่ใช่สัญลักษณ์ จากนั้นในบรรทัด เราจะเพิ่มค่าคีย์ให้กับรหัส ASCII ของตัวอักษรและเก็บไว้ในตัวแปรจำนวนเต็ม แม้ว่าผลลัพธ์จะเป็น int คำสั่ง printf จะใช้ตัวยึดตำแหน่ง %c สำหรับอักขระ ดังนั้นโปรแกรมจะพิมพ์อักขระที่เกี่ยวข้องกับผลลัพธ์จำนวนเต็ม ในกรณีที่สอง เราจะแสดงตัวเลขโดยใช้ตัวยึดตำแหน่ง %d คุณสามารถใส่รหัสนี้ลงใน cs50 IDE แล้วเล่นกับมันได้ มาดูกันว่า asciimath ทำงานอย่างไรกับคีย์ต่างๆ ลองใช้ค่า 25 เราจะเห็นภาพต่อไปนี้: และตอนนี้ให้คีย์เป็น 26: เราได้ [ และไม่ใช่ตัวอักษร A เลย มันเป็นเพียงอักขระ ASCII ถัดไปหลังจาก Z ดังนั้นการเพิ่มคีย์จะไม่ งาน. เราจำเป็นต้องใช้สูตรการเข้ารหัสเพื่อกลับไปยังจุดเริ่มต้นของตัวอักษรทันทีที่ตัวอักษรหมด โปรดจำไว้ว่าเราได้เขียนไว้ข้างต้นแล้ว: /* * asciimath.c * by Zamyla Chan * * Calculates the addition of a char and an integer, * and displays both the resultant character and its * ASCII value. * * Usage: ./asciimath key [char] * */ #include #include #include int main(int argc, string argv[]) { if (argc != 2) { printf("print the key next time \n"); return 1; } // key is the second command line argument int key = atoi(argv[1]); //преобразование строки в int int letter = 'A'; printf("\nCalculating '%c' + %d...\n", letter, key); int result = (letter + key); printf("The ASCII value of %c is %d.\n\n", result, result); return 0; } int result = (letter + key);Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 8Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 9ci = (pi + k) % 26 โดยที่ ci คือตัวอักษรตัวเลข i ในข้อความไซเฟอร์, pi คือตัวอักษรตัวเลข i ในข้อความธรรมดา, k คือคีย์ และ %26 คือส่วนที่เหลือของการหารด้วย 26 (หรือ "โมดูโล 26") ลองใช้สูตรนี้กับตัวอักษร Y เอา k = 2 คำนวณ ('Y' + 2) %26 รหัส ASCII ของตัวอักษร 'Y' = 89 จากนั้น ('Y' + 2) %26 = (89 + 2 )% 26 = 91%26 = 13 แต่นี่ไม่ใช่ค่า ASCII ของตัวอักษร A ที่เราต้องการ ซึ่งก็คือ 65 ทีนี้ลองให้ตัวอักษรแต่ละตัวมีค่าตั้งแต่ 0 ถึง 25 ตามลำดับ ในกรณีนี้ Y = 24 (24+2)%26 = 0 ตัวอักษร A มีเพียงดัชนีดังกล่าว ดังนั้น สูตรนี้จึงอ้างอิงถึงดัชนีตัวอักษรของตัวอักษร ไม่ใช่ค่า ASCII หากต้องการพิมพ์อักขระที่เข้ารหัส คุณจะต้องมีค่า ASCII และหาวิธีสลับระหว่างค่า ASCII และตัวเลขในตัวอักษร เมื่อเราหาสูตรสำหรับอักขระตัวหนึ่งได้แล้ว เราจะต้องนำไปใช้กับตัวอักษรแต่ละตัวในสตริงที่ป้อนจากคีย์บอร์ด แต่ถ้านี่คือตัวอักษรเท่านั้น! และจำไว้ว่าตัวพิมพ์ใหญ่และตัวพิมพ์เล็กต้องการความหมายที่แตกต่างกัน นี่คือจุดที่ฟังก์ชัน isupper และ islower มีประโยชน์ คุณอาจมีสองสูตร สูตรหนึ่งสำหรับตัวพิมพ์ใหญ่ และอีกสูตรสำหรับตัวอักษรตัวเล็ก ฟังก์ชันจะช่วยคุณเลือกว่าจะใช้สูตรใด จะใช้สูตรกับอักขระทุกตัวในสตริงได้อย่างไร โปรดจำไว้ว่าสตริงเป็นเพียงอาร์เรย์ของอักขระ ฟังก์ชัน strlen (ความยาวสตริง) จะช่วยคุณกำหนดจำนวนการวนซ้ำในลูปHarvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 10

ภารกิจที่ 2 Parlez-vous français?

ทฤษฎี
รหัส Vigenère ค่อนข้างปลอดภัยกว่ารหัส Caesar เนื่องจากใช้คำเป็นกุญแจและยากที่จะถอดรหัสด้วยตนเองโดยใช้การวิเคราะห์ความถี่หรือการใช้กำลังดุร้ายเพียงอย่างเดียว ตัวอักษรแต่ละตัวของคีย์จะสร้างตัวเลข และด้วยเหตุนี้ เราจึงมีคีย์หลายตัวสำหรับเปลี่ยนตัวอักษร ตัวอย่าง: p = Meet me in the park at eleven am В качестве ключевого слова возьмем k = bacon Длина messages p = 25 В то время How длина k = 5 Поэтому его нужно повторять 5 раз. Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 11 หากจำนวนตัวอักษรในข้อความหารด้วยคีย์ไม่ลงตัว เราจะใช้เพียงบางส่วนเท่านั้นในการใช้งานคีย์ครั้งล่าสุด: Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 12 ในการค้นหาค่าออฟเซ็ต เราใช้ตำแหน่งของตัวอักษรแต่ละตัวในคีย์เบคอนของเรา ในตัวอักษร (จาก a ถึง z) เรานับจากศูนย์ เช่นเดียวกับโปรแกรมเมอร์ตัวจริง และตัวอักษรแต่ละตัวในข้อความต้นฉบับจะถูกเลื่อนไปตามตัวเลขที่กำหนด เช่นเดียวกับในรหัสซีซาร์ หากจำเป็น จะกลับมาตามหลัง Z ไปที่จุดเริ่มต้นของตัวอักษร ดังนั้น M จะเคลื่อนที่ทีละ 1 e ตัวแรกจะไม่เคลื่อนที่เลย และตัวที่สองจะเคลื่อนที่ 2 ตำแหน่ง ด้านล่างนี้คุณจะเห็นข้อความต้นฉบับ คีย์ที่เขียน และผลลัพธ์ของการใช้งาน Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 13 แน่นอนว่ารหัส Vigenère นั้นแข็งแกร่งกว่า แต่ถ้าคุณรู้ความยาวของกุญแจ มันก็จะหักได้ง่ายทีเดียว จะระบุได้อย่างไร? หากข้อความต้นฉบับยาวพอที่จะมีคำบางคำปรากฏหลายครั้ง คุณจะเห็นข้อความซ้ำ: คุณ Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 14 ยังสามารถใช้กำลังดุร้ายได้ แต่มีหลายตัวเลือก: 26^n – 1 โดยที่ n คือความยาวของคีย์ที่ไม่รู้จัก . แต่ปกตินี่เยอะมาก จริงอยู่นี่ไม่ใช่ปัญหาสำหรับคอมพิวเตอร์ และตอนนี้คณิตศาสตร์ของการเข้ารหัส ให้ p เป็นข้อความ k เป็นคีย์เวิร์ด kj เป็นตัวอักษรตัว j ของคีย์ pi เป็นตัวเลขตัวอักษร i ในข้อความต้นฉบับ ci เป็นตัวเลขตัวอักษร i ในการเข้ารหัส . แล้ว: ci = (pi + kj) % 26
ออกกำลังกาย
เงื่อนไข เขียนโปรแกรม vigenere.c ที่เข้ารหัสข้อความโดยใช้รหัส Vigenere เราระบุอาร์กิวเมนต์บรรทัดคำสั่งหนึ่งรายการให้กับอินพุตโปรแกรม: คำสำคัญ k ซึ่งประกอบด้วยตัวอักษรของตัวอักษรภาษาอังกฤษ หากแอปพลิเคชันเปิดขึ้นโดยมีมากกว่าหนึ่งอาร์กิวเมนต์หรือมีอาร์กิวเมนต์ที่ไม่รวมอยู่ในตัวอักษร จำเป็นต้องแสดงข้อมูลข้อผิดพลาดและยุติโปรแกรม นั่นคือ main จะส่งกลับ 1 - ในกรณีนี้ การทดสอบอัตโนมัติของเราจะเข้าใจว่าทุกอย่างเรียบร้อยดีที่นี่ และเงื่อนไขนี้จะถูกนำมาพิจารณาด้วย หากทุกอย่างเรียบร้อยดี โปรแกรมควรดำเนินการขอสตริงข้อความ p ซึ่งเราเข้ารหัสด้วยคีย์ k ที่ได้รับด้านบน พิมพ์ผลลัพธ์และดำเนินการโปรแกรมให้เสร็จสิ้น โดยส่งคืนค่า 0 การชี้แจง จำเป็นต้องตรวจสอบให้แน่ใจว่าในคีย์ k อักขระ A และ a ถูกกำหนดให้เป็น 0, B และ b เป็น 1, ..., Z และ z เป็น 25 โปรแกรมต้องใช้รหัส Vigenère กับตัวอักษรของข้อความ p เท่านั้น อักขระที่เหลือ (ตัวเลข เครื่องหมายวรรคตอน ช่องว่าง) จะต้องส่งออกโดยไม่มีการเปลี่ยนแปลง หากอัลกอริทึมจะใช้อักขระ jth kกับอักขระ i pที่ไม่ได้อยู่ในตัวอักษร ให้ใช้อักขระคีย์ jth นั้นกับอักขระตัวอักษรตัวถัดไปในข้อความ คุณไม่สามารถปล่อยมันไว้และไปยังตัวละครอื่นใน k ได้ สุดท้าย นี้ โปรแกรมจะต้องคงกรณีของตัวอักษรแต่ละตัวไว้ในp
ไม่รู้ว่าจะเริ่มตรงไหน?
Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 15
คำแนะนำบางส่วนจาก Zamilya ผู้ช่วยหลักสูตร CS50 มีดังนี้
โชคดีที่โปรแกรมนี้คล้ายกับรหัส Caesar มาก มีเพียงคีย์เท่านั้นที่เป็นสตริงแทนที่จะเป็นจำนวนเต็ม หากคุณใช้รหัสชื่อของผู้ปกครองโรมันสำเร็จแล้ว อาจเป็นการเริ่มต้นที่ดีสำหรับงานที่สอง คุณคงทราบแล้วว่ารหัส Vigenère ที่มีตัวอักษรตัวเดียวเป็นกุญแจนั้นเหมือนกับรหัสของ Caesar อัลกอริทึมVigenèreใช้ขั้นตอนเดียวกับ Caesar:
  1. รับกุญแจ
    • codeword เป็นอาร์กิวเมนต์บรรทัดคำสั่งที่สอง argv[1]
    • ต้องอยู่ในตัวอักษร: ฟังก์ชันอิซัลฟา
  2. รับข้อความ
  3. เข้ารหัส
  4. พิมพ์ข้อความตัวเลข
ดังนั้น ลองตรวจสอบอาร์กิวเมนต์บรรทัดคำสั่งที่สอง argv[1] เพื่อดูว่าเป็นของอักขระตัวอักษรหรือไม่ เราทำสิ่งนี้โดยใช้isalpha ที่คุ้นเคย อยู่ แล้ว หากคีย์ถูกต้อง เราได้รับสตริงจากผู้ใช้และเริ่มการเข้ารหัส สูตรการเข้ารหัสVigenèreคล้ายกับสูตรการเข้ารหัสของซีซาร์ คุณจะแปลงตัวอักษรเป็นค่าชดเชยการเข้ารหัสที่เกี่ยวข้องได้อย่างไร ลองเปรียบเทียบค่าโดยใช้ตาราง ASCII Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 16 เป็นไปได้มากว่าคุณจะสามารถค้นหารูปแบบระหว่างตัวอักษรและดัชนีตัวอักษรโดยใช้ลำดับในตาราง คุณรู้วิธีลบตัวอักษรตัวหนึ่งออกจากกันเพื่อให้ได้ผลลัพธ์ที่ต้องการหรือไม่? ค่าชดเชยสำหรับตัวพิมพ์ใหญ่และตัวอักษรตัวเล็กจะเหมือนกัน ดังนั้นคุณจะต้องกำหนดสูตรที่คล้ายกันสองสูตรเพื่อกำหนดค่าชดเชยสำหรับตัวอักษรตัวพิมพ์เล็กและแยกกันสำหรับตัวอักษรตัวพิมพ์ใหญ่ โปรดจำไว้ว่าการวนซ้ำข้อความควรละเว้นอักขระที่ไม่ใช่ภาษาอังกฤษ และอย่าลืมเก็บตัวพิมพ์ไว้ด้วย หากคุณดูที่สูตรการเข้ารหัส ci = (pi + kj) % 26 คุณจะเห็นตัวแปรดัชนีสองตัวคือ i และ j อันหนึ่งจะบันทึกตำแหน่งในข้อความต้นฉบับ ส่วนอีกอันจะบันทึกตำแหน่งไว้ในคีย์ หากข้อความของคุณยาวกว่าคีย์ ดัชนีบนคีย์จะเปลี่ยนจากส่วนท้ายของคีย์กลับไปยังจุดเริ่มต้น ทำอย่างไร? ใช้การดำเนินการแบ่งแบบโมดูโล! ผลลัพธ์ของการดำเนินการคือเศษที่เหลือของการหารตัวเลขสองตัว ประโยชน์เชิงปฏิบัติของการดำเนินการนี้ในการเขียนโปรแกรมนั้นยิ่งใหญ่มาก! ลองนึกภาพว่าคนกลุ่มใหญ่จำเป็นต้องแบ่งออกเป็นสามกลุ่มย่อย วิธีหนึ่งในการทำเช่นนี้คือขอให้พวกเขาจ่ายเงินสำหรับอันที่หนึ่ง สอง และสาม Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 17 นั่นคือคนแรกอยู่ในกลุ่มแรก คนที่สองอยู่ในกลุ่มที่สอง คนที่สามอยู่ในกลุ่มที่สาม คนที่สี่อยู่ในกลุ่มแรกอีกครั้ง และอื่นๆ คุณสามารถใช้การแบ่งแบบโมดูโลเพื่อดำเนินการเดียวกันได้ ลองนับสามกลุ่มเดียวกันตั้งแต่เริ่มต้น มีวิธีดำเนินการดังนี้: Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 18 หากคุณนำดัชนีมาหารค่าสูงสุดแบบโมดูโล ผลลัพธ์ที่ได้จะไม่มากกว่าหรือเท่ากับค่านั้น ลองใช้หลักการนี้เพื่อคืนคีย์เวิร์ดไปที่จุดเริ่มต้น! แทนที่จะเรียงลำดับตามกลุ่ม คุณต้องมีดัชนีของคำหลัก เพื่อให้คุณสามารถชดเชยตัวอักษรที่ถูกต้องได้โดยไม่ต้องเกินความยาวของคีย์ เนื่องจากเราทำการทดสอบโค้ดของคุณโดยอัตโนมัติ โปรแกรมจึงควรทำงานดังที่แสดงด้านล่าง: jharvard@appliance (~/Dropbox/pset2): ./vigenere bacon Meet me at the park at eleven am Negh zf av huf pcfx bt gzrwep oz คุณจะทดสอบโปรแกรมได้อย่างไรนอกเหนือจากการคำนวณไซเฟอร์เท็กซ์ด้วยตนเอง เราใจดี : สำหรับสิ่งนี้เราจึงเขียนโปรแกรมdevigenere ใช้อาร์กิวเมนต์บรรทัดคำสั่ง (คำหลัก) เพียงตัวเดียวเท่านั้น และหน้าที่ของมันคือใช้ไซเฟอร์เท็กซ์เป็นอินพุตและส่งกลับข้อความธรรมดา เรียกใช้: ~cs50/pset2/devigenere k โดยที่ k คือคีย์เวิร์ด หากคุณต้องการตรวจสอบความถูกต้องของโปรแกรมของคุณโดยใช้ check50 ให้รัน: check50 2014.fall.pset2.vigenere vigenere.c และถ้าคุณต้องการประเมินการใช้งาน vigenere ของเรา ให้พิมพ์: ~cs50/pset2/vigenere

วิธีตรวจสอบรหัสของคุณและรับเครื่องหมาย

ความสนใจ! หากเป็นสิ่งสำคัญสำหรับคุณที่จะต้องตรวจสอบความถูกต้องของงานเท่านั้น ให้ใช้ cs50check หากคุณต้องการรับเกรดบนแพลตฟอร์ม edx ให้ทำตามขั้นตอนที่อธิบายไว้ด้านล่าง โปรดทราบว่าขั้นตอนนี้ใช้ cs50check เดียวกันในการตรวจสอบงาน ข้อแตกต่างเพียงอย่างเดียวคือจดจำผลลัพธ์และคำนวณคะแนนโดยรวม
  1. เข้าสู่ระบบ CS50 IDE
  2. ใกล้มุมซ้ายบนของCS50 IDEซึ่งเป็นที่ตั้งของไฟล์เบราว์เซอร์ (ไม่ใช่ในหน้าต่างเทอร์มินัล) ให้คลิกขวาที่ ไฟล์ Initials.cที่อยู่ใน ไดเร็กทอรี pset2แล้วคลิกDownload คุณจะเห็นว่าเบราว์เซอร์โหลดInitials.cแล้ว
  3. ทำซ้ำสำหรับcaesar.c
  4. ทำซ้ำสำหรับvigenere.c
  5. ในหน้าต่างหรือแท็บแยกต่างหาก ให้เข้าสู่ระบบ CS50 ส่ง
  6. คลิกที่ ไอคอน ส่งที่มุมซ้ายบนของหน้าจอ Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 19
  7. ในรายการโฟลเดอร์ทางด้านซ้าย ให้คลิกที่ไดเร็กทอรีProblem Set 2จากนั้นคลิกที่ ปุ่ม Upload New Submission มันอยู่ทางขวา Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 20
  8. บนหน้าจอที่ปรากฏขึ้นให้คลิกที่ ปุ่ม เพิ่มไฟล์ ... หน้าต่างสำหรับเลือกไฟล์จากคอมพิวเตอร์ของคุณจะเปิดขึ้น Harvard CS50: การบ้านสัปดาห์ที่ 2 (การบรรยายที่ 5 และ 6) - 21
  9. นำทางไปยังโฟลเดอร์ที่คุณเก็บInitials.cไว้ ส่วนใหญ่แล้วจะอยู่ใน โฟลเดอร์ Downloads ของคุณ หรือที่ใดก็ตามที่เบราว์เซอร์ของคุณใส่ไฟล์ตามค่าเริ่มต้น เมื่อคุณพบInitials.cให้คลิกที่มันหนึ่งครั้งเพื่อเลือก จากนั้นคลิก Open
  10. คลิกเพิ่มไฟล์อีกครั้ง
  11. ค้นหาcaesar.cและเปิดมัน
  12. ทำเช่นเดียวกันกับไฟล์vigenere.c
  13. คลิกเริ่มอัปโหลด ไฟล์ ของคุณจะถูกอัปโหลดไปยัง เซิร์ฟเวอร์CS50
  14. บนหน้าจอที่ปรากฏขึ้น คุณจะเห็นหน้าต่างNo File Selected หากคุณเลื่อนเคอร์เซอร์ไปทางซ้าย คุณจะเห็นรายการไฟล์ที่ดาวน์โหลด เพื่อยืนยันให้คลิกที่แต่ละรายการ หากคุณไม่แน่ใจเกี่ยวกับบางสิ่งบางอย่าง คุณสามารถอัปโหลดไฟล์อีกครั้งโดยทำซ้ำขั้นตอนเดียวกัน คุณสามารถทำเช่นนี้ได้บ่อยเท่าที่คุณต้องการจนถึงสิ้นปี 2559
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION