Site icon MkS

[C/C++] Base64 編解碼程式

7DIS1467Y2

Base64  編碼語解碼,其實是站長指派的「物件導性程式語言」的小組作業,至於為什麼要出編解碼,是因為站長很喜歡編碼與解碼的題目,算是喜歡玩含有邏輯概念的題目吧,聽說隔壁班有出到 RSA 加密,站長就沒研究了,藉口是沒時間,實際上是懶得再去碰程式了,然後由於久久沒發文,今天拿之前寫的 Base64 編解碼程式來衝一下文章數。

 


Base64

先來簡單了解一下什麼是 Base64 編碼與解碼,首先英文數字各別經過 ASCII 翻譯成機械碼,會是 8 bit,而 Base64 則是使用 6 bit,而 Base64 與 ASCII 使用的字元列表各有不同。

編碼表可以參考維基百科:https://zh.wikipedia.org/wiki/Base64

有不足的地方則用”=”,來補,一個”=”代表 2 bit 的 0,也就是說 “M” 的 Base64 就會等於 “TQ==”,過程也就是將 M 先解成機械碼 “01001101”,再將他切成 6 bit 為一組 “010011 | 01” ,後面第二組只有 01 不為 6bit ,所以則補 0,為 “010011 | 010000” 接著透過 Base64 的編碼來表示就會為 TQ,由於後方有捕兩組 00,所以需要補上兩組 “==”,M 的 BASE64 編碼為 TQ==。

 

CODE

#include <iostream>
#define CODE "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#define EZ    63
using namespace std;

char E = NULL;
char D;
int out;
void Decode(char i, char x){
    if (x == 1){
        D = (i << 2);
    }else if (x == 2){
        cout << char(D | (i >> 4));
        D = (i << 4);
    }else if (x == 3){
        cout << char(D | (i >> 2));
        D = (i << 6);
    }else if (x == 4){
        cout << char(D | i);
    }
}

char Encode(char i,char x){
    if (x == 1){
        out = (i >> 2) | E;
        E = (i << 4) & EZ;
        return out ;
    }else if(x == 2){
        out = (i >> 4) | E;
        E = (i << 2) & EZ;
        return out;
    }else if (x == 3){
        out = (i >> 6) | E;
        E = i & EZ;
        return out;
    }
}

int main(){
    int i, x = 1;
    int key;
    char* in = new char[1000];
    cout << "Base64 Decode & Encode" << endl;
    cout << "1. Decode" << endl;
    cout << "2. Encode" << endl;
    cout << "Please select:"; cin >> key;
    cout << "====================" << endl;
    cout << "input:" << endl;
    cin.get();
    cin.getline(in, 1000);
    cout << endl;

    switch (key){
    case 1:
        cout << "Result:" << endl;
        for (i = 0; in[i] != NULL; i++, x++){
            for (int j = 0; j <= EZ; j++){
                if ((char)in[i] == (char)CODE[j]){
                    Decode(j, x);
                    if (x == 4) x = 0;
                }
            }
        }
        if (x != 1){
            for (int j = 1; j <= 3; j++){
                if (x == 2 * j) cout << (D << 2 * j);
            }
        }
        break;

    case 2:
        cout << "Base64:" << endl;
        for (i = 0; in[i] != NULL; i++, x++){
            cout << CODE[Encode(in[i], x)];
            if (x == 3) {
                x = 0;
                cout << CODE[E];
                E = NULL;
            };
        }
        if (x != 1){
            cout << CODE[E];
            if (i * 8 % 6 == 2)cout << "==";
            else if (i * 8 % 6 == 4)cout << "=";
        }
        break;

    default:
        cout << "Input Error!!";
        system("pause");
        return 1;
    }
    delete in;
    return 0;
}

程式解說

先定義編碼表,透過變數 “key” 來選擇要編碼還是解碼,然後編解碼的部分運用全域變數來暫存溢位的部分,編碼部分需而外計算補多少 0 來補 “=”,解碼部分則可以忽略 “=”。

 

執行畫面

編碼畫面:

解碼畫面:

 

簡易心得

題目出完之後,其實也就開始上 Google、wiki,查詢想要的資訊,主要也是因為這一個題目在網路上較少開放 Code 讓人 copy,大學生作業就是會操來操去的,有一點為班上的人擔憂,以上是題外話,然後接著大約花了半天的時間完成這道題目,其實不難,至於我的 Code 方式,說實在的不是最優的,但至少可以解決這一題的問題,然後在寫程式的過程中,其實也有發現一些不影響的 Bug,但當時只想著快點出題目,然後就衝著去找 TA 了,結果回來後連改都沒改,直接攤著打 LOL :”P。

Exit mobile version