66#include < codecvt>
77#include < random>
88#include < Windows.h>
9+ #include < ctime>
910#include < nlohmann/json.hpp>
1011#include < cppcodec/base64_rfc4648.hpp>
1112#include < CLI11.hpp>
@@ -27,6 +28,10 @@ const string SIG_BASE64 = "奂込,妍桜,姾凪,娂辺,奂飴,妍仮,姾実,娂
2728const string SIG_DECRYPT = " 飞込,电桜,亖凪,冇辺,亖飴,电仮,飞実,冇雫,亖気,电抜,飞杁" ;// 加密字符串的标志位列表
2829const string NULL_STR = " 孎" ; // 默认忽略的占位字符,一个生僻字。
2930
31+ random_device rd;
32+ mt19937 generator (rd());
33+ uniform_int_distribution<int > distribution (0 , 10000 );
34+
3035struct PreCheckResult { // 专门用来打包传递预检的结果
3136 string output;
3237 bool isUnNormal = false ; // 判断是否含有特殊符号(表外内容)
@@ -47,16 +52,16 @@ DemapResult deMap(PreCheckResult input);
4752string FindOriginText (string letter);
4853string GetCryptedText (string letter);
4954string GetLinkCryptedText (string text);
55+ int GetRandomIndex (int length);
5056string UrlEncode (const string& szToEncode);
51- string UrlDecode (const string& szToDecode);
5257std::string GbkToUtf8 (const char * src_str);
5358std::vector<BYTE> readFile (const char * filename);
5459PreCheckResult preCheck (string input);
5560
5661
5762int main (int argc, char *argv[]){
5863 SetConsoleOutputCP (CP_UTF8); // 注意,由于使用了Windows.h,这个版本仅能在Windows平台使用。
59- CLI::App app{" ***Abracadabra v0.2.1 ***" }; // CLI11提供的命令行参数解析
64+ CLI::App app{" ***Abracadabra v0.2.5 ***" }; // CLI11提供的命令行参数解析
6065
6166 string arg1 = " " ;
6267 PreCheckResult input;
@@ -65,8 +70,8 @@ int main(int argc, char *argv[]){
6570 string::size_type idx;
6671 ofstream outfile;
6772 vector<BYTE> inputfiledata;
68-
6973
74+
7075 // 定义命令行参数
7176 CLI::Option* i2flag = app.add_option (" DEFAULT" , i2, " Input text, if there is no given option besides." );
7277 CLI::Option* lflag = app.add_flag (" -l" , l, " Force to encrypt using url mode" );
@@ -312,25 +317,14 @@ string enMap(PreCheckResult input,bool forceLink,bool forceBase64,bool forceDire
312317 forceBase64 = true ;
313318 }
314319 int size = OriginStr.length ();
320+
315321 for (int i=0 ;i<size;){
316322 int cplen = 1 ; // 该死的C++,处理中文字符贼繁琐
317- int cplen2 = 1 ;
318323 if ((OriginStr[i] & 0xf8 ) == 0xf0 ) cplen = 4 ;
319324 else if ((OriginStr[i] & 0xf0 ) == 0xe0 ) cplen = 3 ;
320325 else if ((OriginStr[i] & 0xe0 ) == 0xc0 ) cplen = 2 ;
321326 if ((i + cplen) > OriginStr.length ()) cplen = 1 ;
322-
323- if ((OriginStr[i+cplen] & 0xf8 ) == 0xf0 ) cplen2 = 4 ;
324- else if ((OriginStr[i+cplen] & 0xf0 ) == 0xe0 ) cplen2 = 3 ;
325- else if ((OriginStr[i+cplen] & 0xe0 ) == 0xc0 ) cplen2 = 2 ;
326- if ((i + cplen + cplen) > OriginStr.length ()) cplen2 = 1 ;
327327 temp = OriginStr.substr (i, cplen);
328- if (i != size - cplen2){ // 一次遍历两个字符,遇到倒数第一个的时候防止越界
329- temp2 = OriginStr.substr (i+cplen, cplen2);
330- }else {
331- temp2 = NULL_STR;
332- }
333- group = temp + temp2;
334328
335329 // 到这儿循环的取字部分就完成了
336330 // temp是前一个字,temp2是后一个字
@@ -345,13 +339,7 @@ string enMap(PreCheckResult input,bool forceLink,bool forceBase64,bool forceDire
345339 TempStr1 = TempStr1 + GetCryptedText (temp); // 把加密字符加到结果字符串的后面
346340 i += cplen;
347341 }
348-
349342 // 第一个循环结束后,TempStr1应当是完全的密文,但是缺少标志位
350- // 随机选择一个下标
351- random_device rd;
352- unsigned int seed = rd ();
353- mt19937 mt_r (seed);
354- uniform_int_distribution<long long > dist (1 , 10000 );
355343 int RandIndex,RandIndex2;
356344 vector<int > Avoid;
357345 for (int q=0 ;q<2 ;q++){// 分两次大循环
@@ -372,78 +360,40 @@ string enMap(PreCheckResult input,bool forceLink,bool forceBase64,bool forceDire
372360 i += cplen;
373361 PosToInset.push_back (i);
374362 }
375- vector<string> CipherArray,CipherArray2;
376363 int i;
377364 if (q==0 ){// 第一次大循环插入模式标志位
378- RandIndex = PosToInset.at (dist (mt_r) % PosToInset.size ());// 在所有可插入位置中随便选一个
365+ RandIndex = PosToInset.at (GetRandomIndex ( PosToInset.size () ));// 在所有可插入位置中随便选一个
379366 if (forceDirect){// 无处理特殊字符标志位
380- Map_Obj[" special" ][" TYPE" ][" NORMAL" ].get_to (CipherArray);
381- RandIndex2 = dist (mt_r) % CipherArray.size ();// 随机获取一个下标
382- i = 0 ;
383- for (auto el : Map_Obj[" special" ][" TYPE" ][" NORMAL" ]){// 遍历列表
384- if (i == RandIndex2){
385- TempStr1.insert (RandIndex,(string)el);
386- string stemp = (string)el;
387- for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
388- Avoid.push_back (z);
389- }
390- break ;
391- }
392- i++;
393- }
367+ RandIndex2 = GetRandomIndex (Map_Obj[" special" ][" TYPE" ][" NORMAL" ].size ());// 随机获取一个下标
368+ string stemp = (string)Map_Obj[" special" ][" TYPE" ][" NORMAL" ][RandIndex2];
369+ TempStr1.insert (RandIndex,stemp);
370+ for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
371+ Avoid.push_back (z);
372+ }
394373 }else if (forceLink){ // 链接模式标志位
395- Map_Obj[" special" ][" TYPE" ][" LINK" ].get_to (CipherArray);
396- RandIndex2 = dist (mt_r) % CipherArray.size ();// 随机获取一个下标
397- i = 0 ;
398- for (auto el : Map_Obj[" special" ][" TYPE" ][" LINK" ]){// 遍历列表
399- if (i == RandIndex2){
400- TempStr1.insert (RandIndex,(string)el);
401- string stemp = (string)el;
402- for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
403- Avoid.push_back (z);
404- }
405- break ;
406- }
407- i++;
408- }
374+ RandIndex2 = GetRandomIndex (Map_Obj[" special" ][" TYPE" ][" LINK" ].size ());// 随机获取一个下标
375+ string stemp = (string)Map_Obj[" special" ][" TYPE" ][" LINK" ][RandIndex2];
376+ TempStr1.insert (RandIndex,stemp);
377+ for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
378+ Avoid.push_back (z);
379+ }
409380 }else if (forceBase64){ // Base64模式标志位
410- Map_Obj[" special" ][" TYPE" ][" BASE64" ].get_to (CipherArray);
411- RandIndex2 = dist (mt_r) % CipherArray.size ();// 随机获取一个下标
412- i = 0 ;
413- for (auto el : Map_Obj[" special" ][" TYPE" ][" BASE64" ]){// 遍历列表
414- if (i == RandIndex2){
415- TempStr1.insert (RandIndex,(string)el);
416- string stemp = (string)el;
417- for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
418- Avoid.push_back (z);
419- }
420- break ;
421- }
422- i++;
423- }
381+ RandIndex2 = GetRandomIndex (Map_Obj[" special" ][" TYPE" ][" BASE64" ].size ());// 随机获取一个下标
382+ string stemp = (string)Map_Obj[" special" ][" TYPE" ][" BASE64" ][RandIndex2];
383+ TempStr1.insert (RandIndex,stemp);
384+ for (int z = RandIndex + 1 ;z < RandIndex + stemp.length ();z++){
385+ Avoid.push_back (z);
386+ }
424387 }
425388 }
426389 else if (q==1 ){ // 第二次大循环插入加密标志位
427-
428-
429390 vector<int > AvailPos;
430391 AvailPos.resize (max (PosToInset.size (),Avoid.size ()));
431-
432392 vector<int >::iterator itEnd = set_difference (PosToInset.begin (), PosToInset.end (), Avoid.begin (), Avoid.end (), AvailPos.begin ());
433-
434393 AvailPos.erase (std::remove (AvailPos.begin (), AvailPos.end (), 0 ), AvailPos.end ());
435- RandIndex = AvailPos.at (dist (mt_r) % AvailPos.size ());// 在所有可插入位置中随便选一个
436-
437- Map_Obj[" special" ][" TYPE" ][" DECRYPT" ].get_to (CipherArray2);
438- RandIndex2 = dist (mt_r) % CipherArray2.size ();// 随机获取一个下标
439- i = 0 ;
440- for (auto el : Map_Obj[" special" ][" TYPE" ][" DECRYPT" ]){// 遍历列表
441- if (i == RandIndex2){
442- TempStr1.insert (RandIndex,(string)el);
443- break ;
444- }
445- i++;
446- }
394+ RandIndex = AvailPos.at (GetRandomIndex (AvailPos.size ()));// 在所有可插入位置中随便选一个
395+ RandIndex2 = GetRandomIndex (Map_Obj[" special" ][" TYPE" ][" DECRYPT" ].size ());// 随机获取一个下标
396+ TempStr1.insert (RandIndex,(string)Map_Obj[" special" ][" TYPE" ][" DECRYPT" ][RandIndex2]);
447397 }
448398 }
449399
@@ -453,7 +403,6 @@ string enMap(PreCheckResult input,bool forceLink,bool forceBase64,bool forceDire
453403DemapResult deMap (PreCheckResult input){
454404 string OriginStr = input.output ;
455405 string TempStr1,TempStrz;
456-
457406 string temp,temp2,group,findtemp;
458407 string::size_type idx;
459408 int size = OriginStr.length ();
@@ -550,28 +499,15 @@ DemapResult deMap(PreCheckResult input){
550499string GetLinkCryptedText (string text){// 查表,检查是否有任何预配置的关键词
551500 string s = text; // 源文本
552501 string s1,s2;
553- random_device rd;
554- unsigned int seed = rd ();
555- mt19937 mt_r (seed);
556- uniform_int_distribution<long long > dist (1 , 10000 );
557- vector<string> CipherArray;
558502 int RandIndex;
559503
560504 for (auto & el : Map_Obj[" link" ].items ()){// 遍历关键词列表
561505 s1 = el.key ();
562506 if (s.find (s1) != string::npos){// 找到关键词
563- el.value ().get_to (CipherArray);
564507 while (s.find (s1)<s.size ()){
565508 // 返回密本中的随机字符
566- RandIndex = dist (mt_r) % CipherArray.size (); // 随机获取一个下标
567- int i = 0 ;
568- for (auto it : Map_Obj[" link" ][s1]){
569- if (i == RandIndex){// 找到下标
570- s2 = (string)it;
571- break ;
572- }
573- i++;
574- }
509+ RandIndex = GetRandomIndex (el.value ().size ()); // 随机获取一个下标
510+ s2 = (string)Map_Obj[" link" ][s1][RandIndex];
575511 int pos = s.find (s1);
576512 s.replace (pos, s1.size (), s2);
577513 }
@@ -583,87 +519,33 @@ string GetLinkCryptedText(string text){//查表,检查是否有任何预配置
583519
584520}
585521string GetCryptedText (string letter){// 查表返回加密之后的字符串
586- random_device rd;
587- unsigned int seed = rd ();
588- mt19937 mt_r (seed);
589- uniform_int_distribution<long long > dist (1 , 10000 );
590-
591- string::size_type idx,idx2,idx3,idx4;
592522 int RandIndex,RandIndex2;
593-
594- idx = LETTERS.find (letter); // 是否是小写字母
595- idx2 = BIG_LETTERS.find (letter); // 是否是大写字母
596- idx3 = NUMBERS.find (letter); // 是否是数字
597- idx4 = SYMBOLS.find (letter); // 是否是符号
598-
599- if (idx != string::npos || idx2 != string::npos){// 判断给定字符的类型
600- string key,keyU;
523+ if (LETTERS.find (letter) != string::npos || BIG_LETTERS.find (letter) != string::npos){// 判断给定字符的类型
601524 for (auto & el : Map_Obj[" basic" ][" alphabet" ].items ())
602- {
603- vector<string> CipherArray;
604- vector<string> CipherArrayBIG;
605- key = el.key ();
606- keyU = (string)key;
607- if (key == letter){
608- el.value ().get_to (CipherArray); // 把密本存进容器里
609- RandIndex = dist (mt_r) % CipherArray.size (); // 随机获取一个下标
610- int i = 0 ;
611- for (auto it : Map_Obj[" basic" ][" alphabet" ][letter]){
612- if (i == RandIndex){
613- return (string)it;
614- }
615- i++;
616- }
617- }else if (strupr ((char *)keyU.c_str ()) == letter){// 碰到大写字母
618- el.value ().get_to (CipherArray);
619- Map_Obj[" special" ][" BIG" ].get_to (CipherArrayBIG);
620- RandIndex = dist (mt_r) % CipherArray.size ();
621- RandIndex2 = dist (mt_r) % CipherArrayBIG.size ();
622- int i = 0 ;
623- for (auto it : Map_Obj[" basic" ][" alphabet" ][key]){
624- if (i == RandIndex){// 选中小写字符的密文
625- int t=0 ;
626- for (auto tt : Map_Obj[" special" ][" BIG" ]){
627- if (t == RandIndex2){// 随机选一个大写标志位
628- return (string)tt + (string)it; // 组合标志位和小写字符密文,返回回去
629- }
630- t++;
631- }
632- }
633- i++;
634- }
525+ {
526+ if (el.key () == letter){
527+ RandIndex = GetRandomIndex (el.value ().size ()); // 随机获取一个下标
528+ return Map_Obj[" basic" ][" alphabet" ][letter][RandIndex];
529+ }else if (letter[0 ] == toupper (el.key ()[0 ])){// 碰到大写字母
530+ RandIndex = GetRandomIndex (el.value ().size ());
531+ RandIndex2 = GetRandomIndex (Map_Obj[" special" ][" BIG" ].size ());
532+ return (string)Map_Obj[" special" ][" BIG" ][RandIndex2] + (string)Map_Obj[" basic" ][" alphabet" ][el.key ()][RandIndex];
635533 }
636534 }
637- }else if (idx3 != string::npos){
535+ }else if (NUMBERS. find (letter) != string::npos){
638536 for (auto & el : Map_Obj[" basic" ][" number" ].items ())
639537 {
640- vector<string> CipherArray;
641- if (el.key () == letter){
642- el.value ().get_to (CipherArray); // 把密本存进容器里
643- RandIndex = dist (mt_r) % CipherArray.size (); // 随机获取一个下标
644- int i = 0 ;
645- for (auto it : Map_Obj[" basic" ][" number" ][letter]){
646- if (i == RandIndex){
647- return it;
648- }
649- i++;
538+ if (el.key () == letter){
539+ RandIndex = GetRandomIndex (el.value ().size ()); // 随机获取一个下标
540+ return Map_Obj[" basic" ][" number" ][letter][RandIndex];
650541 }
651542 }
652- }
653- }else if (idx4 != string::npos){
543+ }else if (SYMBOLS.find (letter) != string::npos){
654544 for (auto & el : Map_Obj[" basic" ][" symbol" ].items ())
655545 {
656- vector<string> CipherArray;
657546 if (el.key () == letter){
658- el.value ().get_to (CipherArray); // 把密本存进容器里
659- RandIndex = dist (mt_r) % CipherArray.size (); // 随机获取一个下标
660- int i = 0 ;
661- for (auto it : Map_Obj[" basic" ][" symbol" ][letter]){
662- if (i == RandIndex){
663- return it;
664- }
665- i++;
666- }
547+ RandIndex = GetRandomIndex (el.value ().size ()); // 随机获取一个下标
548+ return Map_Obj[" basic" ][" symbol" ][letter][RandIndex];
667549 }
668550 }
669551 }
@@ -778,4 +660,8 @@ std::vector<BYTE> readFile(const char* filename)
778660 // read the data:
779661 return std::vector<BYTE>((std::istreambuf_iterator<char >(file)),
780662 std::istreambuf_iterator<char >());
663+ }
664+ inline int GetRandomIndex (int length){
665+ int Rand = distribution (generator);
666+ return Rand % length;
781667}
0 commit comments