Thứ Bảy, 16 tháng 11, 2013

Một vài bài toán đơn giản 4.

Mã hóa và giải mã? Bạn đã từng nghe tới nó chưa?
Nếu chưa thì hãy xem qua bài viết này, còn nếu có thì cũng xem luôn nhé. ^^


Mã hóa và giải mã là 2 quá trình ngược nhau. Nói 1 cách ngắn gọn thì

-Mã hóa (encode): là quá trình chuyển 1 thông điệp sang 1 dạng khác, mà đối với những người không biết cách giải mã thì sẽ không thể hiểu được.
-Giải mã (decode): là quá trình chuyển 1 thông điệp đã được mã hóa về thông điệp ban đầu.

Ta sẽ xét 1 phương pháp mã hóa và giải mã cụ thể sau:
Quy tắc mã hóa :
Đoạn thông điệp được mã hóa là một đoạn văn bản có ý nghĩa. Đầu và cuối thông điệp không có khoảng trắng. Các ký tự sử dụng trong đoạn văn bản này là các ký tự có giá trị từ 32 đến 126 trong bảng mã ASCII.
Đoạn văn bản được mã hóa theo một khoá K. Khoá K có giá trị trong đoạn [0, 255].
Bước 1: Các ký tự trong thông điệp ban đầu sẽ được chuyển sang dạng nhị phân.
Bước 2: Các ký tự này (ở dạng nhị phân) sẽ thực hiện phép toán XOR với khóa K cho trước để được bản tin đã mã hoá.
Bước 3: Dãy nhị phân của bản tin đã mã hóa được chia thành các nhóm 5 bit. Mỗi nhóm 5 bit này được thêm vào bit 1 ở đầu và chuyển thành ký tự có mã ASCII tương ứng.
Các đội sẽ nhận được bản tin đã mã hoá sang dạng ký tự ASCII như ở bước 3 và khóa K. Nhiệm vụ của các đội là giải ra đoạn văn bản thông điệp ban đầu.

Dễ thấy cách mã hóa và giải mã không có gì phức tạp, ta chỉ cần làm y như những gì đề bài yêu cầu (đối với encode) và thứ tự ngược lại (với decode).

Source code
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int s[111];
string giaima(string s, int k)
{
    string Ret = "";
    int n = s.length();
    int left = 8, u = 0;

    for(int i = 0; i < n; ++i)
    {
        s[i] &= ~(1<<5);
        int get = (left < 5) ? left:5;
        left -= get;
        u = (u<<get) + (s[i]>>(5-get));
        if (left == 0)
        {
            Ret += char(u^k);
            u = s[i] - (s[i]>>(5-get) << (5-get)) ;
            left = 8 - (5-get);
        }
    }
    return Ret;
}

string mahoa(string ss, int k)
{
    string Ret = "";
    int n = ss.length();

    for(int i = 0; i < n; ++i)
    {
         s[i] = ss[i];
         s[i] ^= k;

    }

    int u = 0, left = 5;
    for(int i = 0; i < n; ++i)
    {
        int uu = int(s[i]);
        int c = 8;
        while (c >= left)
        {
            u = (u<<left) + (s[i]>>(c-left));
            Ret += char(u+(1<<5));
            u = 0;
            s[i] -= (s[i]>>(c-left) << (c-left));
            c -= left;
            left = 5;
        }
        u = s[i];
        left -= c;
    }

    return Ret;
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("i.inp","r",stdin);
        freopen("o.out","w", stdout);
    #endif
    string s="";
    int k, choice;
    getline(cin,s);

    scanf("%d", &k);
    //
    scanf("%d", &choice);
    if (choice)//neu choice <>0 thi ma hoa
        cout<<mahoa(s,k);
    else// neu choice = 0 thi giai ma
        cout<<giaima(s,k);
    return 0;
}

Không có nhận xét nào:

Đăng nhận xét