پیوست ‎O‎- تمرین‌ها

‎O.2‎- نوشتن اسکریپت ها

برای انجام هر یک از وظایف زیر یک اسکریپت بنویسید.

آسان

اسکریپت تکثیر کننده خودش

اسکریپتی بنویسید که از خودش پشتیبان تهیه کند، یعنی خودش را به فایلی با نام ‎backup.sh‎ کپی کند.

اشاره: از فرمان cat و پارامتر مکانی مناسب استفاده کنید.

لیست کردن دایرکتوری خانه

یک لیست‌گیری بازگشتی از دایرکتوری خانه کاربر انجام داده و اطلاعات را در یک فایل ذخیره کنید. فابل را فشرده کنید، اسکریپت باید به کاربر اعلان قرار دادن یک ‎USB flash‎ و زدن ENTER را نمایش بدهد. سرانجام، با استفاده از تجزیه خروجی df کسب اطمینان نمایید که flash به طور صحیح mount گردیده است و فایل را روی آن ذخیره کنید. توجه نمایید که این درایو قبل از اینکه جدا بشود باید unmount بشود.

تبدیل حلقه‌های for به حلقه‌های while و until

تبدیل حلقه‌های for در مثال ‎11-1‎ به حلقه‌های while. اشاره: داده‌ها را در یک آرایه ذخیره نموده و تمام عناصر آرایه را پیمایش کنید.

«کار دشوار» را قبلا انجام داده‌اید، اکنون حلقه‌ها در مثال را به حلقه‌های until تبدیل کنید.

تغییر فاصله سطرها در یک فایل متن

اسکریپتی بنویسید که هر سطر فایل هدف را خوانده، سپس دوباره سطر را در stdout بنویسد، اما با یک سطر خالی اضافه به دنبال آن. این کار دارای همان اثر ‎double-spacing‎ (یک خط در میان نمودن) فایل است.

تمام کد لازم برای بازبینی آنکه آیا اسکریپت شناسه خط فرمان لازم (نام فایل) را به دست می‌آورد، و آیا فایل مشخص شده وجود دارد، در آن قرار بدهید.

وقتی اسکریپت به درستی اجرا می‌شود، آن را برای ‎triple-space‎ (دو خط در میان کردن) فایل مقصد، ویرایش نمایید.

سرانجام، اسکریپتی برای حذف نمودن تمام سطرهای خالی فایل مقصد، یا ‎single-spacing‎ آن بنویسید.

لیست‌گیری وارونه

اسکریپتی بنویسید که خودش را در stdout بازتاب بدهد، اما به صورت از انتها به ابتدا.

غیر فشرده نمودن فایل‌ها به طور خودکار

لیستی از نام فایل‌ها به عنوان ورودی مفروض است، این اسکریپت به نوع فشرده سازی مورد استفاده در هر فایل نیاز دارد (با تجزیه خروجی فرمان file). سپس اسکریپت به طور خودکار فرمان غیر فشرده کردن متناسب را فراخوانی می‌کند (gunzip،‏ bunzip2،‏ unzip،‏ uncompress، یا هرچه). اگر فایل مقصد فشرده نباشد، اسکریپت یک پیغام تذکر منتشر می‌کند، اما عمل دیگری روی آن فایل خاص انجام نمی‌دهد.

ID سیستم منحصر به فرد

یک شناسه هویتی «منحصر به فرد» شش رقمی هگزا دسیمال برای کامپیوتر خود تولید کنید. از فرمان معیوب hostid استفاده نکنید. اشاره: ابتدا ‎md5sum /etc/passwd‎، سپس جدا کردن شش رقم اول خروجی.

Backup

تمام فایل‌ها در درخت دایرکتوری خانگی‌تان‎(/home/your-name)‎ را که در ۲۴ ساعت گذشته ویرایش شده‌اند به صورت یک «tarball» (فایل ‎*.tar.gz‎) بایگانی کنید. اشاره: از find استفاده کنید.

اختیاری: شما می‌توانید این را به عنوان شالوده یک اسکریپت backup استفاده کنید.

بررسی که آیا یک پردازش هنوز در حال اجرا است

یک ID پردازش(PID) به عنوان یک شناسه معین گردیده، این اسکریپت در فواصل تعیین شده کاربر بازبینی می‌کند، آیا پردازش مفروض هنوز در حال اجرا است. شما می‌توانید از فرمان‌های ps و sleep استفاده نمایید.

اعداد اول

تمام اعداد اول بین ‎60000‎ و ‎63000‎ را (در stdout) چاپ کنید. خروجی باید به زیبایی در ستون‌ها قالب‌بندی شده باشد (اشاره: از printf استفاده کنید).

اعداد شانسی

یک نوع از قرعه‌کشی گزینش پنج عدد مختلف در محدوده ‎1 - 50‎ را شامل می‌شود. اسکریپتی بنویسید که پنج عدد شبه‌تصادفی در این محدوده رابدون مورد تکراری تولید کند. اسکریپت گزینه‌ای ارایه خواهد نمود برای نمایش اعداد در stdout یا ذخیره نمودن در یک فایل همراه با تاریخ و زمانی که یک مجموعه عدد خاص تولید شده‌اند. (اگر اسکریپت شما اعداد ثابتی برای برنده قرعه کشی تولید می‌کند، آنوقت شما می‌توانید به عایدات آن متکی شوید و اسکریپت‌نویسی پوسته را به افرادی از ما واگذار نمایید که برای زندگی باید کار کنند.)

متوسط

عدد صحیح یا رشته

یک اسکریپت تابع بنویسید که تعیین کند آیا شناسه داده شده به آن یک عدد صحیح است یا یک رشته. اگر یک عدد صحیح داده شده، اسکریپت ‎TRUE (0)‎ را برگشت بدهد، و اگر شناسه داده شده رشته باشد، ‎FALSE (1)‎ را برگشت بدهد.

اشاره: موقعی که ‎$1‎ یک عدد صحیح نباشد، عبارت زیر چه چیزی برگشت خواهد داد؟

expr $1 + 0

ASCII به صحیح

تابع atoi در C یک رشته کاراکتری را به یک عدد صحیح تبدیل می‌کند. یک تابع اسکریپت پوسته بنویسید که همان عمل را انجام بدهد. بعلاوه، یک تابع اسکریپت پوسته بنویسید که برعکس آن را انجام بدهد، یعنی یک عدد صحیح را به کاراکتر ASCII تبدیل نماید.

مدیریت فضای دیسک

تمام فایل‌های بزرگتر از ‎100K‎ در درخت دایرکتوری ‎/home/username‎ یک به یک لیست گردد. گزینه‌ای برای حذف یا فشرده کردن به کاربر ارایه شود، سپس با نمایش مورد بعد پیش برود. نام تمام فایل‌های حذف شده و زمان حذف آنها در یک فایل log نوشته شود.

Banner

قابلیت فرمان نکوهش شده banner را در یک اسکریپت شبیه‌سازی نمایید.

حذف حساب‌های کاربری غیر فعال

حساب‌های کاربری غیر فعال روی یک سرویس‌دهنده شبکه، فضای دیسک را هدر داده و می‌توانند یک خطر احتمالی امنیتی بشوند. یک اسکریپت مدیریتی بنویسید (به وسیله root یا cron daemon فراخوانی بشود) که حساب‌های کاربری دستیابی نشده در خلال ۹۰ روز گذشته را بازبینی و حذف نماید.

اِعمال سهمیه‌های دیسک

برای یک سیستم چند کاربره اسکریپتی بنویسید که استفاده کاربر از دیسک را بازبینی کند. اگر کاربری از یک میزان تعیین شده (برای مثال ‎500 MB‎) در دایرکتوری ‎/home/username‎ خود فراتر برود، آنوقت اسکریپت به طور خودکار یک پیغام ‎e-mail‎ «زیاده‌روی» به او ارسال کند.

این اسکریپت از فرمان‌های du و mail استفاده خواهد کرد. به عنوان یک گزینه، تنظیم تحمیل سهمیه‌ها را با استفاده از فرمان‌های quota و setquota امکان‌پذیر خواهد نمود.

اطلاعات کاربر وارد شده به سیستم

نام حقیقی و زمان و تاریخ آخرین login تمام کاربران لاگین نموده را نشان بدهید.

اشاره: از who،‏ lastlog، و تجزیه ‎/etc/passwd‎ استفاده کنید.

حذف بی‌خطر

به عنوان یک اسکریپت، یک فرمان حذف «بی‌خطر»، ‎sdel.sh‎ پیاده‌سازی کنید. فایل‌هایی که نام آنها به عنوان شناسه خط فرمان به این اسکریپت داده شود حذف نمی‌شوند، بلکه به جای آن اگر از قبل فشرده نباشند (به کار بردن file برای کنترل) gzip می‌شوند، سپس به دایرکتوری ‎~/TRASH‎ منتقل می‌گردند. اسکریپت به مجرد فراخوانی، دایرکتوری ‎~/TRASH‎ را برای فایل‌های قدیمی‌تر از ‎48‎ ساعت بازبینی و آنها را به طور دایمی حذف می‌کند. (یک جایگزین بهتر، شاید داشتن یک اسکریپت دوم برای انجام این کار باشد که به طور متناوب به وسیله ‎cron daemon‎ فراخوانی گردد.)

پشتوانه بیشتر: اسکریپت را طوری بنویسید که بتواند به طور بازگشتی فایل‌ها و دایرکتوری‌ها را مدیریت کند. این کار، توانایی «حذف بی‌خطر» ساختارهای دایرکتوری کامل را به اسکریپت می‌دهد.

معاوضه پول

کارآمدترین روش برای معاوضه ‎1.68‎ دلار تنها با سکه‌های رایج در گردش پولی چیست؟ عبارت است از شش ‎quarter‎ (سکه بیست و پنج سنتی)، یک ‎dime‎ (سکه ده سنتی)، یک ‎nickel‎ (سکه پنج سنتی)، و سه سنت.

برای هر ورودی اختیاری تعیین شده در خط فرمان به دلار و سنت به صورت ‎($*.??)‎، معاوضه را با استفاده از حداقل سکه‌ها حساب کنید. اگر کشور اصلی شما ایالات متحده نیست، می‌توانید به جای آن واحد پول محلی را به کار ببرید. اسکریپت نیازمند تجزیه ورودی خط فرمان، سپس تغییر آن به مضربی از کوچکترین واحد پولی (سنت یا هر چه) می‌باشد. اشاره: به مثال ‎24-8‎ نگاه کنید.

معادله درجه دوم

یک معادله درجه دوم به شکل ‎Ax^2 + Bx + C = 0‎ را حل کنید. اسکریپت ضرایب A،‏ B،‏ و C را به عنوان شناسه گرفته و جواب‌ها را تا پنج رقم اعشار برگشت بدهد.

اشاره: با به کار بردن فرمول شناخته شده ‎x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A‎، ضرایب را به bc لوله‌کشی کنید.

جدول لگاریتم‌ها

با استفاده از فرمان‌های bc و printf یک جدول قالب‌بندی شده زیبای ۸ مکانی از لگاریتم‌های طبیعی در فاصله بین ‎0.00‎ و ‎100.00‎ در فواصل ‎.01‎ چاپ کنید.

اشاره: bc برای بارگیری کتابخانه ریاضی به گزینه ‎-l‎ احتیاج دارد.

جدول یونیکد

با استفاده از مثال ‎T-1‎ به عنوان یک الگو، اسکریپتی بنویسید که یک جدول یونیکد کامل را در یک فایل بنویسد.

اشاره: گزینه ‎-e‎ را با echo به کار ببرید: ‎echo -e '\uXXXX'‎، که در آن XXXX عدد یونیکد معرف کاراکتر است. این نیازمند نگارش ‎4.2‎ یا جدیدتر Bash است.

حاصل جمع اعداد منطبق

جمع تمام اعداد پنج رقمی (در محدوده ‎10000 - 99999‎) شامل به طور دقیق دو رقم از ارقام : ‎{ 4, 5, 6 }‎ را پیدا کنید. این ارقام می‌توانند در همان عدد تکرار بشوند، و اگر چنین باشد، برای هر حضور یکبار به حساب می‌آیند.

برخی نمونه‌های اعداد منطبق عبارتند از ‎42057‎،‏ ‎74638‎،‏ و ‎89515‎.

اعداد خوش یمن

یک عدد خوش یمن آن است که حاصل جمع ارقام جداگانه آن در اثر جمع‌های متوالی به ‎7‎ منجر می‌شود. برای مثال، ‎62431‎ یک عدد خوش یمن است ‎(6 + 2 + 4 + 3 + 1 = 16, 1 + 6 = 7)‎. تمام اعداد خوش یمن میان ‎1000‎ و ‎10000‎ را پیدا کنید.

Craps

با بهره‌گیری از گرافیک‌های ASCII مثال ‎A-40‎، اسکریپتی بنویسید که بازی شرط‌بندی شناخته شده craps را اجرا کند. اسکریپت شرط‌های دو بازیکن یا بیشتر را خواهد پذیرفت، سپس انداختن طاس، و تعیین برنده‌ها و بازنده‌ها، به علاوه نقدینگی بازیکن‌ها.

Tic-tac-toe

اسکریپتی بنویسید که بازی بچگانه ‎tic-tac-toe‎ در مقابل یک بازیکن را بازی کند. اسکریپت از بازیکن سوال می‌کند که آیا او می‌خواهد شروع کننده بازی باشد. اسکریپت یک استراتژی بهینه را دنبال خواهد نمود، و بنابراین هرگز بازنده نمی‌شود. برای ساده‌سازی می‌توانید از گرافیک‌های اسکی استفاده کنید:

   o | x |
   ----------
     | x |
   ----------
     | o |
     
   Your move, human (row, column)?

به ترتیب الفبا نوشتن یک رشته

یک رشته اختیاری خوانده شده از خط فرمان را به ترتیب الفبا (به ترتیب اسکی) بنویسید.

تجزیه

‎/etc/passwd‎ را تجزیه نموده و آن را در یک قالب جدولی پاکیزه و آسان برای خواندن، به خروجی بدهید.

ثبت رخداد لاگین‌ها

‎/var/log/messages‎ را برای تهیه یک فایل به خوبی قالب‌بندی شده از لاگین کاربران و زمان لاگین‌ها، تجزیه کنید. ممکن است لازم باشد اسکریپت به عنوان root اجرا گردد. (اشاره: رشته «LOGIN» را جستجو کنید.)

چاپ شکیل یک فایل داده

برخی بسته‌های بانک‌ اطلاعاتی و صفحه گسترده‌، فایل‌های ذخیره با فیلدهای جدا شده توسط کاما، که به طور رایج به عنوان کمیت‌های جداشده با کاما یا CSVها منسوب شده‌اند، به کار می‌برند. سایر برنامه‌های کاربردی اغلب به تجزیه این فایل‌ها نیاز دارند.

یک فایل داده‌ای با فیلدهای جدا شده به وسیله کاما، به شکل زیر تعیین شده است:

Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989
Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
...

داده‌ها را دوباره قالب‌بندی نموده و در stdout با ستون‌های برچسب‌دار هم‌تراز، چاپ کنید.

هم تراز کردن

ورودی متن اسکی یا از stdin یا از یک فایل تعیین گردیده، فاصله کلمات را برای تراز کردن سطرها با یک طول سطر تعیین شده توسط کاربر، تنظیم کنید، سپس خروجی را به stdout ارسال کنید.

لیست پستی

اسکریپتی بنویسید که با استفاده از فرمان mail، یک لیست پستی ساده را مدیریت کند. اسکریپت ماهانه خبرنامه شرکت را به طور خودکار ‎e-mail‎‎ می‌کند، متن تعیین شده را از یک فایل می‌خواند، و آن را به تمام آدرس‌ها در فهرست پستی، که اسکریپت آن را از یک فایل متنی مشخص شده دیگری خواهد خواند، ارسال می‌کند.

تولید کلمه عبورها

کلمه عبورهای هشت کاراکتری شبه تصادفی، با استفاده از کاراکترهای محدوده ‎[0-9]‎،‏ ‎[A-Z]‎،‏ ‎[a-z]‎ تولید کنید. هر کلمه عبور باید حداقل شامل دو رقم نیز باشد.

دیده‌بانی یک کاربر

شما ظنین شده‌اید که کاربر خاصی روی شبکه از امتیازاتش سوءاستفاده کرده است و احتمالا برای هک کردن سیستم تلاش می‌کند. اسکریپتی بنویسید که به طور خودکار وقتی او به سیستم وارد می‌شود، فعالیت‌های او را دیده‌بانی کرده و در فایل ثبت وقایع درج کند. فایل log مدخل‌های مربوط به یک هفته گذشته را ذخیره و مدخل‌های قدیمی‌تر از هفت روز را حذف می‌کند.

شما می‌توانید از last،‏ lastlog، و lastcomm در جهت نظارت خود بر شخص مظنون استفاده کنید.

بازبینی پیوندهای بدون مقصد

با استفاده از lynx با گزینه ‎-traversal‎ اسکریپتی بنویسید که یک وبسایت را جهت لینک‌های خراب بازبینی نماید.

دشوار

تست کردن کلمه عبورها

اسکریپتی بنویسید که کلمه عبورها را بازبینی و اعتبارسنجی کند. مقصود کلمه عبورهای «ضعیف» یا به سادگی قابل حدس زدن است.

یک کلمه عبور آزمایشی به صورت پارامتر خط فرمان، ورودی اسکریپت خواهد بود. کلمه عبور برای قابل قبول شناخته شدن باید حداقل شرایط زیر را احراز نماید:

  • حداقل طول آن هشت کاراکتر باشد

  • باید دارای حداقل یک کاراکتر عددی باشد

  • باید حداقل شامل یکی از کاراکترهای غیر حرفی زیر باشد: @،‏ #،‏ $،‏ %،‏ &،‏ *،‏ +،‏ -،‏ =

اختیاری:

  • در کلمه عبور تحت بررسی، روی هر رشته از حداقل چهار کاراکتر الفبایی متوالی، یک کنترل دیکشنری انجام بدهید. این کار کلمه عبورهای شامل «کلمات» موجود در یک لغتنامه‌ استاندارد را مردود می‌کند.

  • اسکریپت را قادر به کنترل تمام کلمه‌عبورهای روی سیستم کنید. این کلمه عبورها در ‎/etc/passwd‎ قرار ندارند.

این تمرین تسلط بر عبارت‌های منظم را آزمایش می‌کند.

ارجاع متقابل

اسکریپتی بنویسید که یک مراجعه متقابل (فهرست الفبایی کلمات) روی یک فایل مقصد تولید کند. خروجی اسکریپت لیستی از تمام موارد وجود کلمات در فایل هدف، به اضافه شماره سطرهایی که هر کلمه در آن واقع گردیده، خواهد بود. به طور معمول، در این قبیل کاربردها، ساختارهای لیست پیوندی استفاده خواهد شد. برای این منظور، شما باید ضمن این تمرین آرایه‌ها را بررسی کنید. احتمالا مثال ‎16-12‎ جای مناسبی برای شروع نیست.

ریشه دوم

اسکریپتی بنویسید که ریشه دوم ‌(جذر) اعداد را با استفاده از شیوه نیوتن محاسبه کند.

الگوریتم برای این کار که به صورت یک قطعه شبه-کد Bash بیان گردیده عبارت است از:

#       روش ایزاک نیوتن برای استخراج سریع ریشه دوم.

guess = $argument
#  ‎$argument‎ عددی است که باید ریشه دوم آن پیدا شود.
# ‎$guess‎ هر «حدس» برآورد شده متوالی یا جواب آزمایشی
#+                                    ریشه دوم است.
#          اولین حدس ما از ریشه دوم، خود شناسه است.

oldguess = 0
#               ‎$oldguess‎ برابر با ‎$guess‎ قبلی است.

tolerance = .000001
#  میزان خطای قابل قبول برای ما در محاسبه ریشه دوم.

loopcnt = 0
#  دنبال کردن تعداد دفعات تکرار حلقه را میسر می‌کند.
# برای بعضی شناسه‌ها، تعداد تکرارهای بیشتری لازم است.


while [ ABS( $guess $oldguess ) -gt $tolerance ]
#       ^^^^^^^^^^^^^^^^^^^^^^^ البته، گرامر را درست کنید.

#  «ABS» یک تابع (ممیز شناور) است که قدر مطلق تفاوت
#+                      بین دو مقدار را پیدا می‌کند.
#  بنابراین، مادامیکه تفاوت میان جواب آزمایشی (حدس)
#+جاری و قبلی از حد مجاز تجاوز کند، حلقه حفظ می‌شود.

do
   oldguess = $guess  #به هنگام کردن ‎$oldguess‎ با ‎$guess‎ قبل.

#  =======================================================
   guess = ( $oldguess + ( $argument / $oldguess ) ) / 2.0
#  = 1/2 ( ($oldguess **2 + $argument) / $oldguess )
#                                       معادل است با:
#  = 1/2 ( $oldguess + $argument / $oldguess )
# یعنی، محاسبه میانگین جواب آزمایشی و میزان انحراف از
#+              شناسه (در واقع تجزیه خطا به دو نیمه).
#   این روش با چند تکرار حلقه به طور تعجب‌‌انگیزی به یک
#+                        جواب دقیق نزدیک می‌شود . . .
#+           البته برای شناسه‌های بزرگتر از ‎$tolerance‎
#  =======================================================

   (( loopcnt++ ))      #  به هنگام‌سازی شمارشگر حلقه.
done

این دستورالعمل به اندازه کافی ساده است، و با یک نگاه اجمالی به نظر می‌رسد تبدیل آن به یک اسکریپت Bash کاری به اندازه کافی آسان باشد. با وجود این، مشکل آن است که Bash دارای هیچ پشتیبانی درونی برای اعداد ممیز شناور نیست. بنابراین، نویسنده اسکریپت جهت تبدیل اعداد و انجام محاسبات به استفاده از bc یا احتمالا awk احتیاج دارد. با این کار، اسکریپت می‌تواند نسبتا شلوغ و بهم‌ریخته بشود. . .

وقایع نگاری دستیابی فایل

تمام دستیابی‌ها به فایل‌های داخل ‎/etc‎ در طول یک روز واحد را در فایل لاگ ثبت کنید. این اطلاعات باید شامل نام فایل، نام کاربر، و زمان دستیابی باشد. اگر هر تغییری در فایلها رخ بدهد نشانه‌گذاری خواهد گردید. این داده‌ها را به صورت رکوردهای جدول(فیلدهای جداشده با tab) در یک فایل لاگ بنویسد.

دیده‌بانی پردازش‌ها

اسکریپتی بنویسید که بر تمام پردازش‌های در حال اجرا نظارت کند و پیگردی نماید هر پردازش پدر، چند پردازش فرزند تولید می‌کند. اگر پردازشی بیش از پنج پردازش فرزند تولید کند، آنوقت اسکریپت یک ‎e-mail‎ با اطلاعات مناسب شامل زمان، ‎PID‎ پدر، PID فرزندان، و غیره به مدیر سیستم (یا root) ارسال نماید. اسکریپت هر ده دقیقه گزارشی در فایل ثبت وقایع درج کند.

پاک کردن توضیحات

تمام توضیحات را از یک اسکریپت پوسته که نام آن در خط فرمان تعیین می‌شود حذف کنید. توجه داشته باشید سطر آغازین ‎#!‎ نباید پاک شود.

حذف کردن تگ‌های HTML

تمام تگ‌های HTML در یک فایل HTML معین را حذف کنید، سپس آن را در سطرهایی با طول بین ‎60‎ تا ‎75‎ کاراکتر دوباره قالب‌بندی کنید. فاصله‌گذاری بلوک و پاراگراف را به طور مناسب بازنشانی کنید، و جدول‌های HTML را به معادل‌های متنی تقریبی آنها تبدیل کنید.

تبدیل XML

یک فایل XML را به هر دو قالب متنی و HTML تبدیل نمایید.

اختیاری: یک اسکریپت که ‎Docbook/SGML‎ را به XML ترجمه کند.

تعقیب Spammerها

اسکریپتی بنویسید که یک ‎e-mail‎ اسپم را به وسیله مقابله آدرس‌های IP با DNSها جهت شناسایی میزبان‌های واقعی و همچنین ‎ISP‎ سرچشمه آن، تجزیه و تحلیل کند. اسکریپت پیغام اسپم تغییر نیافته را به ISPهای مسئول forward خواهد کرد. البته، فیلتر نمودن آدرس IP متعلق به ISP خودتان ضروری خواهد بود، اینطور به شکایت از خودتان منجر نمی‌شود.

همچنانکه لازم است، از فرمان‌های تجزیه و تحلیل شبکه استفاده کنید.

برای ایده‌ گرفتن، مثال ‎16-41‎ و مثال ‎A-28‎ را ببینید.

اختیاری: اسکریپتی بنویسید که لیستی از پبغام‌های ‎e-mail‎ را جستجو نموده و بر طبق فیلترهای مشخص شده اسپم را حذف نماید.

تولید صفحه‌های man

اسکریپتی بنویسید که فرایند تولید صفحه‌های man را خودکار نماید.

فایل متنی که شامل اطلاعاتی جهت قالب‌بندی شدن در یک صفحه man است داده شده، اسکریپت این فایل را می‌خواند، سپس فرمان‌های مناسب groff را برای بیرون دادن صفحه man متناظر آن در stdout، فراخوانی می‌کند. فایل متن شامل بلوک‌هایی از اطلاعات تحت سرفصل‌های استاندارد صفحه man، به عنوان مثال، NAME،‏ SYNOPSIS،‏ DESCRIPTION،‏ و غیره است.

مثال ‎A-39‎ یک مرحله مقدماتی آموزنده است.

نسخه‌برداری Hex

از یک فایل باینری مشخص شده به عنوان شناسه اسکریپت، یک رونوشت‌گیری هگزادسیمال انجام بدهید. خروجی باید در فیلدهای جدولی مرتب شده باشد، فیلد اول نشان‌دهنده آدرس، هر هشت فیلد بعدی یک عدد چهار بایتی هگز، و فیلد پایانی معادل اسکی هر هشت فیلد قبلی باشد.

اقدام بدیهی بعدی برای این کار توسعه دادن اسکریپت نسخه برداری هگز به یک disassembler است. با استفاده از یک جدول مقابله‌ای، یا برخی تدابیر هوشمندانه دیگر، مقادیر هگز را به کدهای عملیاتی ‎80x86‎ تبدیل کنید.

شبیه‌سازی یک ‎Shift Register‎

با استفاده از مثال ‎27-15‎ به عنوان یک الهام بخش، اسکریپتی بنویسید که ‎shift register‎ شصت و چهار بیتی را به صورت یک آرایه شبیه‌سازی کند. توابع برای load ثبات، shift چپ، shift راست، و دوران آن پیاده‌سازی کنید. سرانجام، تابعی بنویسید که محتویات ثبات را به عنوان هشت کاراکتر اسکی هشت بیتی تفسیر نماید.

محاسبه دترمینان‌ها

اسکریپتی بنویسید که دترمینان‌ها‎[1]‎ را به وسیله بسط مینورها به طور بازگشتی محاسبه نماید. یک دترمینان ‎4 x 4‎ را به عنوان یک مورد آزمایشی به کار ببرید.

Hidden Words

یک تولید کننده پازل «یافتن کلمه» بنویسید، اسکریپتی که ‎10‎ کلمه ورودی را در یک آرایه ‎10 x 10‎ از حروف تصادفی پنهان می‌کند. کلمات میتوانند به طور سطری یا به طرف پایین یا قطری پنهان بشوند.

اختیاری: اسکریپتی بنویسید که پازل« یافتن کلمه» را حل می‌کند. برای پیش‌گیری از سخت شدن بیش از حد آن، اسکریپت حل کننده فقط کلمات افقی یا عمودی را پیدا خواهد کرد. (اشاره: با هر سطر یا ستون به عنوان یک رشته رفتار نموده، و رشته‌ها ی فرعی را جستجو کنید.)

Anagram سازی

Anagram(ساخت کلمه از حروف کلمه دیگر) ورودی چهار حرفی، anagramهای word عبارتند از: ‎do or rod row word‎. شما می‌توانید از ‎/usr/share/dict/words‎ به عنوان یک لیست مرجع استفاده کنید.

نرده‌بان‌های لغت

یک «نردبان لغت» یک تسلسل از کلمات است، که هر کلمه متوالی در آن با کلمه قبلی به وسیله یک حرف منفرد اختلاف دارد.

برای مثال، برای «نردبان» از mark به vase:

mark --> park --> part --> past --> vast --> vase
         ^           ^       ^      ^           ^

اسکریپتی بنویسید که معماهای نردبان کلمه را حل کند. با یک کلمه شروع و خاتمه معین، اسکریپت تمام مراحل میانی در «نردبان» را لیست خواهد نمود. توجه کنید که تمام کلمات در تسلسل باید کلمه‌های درست فرهنگ لغات باشند.

Fog Index

«‎fog index‎» یک قطعه متن، دشواری خواندن آن را به صورت یک عدد تقریبی جهت سواد تحصیلی لازم برای خواندن آن، برآورد می‌کند. برای مثال، یک قطعه متن با ‎fog index‎ برابر ‎12‎ باید برای هر کس که دارای ‎12‎ سال تحصیل رسمی است قابل درک باشد.

نگارش Gunning برای این شاخص، از الگوریتم زیر استفاده می‌کند.

  1. انتخاب بخشی از متن با طول حداقل یکصد کلمه.

  2. شمارش تعداد جمله‌ها (بخشی از یک جمله کوتاه شده، بواسطه علایم نگارشی متن به صورت یک جمله شمرده می‌شوند).

  3. پیدا کردن میانگین تعداد کلمه در هر جمله.

    AVE_WDS_SEN = TOTAL_WORDS / SENTENCES

  4. شمارش تعداد کلمات «دشوار» در قطعه متن -- آنها که شامل حداقل سه ‎syllable‎ (بخش هجایی) هستند. تقسیم این کمیت به کل کلمات برای به دست آوردن نسبت کلمات دشوار.

    PRO_DIFF_WORDS = LONG_WORDS / TOTAL_WORDS

  5. شاخص دشواری Gunning حاصل جمع دو کمیت فوق ضربدر ‎0.4‎ و سپس گرد شدن به نزدیک‌ترین عدد صحیح است.

    G_FOG_INDEX = int ( 0.4 * ( AVE_WDS_SEN + PRO_DIFF_WORDS ) )

مرحله ‎4‎ مشکل‌ترین بخش این تمرین است. الگوریتم‌های گوناگونی برای برآورد کردن سیلاب‌های یک کلمه وجود دارد. یک فرمول مفید ولی نه خیلی دقیق شاید تعداد حروف در یک کلمه و اختلاط صدا دار و بی‌صدا را در نظر بگیرد.

یک بیان دقیق از شاخص دشواری نگارش Gunning، کلمات مرکب و اسامی‌خاص را به عنوان کلمات «دشوار» نمی‌شمارد، اما این کار اسکریپت را به حد افراط پیچیده خواهد نمود.

محاسبه عدد پی با استفاده از ‎Buffon's Needle‎

ریاضیدان فرانسوی قرن هیجدهم ‎de Buffon‎ با آزمایش‌ جدید و بدیعی مطرح گردید. سوزنی به طول l را به دفعات روی کف چوبی اتاق که از صفحه‌های بلند و باریک موازی پوشیده شده است، می‌اندازیم. کناره‌های صفحه‌های چوبی هم عرض، تعدادی خطوط موازی تولید می‌کنند که در فاصله ثابت d (مساوی عرض هر صفحه) از یکدیگر قرار دارند. تعداد کل دفعات انداختن سوزن و دفعاتی که سوزن یکی از این خطوط را قطع می‌کند شمارش می‌کنیم. نسبت این دو کمیت یک ضریب کسری از PI است.

مترجم: اگر طول سوزن و فاصله خطوط موازی یعنی n و d با هم برابر باشند، این نسبت تقریبا برابر با 2 π خواهد شد. و در حالت کلی هم به طور تقریبی این رابطه بر قرار است.    نسبت =  2 π  ✕  l d

به طریقی که مثال ‎16-50‎ بیان می‌کند، اسکریپتی بنویسید که یک شبیه‌سازی ‎Monte Carlo‎ از ‎Buffon's Needle‎ اجرا می‌کند. برای ساده‌ کردن موضوع، طول سوزن را برابر با فاصله بین خطوط، ‎l = d‎ قرار بدهید.

اشاره: در حقیقت دو متغیر شاخص وجود دارد: فاصله مرکز سوزن به نزدیک‌ترین خط، و زاویه انحراف سوزن نسبت به آن خط. (مترجم: در این حالت یعنی تساوی l و d فاصله مذکور از صفر تا یک دوم d و زاویه از صفر تا یک دوم π تغییر می‌کند) می‌توانید از bc برای مدیریت محاسبات استفاده کنید.

رمز Playfair

رمزنگاری ‎Playfair (Wheatstone)‎ را در یک اسکریپت پیاده کنید.

رمز نگاری Playfair متن را به وسیله جایگزینی digramها (گروه‌های دوحرفی) رمزبندی می‌کند. به طور قراردادی از کادر کلید ‎5 x 5‎ حرف در هم آمیخته جهت رمزنگاری و رمزگشایی استفاده می‌گردد.

   C O D E S
   A B F G H             کادر کلید
   I K L M N
   P Q R T U
   V W X Y Z

هر حرف الفبا یکبار ظاهر می‌شود، به غیر از «I» که نماینده «J» نیز می‌باشد. کلید واژه انتخابی ‎CODES‎ ابتدا می‌آید، و آنوقت تمام حروف الفبا به ترتیب از چپ به راست با پریدن از روی حروفی که از قبل استفاده شده‌اند نوشته می‌شوند. برای رمزبندی، پیغام متن ساده به صورت digramها (گروه‌های دو حرفی) جدا می‌شوند. اگر یک گروه دارای دو حرف یکسان باشد، حرف دوم حذف شده و یک گروه جدید ساخته می‌شود. اگر در انتها یک حرف منفرد باقی بماند یک کاراکتر تهی، معمولا یک X درج می‌گردد.

THIS IS A TOP SECRET MESSAGE TH IS IS AT OP SE CR ET ME SA GE

برای هر گروه دوحرفی، سه احتمال وجود دارد.

-----------------------------------------------

1) هر دو حرف در یک سطر کادر کلید قرار خواهند داشت: هر حرف با حرف بلافاصله در سمت راست خود در همان سطر جایگزین می‌شود. اگر لازم باشد، یعنی در انتهای سطر باشد به ابتدای سطر می‌رود. یا 2) هر دو حرف در یک ستون از کادر کلید خواهند بود: هر حرف با حرف بلافاصله پایین‌تر خود در همان ستون جایگزین می‌شود. اگر لازم باشد از بالا ی همان ستون استفاده می‌شود . یا 3) هر دو حرف گوشه‌های یک چهار گوشه در داخل کادر کلید را می‌سازند: هر حرف با حرفی که در گوشه دیگر همان سطر قرار دارد جایگزین می‌گردد.

دوحرفی «TH» مشمول حالت شماره ‎3‎ می‌شود.

G H M N T U (چهار گوشه‌ای با T و H در گوشه‌ها) T --> U H --> G

دوحرفی «SE» مشمول حالت شماره ‎1‎ است.

C O D E S (سطر شامل S و E) S --> C (چرخش به چپ به ابتدای سطر) E --> S

========================================================================= برای رمزگشایی متن رمزی،روش کار در حالت اول و دوم را برعکس می‌کنیم (جابجایی در جهت مخالف برای جایگزینی). در حالت سوم، دو گوشه دیگر چهار ضلعی انتخاب می‌گردند. کار کلاسیک ‎Helen Fouche Gaines‎ با عنوان ‎ELEMENTARY CRYPTANALYSIS (1939)‎، یک شرح تفصیلی نسبتا خوبی از رمزبندی ‎Playfair Cipher‎ و روش‌های رمزگشایی آن ارایه می‌کند.

این اسکریپت دارای سه بخش اصلی خواهد بود

  1. تولید کادر کلید، بر اساس کلیدواژه ورودی کاربر.

  2. رمزی کردن پیغام متن ساده.

  3. رمزگشایی متن رمز شده.

اسکریپت استفاده گسترده‌ای از آرایه‌ها و توابع به عمل خواهد آورد. شما ممکن است از مثال ‎A-56‎ به عنوان یک الهام‌بخش استفاده نمایید.

--

لطفا راه‌حل‌های خود جهت این تمرین‌ها را برای نگارنده ارسال نکنید. روش‌های متناسب‌تری برای اینکه او را تحت تاثیر استعدادتان قرار دهید وجود دارد، از قبیل ارایه نمودن bugfixها و پیشنهاد‌هایی برای بهتر کردن این کتاب.

یادداشت‌ها

[1]

برای آن با استعدادهایی در میان شما که در جبر مقدماتی مردود گردیده‌اند، یک دترمینان یک کمیت عددی مرتبط با یک ماتریس چند بعدی است (آرایه‌ای از اعداد).

برای یک مورد ساده دترمینان ‎2 x 2‎:

|a b| |b a|

حل آن ‎a*a - b*b‎ است، که در آن a و b نماینده اعداد هستند.