پیاده سازی رمز سزار یا همان Caesar cipher با زبان سی پلاس پلاس

سلام
در روش رمزنگاری سزار از چرخش حروف الفبا استفاده می شود. بنابراین نمادها و ارقام بدون تغییر خواهند بود. این روش در زمان باستان جهت رمزنگاری پیام های محرمانه استفاده می شد اما امروزه صرفا بیشتر شبیه اسباب بازی رمزنگاری است!
هدف این مقاله ارتقا و توسعه روش رمزنگاری سزار نیست اما به شما نشان خواهد داد که چگونه این روش را برای زبان انگلیسی و به وسیله ++C پیاده سازی کنید.

 

اهداف
* فراهم کردن روشی برای رمزنگاری []char و std::string و فایل ها
* این کار را می توانید به وسیله تابعی که به عنوان الگوی اولیه است انجام دهید و آن را برای هر مورد تکرار کنید.
sdd زبان
نسخه استاندارد 2011 زبان ++C
کامپایلر شما باید از توابع lambda حلقه های for و مقدار دهنده های اولیه لیست پشتیبانی کند تا بتوانید از کدهای موجود در این مقاله و پیوست های انتهایی استفاده کنید. در صورتی که این طور نیست می توانید خودتان آن را به سورس کد اضافه کنید.

پارامترها و منطق طراحی
تابع اصلی و مرکزی برنامه ()caesar_cipher است که دارای چهار پارامتر ورودی است.

نام

توضیحات

src_begin

سورس شروع

src_end

سورس پایان

dest_begin

آغاز کننده مقصد

shift

عدد صحیح به نمایندگی از تعداد جابجایی حروف الفبا

استفاده از تکرارکننده ها به جای یک محتوای واقعی دو مزیت دارد:
۱- این تابع در موارد مختلف قابل استفاده است.
۲- پیاده سازی تابع ساده شده است.

نحوه استفاده
نوع خوب:

<code>

salam

</code>

std::string s("Hello, World!");

caesar_cipher(s.begin(), s.end(), s.begin(), 4);  // s == "Lipps, Asvph!"
caesar_cipher(s.begin(), s.end(), s.begin(), -4); // s == "Hello, World!"

 

نوع بد:

const std::vector<char> vc{'D', 'b', 'f', 't', 'b', 's'};
std::list<char>         lc(vc.size());

caesar_cipher(vc.begin(), vc.end(), lc.begin(), -1);
// lc == std::list<char>({'C', 'a', 'e', 's', 'a', 'r'})

نوع افتضاح:
 

const char              ca[]{"Sqjzanxwn!"};
std::unique_ptr<char[]> upca(new char[sizeof ca]);

caesar_cipher(std::begin(ca), std::end(ca), upca.get(), 4);
// std::strcmp(upca.get(), "Wunderbar!") == 0 

سورس کد تابع مرکزی و اصلی
اگر به یک برنامه کامل احتیاج دارید که با فایل ها کار کند بخش بعدی را ببینید.
یادداشت ها:
*زمانی که حروف الفبا جابجا می شوند، آن ها دور می زنند. این به این معناست که برای حروف الفبایی با ۲۶ حرف، جابجایی به تعداد ۲۷  دقیقا مشابه جابجایی به تعداد۱ است و جابجایی ۵۲ مثل این است که هیچ جابجایی ای صورت نگرفته است.
*هدف خط ۱۱ این است که عمل جابجایی را با گرفتن یک مدار و با استفاده از ()std:rotate به صورت تر و تمیز انجام دهد.
 

#include <algorithm>
#include <cctype>
#include <string>

template <typename InputIterator, typename OutputIterator>
OutputIterator caesar_cipher(InputIterator src_begin, InputIterator src_end, OutputIterator dest_begin, int shift)
{
    const std::string ab("abcdefghijklmnopqrstuvwxyz"); // AlphaBet
    std::string rot_ab(ab); // ROTated AlphaBet

    shift %= static_cast<int> (ab.length());

    if (shift < 0)
        std::rotate(rot_ab.rbegin(), rot_ab.rbegin() - shift, rot_ab.rend());
    else
        std::rotate(rot_ab.begin(), rot_ab.begin() + shift, rot_ab.end());

    return std::transform(src_begin, src_end, dest_begin, [ab, rot_ab](unsigned char c) -> char {
        if (std::isalpha(c))
        {
            if (std::isupper(c))
                return std::toupper(rot_ab.at(ab.find(std::tolower(c))));

            return rot_ab.at(ab.find(c));
        }

        return c;
    });
}

 

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

لینک های مفید

http://en.wikipedia.org/wiki/Caesar_cipher
http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
http://en.wikipedia.org/wiki/Iterator_pattern
http://www.stroustrup.com/C++11FAQ.html#uniform-init

منبع: سایت cplusplus.com نوشته Catfish3
ترجمه و ویرایش: تمدن