JavaRush /وبلاگ جاوا /Random-FA /هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6)
Masha
مرحله

هاروارد 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 تا مطمئن شوید که نسخه فضای کاری شما به روز است. اگر به طور تصادفی پنجره ترمینال را ببندید، به منوی View بروید و مطمئن شوید که یک علامت در کنار آیتم کنسول وجود دارد (اگر نیست آن را بررسی کنید). هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 1 روی (+) کلیک کنید، در داخل دایره سبز رنگ روی قاب پنجره ترمینال، New Terminal را انتخاب کنید . هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 2 ایجاد یک پوشه کاری: توجه داشته باشید که بین mkdir و ~/workspace/pset2mkdir ~/workspace/pset2 فاصله وجود دارد . به طور خلاصه، ~ به معنای دایرکتوری ریشه است، ~/workspace پوشه ای است به نام Workspace در داخل دایرکتوری root، ~/workspace/pset2 دایرکتوری به نام pset2 در داخل ~/workspace است . اکنون اجرا کنید: برای تغییر به دایرکتوری جدید. خط فرمان چیزی شبیه به این است: اگر چیزی اشتباه است، مراحل را تکرار کنید. همچنین می توانید با فراخوانی دستورات چند دستور اخیر را به ترتیب زمانی مشاهده کنید. همچنین می توانید مکان نما خود را روی خط فرمان قرار دهید و فلش رو به بالا را روی صفحه کلید خود فشار دهید تا تمام دستورات را به ترتیب از آخرین وارد شده تا اول مشاهده کنید. با استفاده از دکمه پایین می توانید به عقب برگردید. ضمناً به جای اینکه هر بار همان دستورات را تایپ کنید، می توانید دستوراتی را که قبلاً تایپ کرده اید اسکرول کنید و با فشردن Enter دوباره آنها را اجرا کنید. شاید متوجه شده باشید که دیوید دقیقاً این کار را در سخنرانی های خود انجام می دهد. وظایف هفته دوم باید در pset2 ذخیره شود . cd ~/workspace/pset2username:~/workspace/pset2 $history

وظیفه 0. مقداردهی اولیه

بیایید نگاهی دقیق تر به خطوط بیندازیم. در فایل initials.c برنامه ای بنویسید که نام کاربر را درخواست کند (با استفاده از تابع GetString نام را به صورت رشته می گیریم) و سپس حروف اول نام (یا نام ها) و نام خانوادگی را با حروف بزرگ و بدون فاصله نمایش می دهد. نقطه‌ها یا نویسه‌های دیگر، فقط با فید خط ( \n ). ما فرض می کنیم که کاربران فقط حروف (حروف کوچک یا بزرگ یا هر دو) را به اضافه یک فاصله بین کلمات وارد می کنند. در نظر بگیرید که افرادی به نام جوزف گوردون-لویت، کانن اوبراین یا دیوید جی. مالان از این برنامه استفاده نخواهند کرد. برای بررسی عملکرد صحیح برنامه با 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
رمزنگاری
رمزنگاری، علم رمزگذاری و رمزگشایی اطلاعات... در واقع پیام های رمزگذاری شده از زمان های قدیم وجود داشته است و ارتش ها از آن برای انتقال پیام های مخفی استفاده می کردند. خوب، اکنون رمزهای عبور شما در فیس بوک و سایر شبکه ها به صورت رمزگذاری شده ذخیره می شوند.

وظیفه 1. سلام، سزار!

اطلاعات نظری
ما یکی از ساده ترین رمزها را مطالعه خواهیم کرد - رمز سزار که به نام امپراتور روم نامگذاری شده است. در این رمز، هر حرف از متن با حرف دیگری جایگزین می شود که تعداد ثابتی از حروف کمتر در الفبا است. این تعداد حروف ثابت کلید نامیده می شود . بنابراین، کلید 1 حرف لاتین C را به حرف D و Z را از طریق چرخه به A تبدیل می‌کند. اگر کلید 3 باشد، حرف C به F و Z به C تبدیل می‌شود. مثال‌ها: ما از رمز سزار استفاده می‌کنیم. کلید 5 در کلمه گربه. c -> h a -> f t -> y Caesar (cat, 5) = hfy کلید = 7، کلمه = کامپیوتر c->j o->v m->t p->w u->b t->a e->l r->y Caesar(computer,7) = jvtwbaly هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 3 رمز سزار ساده است، اما، افسوس، غیر قابل اعتماد (اینها چیزهای به هم پیوسته هستند!): برای الفبای انگلیسی فقط 25 گزینه رمزگذاری وجود دارد، به راحتی می توان از همه گزینه ها حتی بدون رایانه عبور کرد. با این حال، رمز سزار اغلب به عنوان یک مرحله در رمزهای دیگر، مانند رمز ویژنر (در پاراگراف بعدی در مورد آن بیشتر) استفاده می شود. بیایید رمز سزار را "ریاضی" کنیم. بیایید متن ساده را با حرف 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 برنامه ای بنویسید که متن را با استفاده از رمز سزار رمزگذاری می کند. یک آرگومان خط فرمان را به عنوان ورودی برنامه ارائه دهید: یک عدد صحیح غیر منفی. برای سادگی، بیایید آن را k بنامیم. اگر کاربر برنامه را بدون آرگومان خط فرمان یا با بیش از یک آرگومان اجرا کند، برنامه باید شکایت کند و مقدار 1 را برگرداند (به این ترتیب خطاها معمولاً نشان داده می شوند): return 1; در همه موارد دیگر، برنامه از کاربر متن را می خواهد. برای رمزگذاری، سپس متن رمزگذاری شده با کلید k را نمایش می دهد (به عنوان مثال، موقعیت های k در طول چرخه به سمت راست منتقل شده است). اگر متن حاوی کاراکترهایی باشد که خارج از الفبای انگلیسی هستند، برنامه آنها را تغییر نمی دهد. پس از چاپ متن رمز، برنامه خارج می‌شود، main 0 را برمی‌گرداند: return 0; اگر main به صراحت صفر را برمی‌گرداند، آن را به طور خودکار برمی‌گرداند (int در واقع نوع بازگشتی اصلی است، اما بیشتر در مورد آن زمان دیگری). طبق قرارداد (قوانین فرم خوب در برنامه نویسی)، اگر به صراحت 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 آرایه ای از رشته ها، رشته نیز آرایه ای از کاراکترها است. بنابراین، می‌توانیم از براکت‌های مربع برای دسترسی به عناصر رشته‌ای به همان روشی که رشته‌های جداگانه در 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. تابع main را شکل می دهیم تا کاربر کلید را در خط فرمان وارد کرده و صحت کلید را بررسی کند. int main(int argc, string argv[]) argc: • int • تعداد آرگومان های وارد شده در خط فرمان • اگر argc = 2 همه چیز خوب است. اگر نه، دستورالعمل را چاپ کنید و برنامه را ببندید. • اگر argc = 2 بررسی می کنیم که آیا کلید یک عدد صحیح است • Argv آرایه ای از رشته ها است، لیستی با آرگومان های وارد شده در آن آرایه یک ساختار داده ای است که حاوی داده های مختلف از یک نوع در سلول های مختلف است. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 4 به عنوان مثال، کاربر رشته blastoff Team Rocket را وارد کرده، سپس: هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 5 با استفاده از تابع atoi() عدد حاصل را به یک عدد صحیح تبدیل می کنیم. اگر این امکان پذیر نباشد، تابع 0 را برمی گرداند هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 6 . ساده است: هر چیزی که کاربر وارد می کند یک رشته است. 3. رمزگذاری. الگوریتم ساده است، اما چگونه می توانید به کامپیوتر توضیح دهید که کدام حروف یکی پس از دیگری می آیند؟ وقت آن است که جدول ASCII را به خاطر بسپارید! هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 7 با این حال، ممکن است بیش از حروف در یک رشته وجود داشته باشد... قبل از اینکه به تغییر رشته ها بپردازید، تصور کنید که فقط باید یک کاراکتر را تغییر دهید. ما می خواهیم حروف را از متن اولیه تغییر دهیم، نه علائم یا اعداد را. چه کار باید بکنیم؟ ابتدا باید بررسی کنیم که آیا این کاراکتر در حروف الفبا وجود دارد یا خیر. این کار را می توان با استفاده از تابع isalpha() انجام داد . اگر کاراکتر در حروف الفبا باشد، این تابع true و false را در غیر این صورت برمی گرداند. دو تابع مفید دیگر - ()isupper و ()islower اگر حرف به ترتیب بزرگ یا کوچک باشد true را برمی‌گردانند. بنابراین: Isalpha(‘Z’) -> true Isalpha(‘;’) -> false Isupper(‘Z’) ->true Isupper(‘z’) -> false Islower(‘Z’) -> false Islower(‘z’)->true اگر isalpha مقدار true را برگرداند، باید این کاراکتر را با استفاده از کلید تغییر دهیم. بیایید به عنوان مثال برنامه Zamili، دستیار CS50 را در نظر بگیریم و تجزیه و تحلیل کنیم. ممکن است تعجب کنید که چرا "A" یک عدد صحیح است در حالی که به وضوح یک حرف است. به نظر می رسد که نمادها و اعداد صحیح قابل تعویض هستند. با قرار دادن حرف A در یک نقل قول می توانید کد اسکی آن را به صورت 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);هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 8هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 9ci = (pi + k) % 26 جایی که ci حرف شماره i در متن رمزی است، pi حرف شماره i در متن ساده، k کلید، و %26 باقیمانده تقسیم بر 26 (یا "مدول 26") است. بیایید این فرمول را به حرف Y اعمال کنیم. k = 2 را در نظر بگیرید. ('Y' + 2) %26 کد اسکی حرف '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 (طول رشته) به شما کمک می کند تا تعداد تکرارها را در یک حلقه تعیین کنید .هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 10

وظیفه 2. Parlez-vous français؟

تئوری
رمز Vigenère تا حدودی ایمن تر از رمز سزار است: از یک کلمه به عنوان کلید استفاده می کند و شکستن آن به صورت دستی با استفاده از تجزیه و تحلیل فرکانس یا نیروی بی رحم به تنهایی دشوار است. هر حرف از کلید یک عدد تولید می کند و در نتیجه چندین کلید برای جابجایی حروف دریافت می کنیم. مثال: p = Meet me in the park at eleven am В качестве ключевого слова возьмем k = bacon Длина messages p = 25 В то время How длина k = 5 Поэтому его нужно повторять 5 раз. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 11 اگر تعداد حروف پیام بر کلید قابل تقسیم نباشد، فقط بخشی از آن را در آخرین کاربرد کلید استفاده می کنیم: هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 12 برای یافتن مقدار افست، از موقعیت های هر حرف کلید بیکن خود استفاده می کنیم. در حروف الفبا (از a تا z). ما مانند برنامه نویسان واقعی از ابتدا حساب می کنیم. و هر حرف در متن اصلی با یک عدد معین جابجا می شود، مانند رمز سزار، در صورت لزوم، پس از Z به ابتدای الفبا برمی گردد. بنابراین M با 1 حرکت می کند، e اول اصلا حرکت نمی کند و دومی 2 موقعیت حرکت می کند. در زیر پیام اصلی، کلید نوشته شده و نتیجه اعمال آن را مشاهده می کنید. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 13 رمز Vigenère، البته، قوی تر است، اما اگر طول کلید را بدانید، شکستن آن بسیار آسان است. چگونه آن را شناسایی کنیم؟ اگر متن اصلی به اندازه کافی طولانی باشد که برخی از کلمات چندین بار در آن ظاهر شوند، چند بار تکرار خواهید دید: می توانید از هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 14 نیروی brute نیز استفاده کنید، اما گزینه های زیادی وجود دارد: 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 اعمال کند. کاراکترهای باقیمانده (اعداد، علائم نقطه گذاری، فاصله ها) باید بدون تغییر خروجی شوند. اگر الگوریتم قرار است j امین کاراکتر k را به کاراکتر ith p که در الفبا نیست اعمال کند، آن j امین کاراکتر کلیدی را به کاراکتر الفبای بعدی در متن اعمال کنید. شما نمی توانید آن را رها کنید و به شخصیت دیگری در k بروید. در نهایت، برنامه باید حروف هر حرف را در p حفظ کند .
نمی دانید از کجا شروع کنید؟
هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 15
در اینجا چند نکته از Zamilya، دستیار دوره CS50 آورده شده است
خوشبختانه، این برنامه بسیار شبیه به رمز سزار است، تنها کلید یک رشته است تا یک عدد صحیح. اگر رمز نام حاکم رومی را با موفقیت پیاده سازی کرده اید، می تواند شروعی عالی برای کار دوم باشد. احتمالاً قبلاً متوجه شده اید که رمز ویژنر با یک حرف به عنوان کلید همان رمز سزار است. الگوریتم ویژنر از مراحل مشابه سزار استفاده می کند:
  1. کلید را دریافت کنید
    • کلمه رمز دومین آرگومان خط فرمان argv است[1]
    • باید در حروف الفبا باشد: تابع isalpha
  2. دریافت متن
  3. رمزگذاری کنید
  4. چاپ متن رمزی
بنابراین، اجازه دهید آرگومان خط فرمان دوم argv[1] را بررسی کنیم تا ببینیم آیا به کاراکترهای الفبایی تعلق دارد یا خیر. ما این کار را با استفاده از isalpha از قبل آشنا انجام می دهیم . اگر کلید درست باشد، یک رشته از کاربر دریافت می کنیم و رمزگذاری را شروع می کنیم. فرمول رمز ویژنر مشابه فرمول رمز سزار است. چگونه می توان یک حرف را به افست رمز مربوطه تبدیل کرد؟ سعی کنید مقادیر را با استفاده از جدول ASCII مقایسه کنید. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 16 به احتمال زیاد، می توانید با استفاده از دنباله های جدول، الگویی بین حروف و شاخص های الفبایی آنها پیدا کنید. آیا متوجه شده اید که چگونه یک حرف را از حرف دیگر کم کنید تا به نتیجه دلخواه برسید؟ افست برای حروف بزرگ و کوچک یکسان است، بنابراین شما باید دو فرمول مشابه برای تعیین افست برای حروف کوچک و جداگانه برای حروف بزرگ تعریف کنید. همچنین به یاد داشته باشید که حلقه متن باید کاراکترهای غیر انگلیسی را نادیده بگیرد. و حفظ حروف را فراموش نکنید. اگر به فرمول رمزنگاری نگاه کنید: ci = (pi + kj) % 26 دو متغیر شاخص i و j خواهید دید. یکی موقعیت را در متن منبع ذخیره می کند، دیگری در کلید. اگر متن شما طولانی تر از کلید باشد، نمایه روی کلید از انتهای کلید به ابتدا باز می گردد. چگونه انجامش بدهیم؟ با استفاده از عملیات تقسیم مدول! نتیجه عملیات باقیمانده تقسیم دو عدد است. مزایای عملی این عملیات در برنامه نویسی به سادگی بسیار زیاد است! تصور کنید که گروه بزرگی از مردم باید به سه زیر گروه تقسیم شوند. یکی از راه های انجام این کار این است که از آنها بخواهید برای اولین، دوم، سوم هزینه کنند. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 17 یعنی نفر اول متعلق به گروه اول، دوم به دوم، سوم به سوم، چهارم به اول و... است. برای انجام همان عملیات می توانید از تقسیم مدولو استفاده کنید. بیایید همان سه گروه را از ابتدا شماره گذاری کنیم. نحوه انجام این کار به این صورت است: هاروارد 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 را نوشتیم . این یک و تنها یک آرگومان خط فرمان (کلمه کلیدی) را می گیرد و وظیفه آن گرفتن متن رمز شده به عنوان ورودی و برگرداندن متن ساده است. Run it: ~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 کلیک کنید . باید ببینید که مرورگر Inicials.c را بارگذاری کرده است .
  3. برای caesar.c تکرار کنید .
  4. برای vigenere.c تکرار کنید .
  5. در یک پنجره یا تب جداگانه، وارد CS50 Submit شوید
  6. روی نماد ارسال در گوشه سمت چپ بالای صفحه کلیک کنید. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 19
  7. در لیست پوشه ها در سمت چپ، روی پوشه مشکل مجموعه ۲ کلیک کنید ، سپس روی دکمه آپلود ارسال جدید کلیک کنید . در سمت راست است. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 20
  8. در صفحه ظاهر شده بر روی دکمه افزودن فایل ها ... کلیک کنید. پنجره ای برای انتخاب فایل ها از رایانه شما باز می شود. هاروارد CS50: تکالیف هفته 2 (سخنرانی 5 و 6) - 21
  9. به پوشه ای بروید که در آن starts.c را نگه می دارید . به احتمال زیاد در پوشه دانلودها یا هر جایی که مرورگر شما فایل ها را به طور پیش فرض قرار می دهد، قرار دارد . هنگامی که inicials.c را پیدا کردید ، یک بار روی آن کلیک کنید تا انتخاب شود، سپس روی Open کلیک کنید.
  10. دوباره روی Add files کلیک کنید .
  11. caesar.c را پیدا کنید و آن را باز کنید.
  12. همین کار را برای فایل vigenere.c انجام دهید .
  13. روی شروع آپلود کلیک کنید. فایل های شما در سرورهای CS50 آپلود خواهند شد .
  14. در صفحه ای که ظاهر می شود، باید پنجره بدون فایل انتخاب شده را ببینید . اگر نشانگر ماوس خود را به سمت چپ حرکت دهید، لیستی از فایل های دانلود شده را مشاهده خواهید کرد. برای تایید، روی هر یک از آنها کلیک کنید. اگر در مورد چیزی مطمئن نیستید، می توانید با تکرار همان مراحل، فایل ها را دوباره آپلود کنید. می توانید این کار را تا پایان سال 2016 هر چند بار که دوست دارید انجام دهید.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION