diff --git a/Enigma.cpp b/Enigma.cpp new file mode 100644 index 0000000..7346ccf --- /dev/null +++ b/Enigma.cpp @@ -0,0 +1,931 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +//2.5 + +struct enigma { + unsigned long long int seed = 0; //亂數種子 + unsigned int rotors = 1; //轉子數量 + vector number; //轉子號碼 + bool set_switch[5] = {true, false, false, false, false}; //切換([0]小寫、[1]大寫、[2]數字、[3]符號、[4]隱藏輸入) + vector ex_char; //交換線的置換表 + vector> sum_table; //所有轉子的置換表 +} origin, backup, setup, back_setup; //運作, 初始運作, 設定, 原始設定 + +void test(); //測試除錯 + +int rand(); //亂數生成 +void reset(); //重新設定 +void rotor_set(enigma &x); //設定轉子 +void rotor_number(enigma &x); //設定轉子號碼 +void switching_lines(enigma &x); //設定交換線 +void table_creating(); //生成置換表 +void setting(); //細項設定 +void refresh(); //重設ex_record +void lang(); //語言設定 +void rotating(int x); //轉子旋轉 + +bool exactly_equal(enigma x, enigma y); //判斷完全相等 + +unsigned int rotors_max = 10; //轉子上限 +int lang_index = 0; //語言 + +//"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.;:?!+-*/='" \~()[]{}`@#$%^&|<>"; //總交換列表 94 +/* +小寫英文字母 0+(0~25) 26 +大寫英文字母 26+(0~25) 26 +數字 52+(0~9) 10 +標點符號 62+(0~31) 32 +運算符號 68+(0~4) +額外標點符號 73+(0~3) +括號 77+(0~5) +特殊符號 83+(0~9) +空白 93+(0) +*/ +string change_char = "abcdefghijklmnopqrstuvwxyz"; //默認可置換字元 +int ch_lth = 26; //默認change_char長度 +string str_char[4] = {"abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "0123456789", ",.;:?!+-*/=\'\" \\~()[]{}`@#$%^&|<>"}; + +string reading = ""; //輸入字串 +bool ex_record[93] = {0}; //紀錄交換過的位置 +char swch[2] = {1,1}; //交換用暫存 + +vector reflection; //反射表 + +int i = 0; //通用暫存變數 +bool ignore_bug = false; //解決getline後cin會忽視輸入的問題 + +//此處變數皆為生成亂數用 +bool flip = false; //交換XOR/XNOR邏輯防位元循環 +unsigned long long int new_bit; //計算新位元 +unsigned long long int keep_unit; //位移後的數 +unsigned short X; //PRBS的執行位置 +unsigned short X_unit = 1; //位移量 +unsigned short turn_face = 0; //旋轉模式 + +int main() { //主體 + cout<<"Welcome to Enigma II."<= 'A' && word <= 'Z') { //大寫保存 + up = true; + word += 32; + }else if (word == '_') { + up = true; + continue; + } + } + int ind = change_char.find(word); //找index,若找不到則回傳-1 + if (0 <= ind) { //主要功能區 + int index = 0; + ind = origin.ex_char[ind]; //交換線輸入 + for (j = 0 ; j < origin.rotors ; j++) { //置換 + ind = origin.sum_table[j][ind]; + // cout<<"2:"<= 0 ; j--) { //回傳 + ind = find(origin.sum_table[j].begin(), origin.sum_table[j].end(), ind) - origin.sum_table[j].begin(); + // cout<<"4:"<= 0 && ind <= 25) { + ind += 26; + up = false; + }else{ //無法轉大寫 + cout<<"_"; + up = false; + } + } + } + if (ind < 0) { //無法轉換則直接輸出 + cout<> X) ^ (origin.seed >> (X - 1))) & 1; + }else{ + new_bit = ((origin.seed >> X) ^ (origin.seed >> (X - 1))) & 1; + } + if (turn_face == 0) { //0:保右右旋(插左邊) + keep_unit = origin.seed & (0xFFFFFFFF >> X_unit); //刪去左邊X_unit個位元 + origin.seed = ((origin.seed & 0xFFFFFFFF << (65 - X_unit)) >> 1) | keep_unit | (new_bit << 63); //去除右邊、右旋、放置原本位元、將移出的0改為新增位元 + }else if (turn_face == 1) { //1:保右左旋(插中間) + keep_unit = origin.seed & (0xFFFFFFFF >> X_unit); //刪去左邊X_unit個位元 + origin.seed = ((origin.seed & 0xFFFFFFFF << (64 - X_unit)) << 1) | keep_unit | (new_bit << (64 - X_unit)); //去除右邊、左旋、放置原本位元、將移出的0改為新增位元 + }else if (turn_face == 2) { //2:保左右旋(插中間) + keep_unit = origin.seed & (0xFFFFFFFF << X_unit); //刪去右邊X_unit個位元 + origin.seed = ((origin.seed & 0xFFFFFFFF >> (64 - X_unit)) >> 1) | keep_unit | (new_bit << X_unit); //去除左邊、右旋、放置原本位元、將移出的0改為新增位元 + }else if (turn_face == 3) { //3:保左左旋(插右邊) + keep_unit = origin.seed & (0xFFFFFFFF << X_unit); //刪去右邊X_unit個位元 + origin.seed = ((origin.seed & 0xFFFFFFFF >> (65 - X_unit)) << 1) | keep_unit | new_bit; //去除左邊、右旋、放置原本位元、將移出的0改為新增位元 + } + if (origin.seed % 5 == 3) { //機率翻轉 + flip ^= true; + turn_face = (turn_face + 1) % 4; + }else if (origin.seed % 5 == 1) { //機率翻轉 + flip ^= true; + turn_face = (turn_face + 3) % 4; + } + X_unit = (X_unit + X) % 64 + 1; //更新位移量 1~64 + return (unsigned int) (origin.seed / 31) % ch_lth; +} + +void reset() { //基礎設定 + origin.seed = backup.seed; + refresh(); //清除紀錄 + rotor_set(origin); //轉子設定 + switching_lines(origin); //交換線設定 + backup = origin; //保存 + table_creating(); //置換表、反射表生成 + return; +} + +void rotor_set(enigma &x) { //轉子總設定 + switch (lang_index) { //轉子數量 + case 0: //en + cout<<"Please enter the amount of rotors:"; + break; + case 1: //ch + cout<<"請輸入轉子數量:"; + break; + } + do { + cin>>x.rotors; + ignore_bug = true; + if (cin.fail()) { + x.rotors = 0; + cin.clear(); + cin.ignore(); + // fflush(); + } + if (x.rotors > rotors_max) { + switch (lang_index) { + case 0: //en + cout<<"Why do you need so many rotors???"< rotors_max); + cout< 0) { + switch (lang_index) { //每個轉子的起始號碼 + case 0: //en + cout<<"Please enter the start position of "<>storage; + ignore_bug = true; + if (cin.fail()) { + storage = 1; + cin.clear(); + cin.ignore(); + // fflush(); + } + if (storage > 0 && storage <= ch_lth) { + x.number.push_back(storage); + }else{ + switch (lang_index) { + case 0: //en + cout<<"Something went wrong!"<>i; + ignore_bug = true; + if (cin.fail()) { + i = 0; + cin.clear(); + cin.ignore(); + // fflush(); + } + if (i > ch_lth/2 || i < 0) { + switch (lang_index) { + case 0: //en + cout<<"Wrong number."< ch_lth/2 || i < 0); + cout< 0 ; i--) { //交換輸入列表 + switch (lang_index) { + case 0: //en + cout<<"Change letter(x y):"; + break; + case 1: //ch + cout<<"交換字母(x y):"; + break; + } + cin>>swch[0]>>swch[1]; + ignore_bug = true; + if (cin.fail()) { + swch[0] = 'a'; + swch[1] = 'a'; + cin.clear(); + cin.ignore(); + // fflush(); + } + int ind0, ind1; + ind0 = change_char.find(swch[0]); + ind1 = change_char.find(swch[1]); + if (ind0 < ch_lth && ind1 < ch_lth && swch[0] != swch[1]) { + if (ex_record[ind0] || ex_record[ind1]) { + switch (lang_index) { + case 0: //en + cout<<"Some characters have been exchange already!"<()); + refresh(); + for (j = 0 ; j < ch_lth ; j++) { + int storage = rand(); + while (ex_record[storage]){ + storage = rand(); + } + ex_record[storage] = true; + origin.sum_table[i].push_back(storage); + } + origin.sum_table[i].push_back(origin.sum_table[i][0]); + } + backup.sum_table = origin.sum_table; + return; +} + +void rotating(int x) { + for (int j = 0 ; j < ch_lth ; j++) { + origin.sum_table[x][j] = (origin.sum_table[x][j+1] + 1) % ch_lth; + } + origin.sum_table[x][ch_lth] = origin.sum_table[x][0]; +} + +void setting() { //設定 + unsigned int page = 1; + const unsigned int page_max = 2; //最大頁數 + setup = origin; + back_setup = backup; + switch (lang_index) { + case 0: //en + cout<>back_setup.seed; + ignore_bug = true; + if (cin.fail()) { + back_setup.seed = 0; + cin.clear(); + cin.ignore(); + // fflush(); + } + cin.clear(); + // fflush(); + }else if (reading == "3") { //小寫 + setup.set_switch[0] ^= true; + back_setup.set_switch[0] ^= true; + }else if (reading == "4") { //大寫 + setup.set_switch[1] ^= true; + back_setup.set_switch[1] ^= true; + }else if (reading == "5") { //數字 + setup.set_switch[2] ^= true; + back_setup.set_switch[2] ^= true; + }else if (reading == "6") { //標點符號 + setup.set_switch[3] ^= true; + back_setup.set_switch[3] ^= true; + }else if (reading == "7") { //提示顯示 + setup.set_switch[4] ^= true; + back_setup.set_switch[4] ^= true; + }else if (reading == "8") { //設定轉子數量 + system("cls"); + rotor_set(setup); + back_setup.rotors = setup.rotors; + back_setup.number.clear(); + back_setup.number = setup.number; + }else if (reading == "9") { //設定origin轉子位置 + system("cls"); + rotor_number(setup); + }else if (reading == "+") { //第二頁 + page++; + }else{ + no_exist = true; + continue; + } + break; + case 2: + if (reading == "1") { //設定backup轉子位置 + system("cls"); + rotor_number(back_setup); + }else if (reading == "2") { //重接交換線 + system("cls"); + switching_lines(setup); + back_setup.ex_char = setup.ex_char; + }else if (reading == "-") { + page--; + }else{ + no_exist = true; + continue; + } + break; + default: + break; + } + } + } +} + +void refresh() { //重新設定置換紀錄 ++ + int lth = 0, k = 0; + if (origin.set_switch[0]) { //小寫 + for (k = 0 ; k < lth+str_char[0].length() ; k++) { + ex_record[k] = false; + } + lth+=str_char[0].length(); + } + if (origin.set_switch[1]) { //大寫 + for (k = lth ; k < lth+str_char[1].length() ; k++) { + ex_record[k] = false; + } + lth+=str_char[1].length(); + } + if (origin.set_switch[2]) { //數字 + for (k = lth ; k < lth+str_char[2].length() ; k++) { + ex_record[k] = false; + } + lth+=str_char[2].length(); + } + if (origin.set_switch[3]) { //符號 + for (k = lth ; k < lth+str_char[3].length() ; k++) { + ex_record[k] = false; + } + lth+=str_char[3].length(); + } + for (k = lth ; k < 94 ; k++) { + ex_record[k] = true; + } +// for (k = 0 ; k < ch_lth ; k++) { //交換線測試 +// cout<>lang_index; + ignore_bug = true; + if (cin.fail()) { + lang_index = 0; + cin.clear(); + cin.ignore(); + // fflush(); + } + lang_index--; + if (lang_index < 0 || lang_index > 1) { + cout<<"Setting fail."< 1); + cin.clear(); + // fflush(); + return; +} + +void test() { //測試 ++ + int j = 0; //暫存變數 +// for (i = 0 ; i < 100 ; i++) { //亂數測試 +// cout<