+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
شرلوک پس از کشف راز قتل اندرسون توسط موریآرتی تصمیم میگیرد اسرار این جنایت مخوف را برای پلیس افشا کند به همین دلیل میخواهد نامهای برای بازرس لستراد بنویسد و این راز را برملا کند. موریآرتی در شبکه پست مزدورانی دارد که نامهها را به صورت مخفیانه بررسی میکنند؛ از آنجا که شرلوک نمیخواهد موریآرتی متوجه کشف این راز توسط او بشود، تصمیم میگیرد که نامه را به صورت رمزنگاری شده برای بازرس ارسال کند. در این سوال شما باید در رمزنگاری نامه به شرلوک کمک کنید!
# نگاشت حروف به اعداد
ابتدا باید هر حرف در زبان انگلیسی را مستقل از بزرگ یا کوچک بودن، به یک عدد از 0 تا 25 نگاشت کنیم و در محاسبات رمزنگاری از آن عدد استفاده کنیم.
<details class="blue">
<summary>
**مشاهده جدول نگاشت**
</summary>
| حرف | عدد |
|:---:|:---:|
| A | 0 |
| B | 1 |
| C | 2 |
| D | 3 |
| E | 4 |
| F | 5 |
| G | 6 |
| H | 7 |
| I | 8 |
| J | 9 |
| K | 10 |
| L | 11 |
| M | 12 |
| N | 13 |
| O | 14 |
| P | 15 |
| Q | 16 |
| R | 17 |
| S | 18 |
| T | 19 |
| U | 20 |
| V | 21 |
| W | 22 |
| X | 23 |
| Y | 24 |
| Z | 25 |
</details>
# الگوریتمهای رمزنگاری
برای تبدیل متن انگلیسی معنادار (`plaintext`) به متن رمزشده (`ciphertext`) میتوان از الگوریتمهای مختلفی استفاده کرد:
<details class="green">
<summary>
**الگوریتم `Additive Cipher`**
</summary>
**توضیح:**
در این روش، هر حرف متن اصلی با شیفت دادن به تعداد مشخصی از حروف در الفبا، به رمز تبدیل میشود.
**پارامترها:**
+ `text` (متن اصلی)
+ `key` (کلید، که یک عدد صحیح است و مقدار شیفت را مشخص میکند)
**مثال:**
+ `text`: "hello"
+ `key`: 3
**رمزنگاری:**
```
h -> K ((7 + 3) % 26 = 10 -> K)
e -> H ((4 + 3) % 26 = 7 -> H)
l -> O ((11 + 3) % 26 = 14 -> O)
l -> O ((11 + 3) % 26 = 14 -> O)
o -> R ((14 + 3) % 26 = 17 -> R)
```
**نتیجه رمز شده:** `"KHOOR"`
**دستور:**
```
additive-cipher -text "hello" -key 3
```
</details>
<details class="green">
<summary>
**الگوریتم `Multiplicative Cipher`**
</summary>
**توضیح:**
در این روش، هر حرف متن اصلی با ضرب در یک کلید به رمز تبدیل میشود.
**پارامترها:**
+ `text` (متن اصلی)
+ `key` (کلید، که یک عدد صحیح است و با 26 نسبت به هم اولاند)
**مثال:**
+ `text`: "hello"
+ `key`: 3
**رمزنگاری:**
```
h -> V ((7 * 3) % 26 = 21 -> V)
e -> M ((4 * 3) % 26 = 12 -> M)
l -> H ((11 * 3) % 26 = 7 -> H)
l -> H ((11 * 3) % 26 = 7 -> H)
o -> Q ((14 * 3) % 26 = 16 -> Q)
```
**نتیجه رمز شده:** `"VMHHQ"`
**دستور:**
```
multiplicative-cipher -text "hello" -key 3
```
</details>
<details class="green">
<summary>
**الگوریتم `Affine Cipher`**
</summary>
**توضیح:**
این روش ترکیبی از رمزنگاری جمعی و ضربی است، به این صورت که هر حرف متن اصلی ضرب در یک کلید میشود و سپس به نتیجه کلید دوم اضافه میشود.
**پارامترها:**
+ `text` (متن اصلی)
+ `a` (کلید ضربی، که یک عدد صحیح است و با 26 نسبت به هم اولاند)
+ `b` (کلید جمعی، که یک عدد صحیح است)
**مثال:**
+ `text`: "hello"
+ `a`: 5
+ `b`: 8
**رمزنگاری:**
```
h -> R ((7*5 + 8) % 26 = 43 % 26 = 17 -> R)
e -> C ((4*5 + 8) % 26 = 28 % 26 = 2 -> C)
l -> L ((11*5 + 8) % 26 = 63 % 26 = 11 -> L)
l -> L ((11*5 + 8) % 26 = 63 % 26 = 11 -> L)
o -> A ((14*5 + 8) % 26 = 78 % 26 = 0 -> A)`
```
**نتیجه رمز شده:** `"RCLLA"`
**دستور:**
```
affine-cipher -text "hello" -a 5 -b 8
```
</details>
<details class="green">
<summary>
**الگوریتم `Mapping Cipher`**
</summary>
**توضیح:**
در این روش، هر حرف متن اصلی به یک حرف دیگر در الفبا مطابق با یک نگاشت از پیش تعریف شده تبدیل میشود.
**پارامترها:**
+ `text` (متن اصلی)
+ `mapping` (نگاشت حروف، به صورت رشتهای که ترتیب جدید حروف الفبا را نشان میدهد)
**مثال:**
+ `text`: "hello"
+ `mapping`: "zyxwvutsrqponmlkjihgfedcba" (نگاشت معکوس الفبا)
**رمزنگاری:**
```
h -> S
e -> V
l -> O
l -> O
o -> L
```
**نتیجه رمز شده:** `"SVOOL"`
**دستور:**
```
mapping-cipher -text "hello" -mapping "zyxwvutsrqponmlkjihgfedcba"
```
</details>
همانطور که در مثالها آمده است، فرمت کلی هر دستور به شکل زیر است:
```
<cipher-type> -text "<text>" [-key <key>] [-a <a-value>] [-b <b-value>] [-mapping "<mapping>"]
```
که در آن `cipher-type`، نوع الگوریتم رمز و سایر موارد، پارامترهای آن الگوریتم رمز هستند. پارامترهایی که بین `[]` آمدهاند، بسته به الگوریتم رمزنگاری ممکن است در دستور وجود نداشته باشند.
## نکات تکمیلی (مهم)
<details class="red">
<summary>
**نکته اول**
</summary>
----------
ترتیب پارامترها میتواند متفاوت باشد. برای مثال دو دستور زیر معادل هستند:
```
affine-cipher -text "hello" -a 5 -b 8
affine-cipher -a 5 -text "hello" -b 8
```
</details>
<details class="red">
<summary>
**نکته دوم**
</summary>
----------
فاصلههای اطراف متن معنادار نادیده گرفته میشوند و در متن رمزشده مشاهده نمیشوند. اما فاصلههای بین کلمات دقیقا در متن رمز شده میآید:
```
Plaintext: " please help me "
Ciphertext: "qmfbtf ifmq nf"
```
</details>
<details class="red">
<summary>
**نکته سوم**
</summary>
----------
بزرگی یا کوچکی حروف در متن معنادار مهم نیست. بنابراین متن رمزشده برای دو متن معنادار `hello` و `Hello` یکسان خواهد بود.
</details>
<details class="yellow">
<summary>
**توجه: لازم است اصول برنامه نویسی شیءگرا، کد تمیز و اصول SOLID تا حد ممکن در نظر گرفته شود.**
</summary>
</details>
<details class="yellow">
<summary>
**توجه: امکان پیادهسازی بخشی از سوال و کسب نمره آن بخش از سوال وجود دارد.**
</summary>
</details>
<details class="yellow">
<summary>
**توجه: تنها یک فایل شامل کدهای نوشته شده آپلود کنید.**
</summary>
</details>
# ورودی
ورودی شامل $n+1$ خط است. در خط اول $n$، تعداد دستورات میآید. در $n$ خط بعدی، در هر خط یک دستور رمزنگاری آمدهاست.
$$1 \le n \le 50$$
# خروجی
در خروجی به ازای هر دستور، نتیجه رمزنگاری را **با حروف بزرگ** در یک خط چاپ کنید.
# مثال
## ورودی نمونه ۱
```
2
additive-cipher -text "HELP me" -key 1
additive-cipher -text " HELP me " -key 1
```
## خروجی نمونه ۱
```
IFMQ NF
IFMQ NF
```
<details class="yellow">
<summary>
**توضیحات نمونه ۱**
</summary>
----------
در دستور اول، متن معنادار از نظر بزرگی یا کوچکی حروف فرقی نمیکند. بنابراین اگر `help me` را بخواهیم با الگوریتم `Additive Cipher` رمز کنیم، محاسبات به صورت زیر است:
```
h -> I ((7 + 1) % 26 = 8 -> I)
e -> F ((4 + 1) % 26 = 5 -> F)
l -> M ((11 + 1) % 26 = 12 -> M)
p -> Q ((15 + 1) % 26 = 16 -> Q)
m -> N ((12 + 1) % 26 = 13 -> N)
e -> F ((4 + 1) % 26 = 5 -> F)
```
+ در این مثال، `key` برابر یک است. بنابراین هر کاراکتر در متن معنادار با عدد 1 جمع میشود. چون عدد حاصل باید بین 0 تا 25 باشد، باقیماندهی حاصل جمع را بر عدد 26 بدست میآوریم. سپس در جدول نگاشت حروف انگلیسی به اعداد، حرف انگلیسی متناظر عدد بدست آمده را به عنوان کاراکتر رمزشده درنظر میگیریم. کاراکتر فاصله بین کلمات نیز دقیقا در متن رمز شده میآید.
بنابراین متن رمز شده، `IFMQ NF` خواهد بود.
+ دستور دوم مشابه دستور اول است، با این تفاوت که فاصلههای اضافی اطراف متن معنادار نادیده گرفته شدهاست. بنابراین متن رمزشده در هر دو دستور یکسان خواهد بود.
</details>
## ورودی نمونه ۲
```
2
multiplicative-cipher -text "danger" -key 3
multiplicative-cipher -key 3 -text "danger"
```
## خروجی نمونه ۲
```
JANSMZ
JANSMZ
```
<details class="yellow">
<summary>
**توضیحات نمونه ۲**
</summary>
----------
+ در دستور اول، اگر `danger` را بخواهیم با الگوریتم `Multiplicative Cipher` و کلید با مقدار 3 رمز کنیم، محاسبات به صورت زیر است:
```
d -> J ((3 * 3) % 26 = 9 -> J)
a -> A ((0 * 3) % 26 = 0 -> A)
n -> N ((13 * 3) % 26 = 13 -> N)
g -> S ((6 * 3) % 26 = 18 -> S)
e -> M ((4 * 3) % 26 = 12 -> M)
r -> Z ((17 * 3) % 26 = 25 -> Z)
```
در دستور دوم، صرفا جای پارامترها عوض شده و محاسبات مانند دستور قبل است.
</details>
## ورودی نمونه ۳
```
1
affine-cipher -text "Hi" -a 3 -b 1
```
## خروجی نمونه ۳
```
WZ
```
<details class="yellow">
<summary>
**توضیحات نمونه ۳**
</summary>
در این مثال، محاسبات رمزنگاری به صورت زیر است:
```
h -> W ((7*3 + 1) % 26 = 22 -> W)
i -> Z ((8*3 + 1) % 26 = 25 -> Z)
```
در این مثال، پارامتر `a` کلید ضربی و پارامتر `b` کلید جمعی است. بنابراین حروف متن معنادار در `a` ضرب و با `b` جمع میشوند.
بنابراین متن رمز شده، `WZ` خواهد بود.
</details>
## ورودی نمونه ۴
```
1
mapping-cipher -text "hello" -mapping "zyxwvutsrqponmlkjihgfedcba"
```
## خروجی نمونه ۴
```
SVOOL
```
<details class="yellow">
<summary>
**توضیحات نمونه ۴**
</summary>
در این مثال، `mapping` داده شده برابر `"zyxwvutsrqponmlkjihgfedcba"` است. به عبارت دیگر نگاشت حروف انگلیسی به متن رمز شده به صورت زیر است:
```
a -> Z
b -> Y
c -> X
d -> W
e -> V
f -> U
g -> T
h -> S
i -> R
j -> Q
k -> P
l -> O
m -> N
n -> M
o -> L
p -> K
q -> J
r -> I
s -> H
t -> G
u -> F
v -> E
w -> D
x -> C
y -> B
z -> A
```
با توجه به نگاشت بالا، متن `hello` به این صورت رمز میشود:
```
h -> S
e -> V
l -> O
l -> O
o -> L
```
بنابراین متن رمز شده، `SVOOL` خواهد بود.
</details>