Skip to content

Commit d356a17

Browse files
authored
V1.2.0 Safety Update
Round Mix Cipher.
2 parents fb13933 + 4c8ba52 commit d356a17

File tree

3 files changed

+222
-27
lines changed

3 files changed

+222
-27
lines changed

README.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Abracadabra 是表演魔术 (施魔法) 时所念的咒语。
2020
- 随机,加密结果具有随机性。
2121
- 无序,加密的文本如咒语般不可阅读。
2222
- 安心,密码表中已剔除敏感汉字。
23-
- 快速,C++ 快如闪电
23+
- 安全,转轮加密更添破译难度
2424

2525
## 快速使用
2626

@@ -31,7 +31,7 @@ Abracadabra 是表演魔术 (施魔法) 时所念的咒语。
3131

3232
```shell
3333
PS C:\Abracadabra> .\abracadabra.exe -h
34-
***Abracadabra v1.0.3 , by SheepChef***
34+
***Abracadabra v1.2.0 , by SheepChef***
3535
Usage: G:\Code-projects\Abracadabra\abracadabra.exe [OPTIONS] [DEFAULT]
3636

3737
Positionals:
@@ -103,10 +103,31 @@ Abracadabra 还在积极开发中,这里是一些注意事项。
103103
104104
### 加密实现
105105
106-
Abracadabra 使用古老的多表加密,以最常用的 500 个汉字(剔除了可能随机组成敏感词的汉字)为密本,对大小写拉丁字母,阿拉伯数字和部分符号进行映射。
106+
Abracadabra 使用古老的多表加密,以最常用的 3000 个汉字(剔除了可能随机组成敏感词的汉字)为密本,对大小写拉丁字母,阿拉伯数字和部分符号进行映射。
107107
108108
大写字母的映射方式为在小写字母前添加一个汉字的标志位,元音字母有更多的映射可能。
109109
110+
### 单重转轮
111+
112+
模拟古老的转轮加密,每次加密均会对密本映射进行偏移。
113+
114+
密本先向右偏移两位,再向左偏移一位。字母、符号、数字分开轮换。
115+
116+
```
117+
abcdefghijklmnopqrstuvwxyz <-- 原始映射 / 加密第一个字符
118+
119+
cdefghijklmnopqrstuvwxyzab <-- 加密第二个字符 / 右移两位
120+
例如,此时要加密字母a,那么会映射到字母c,再查表。
121+
122+
bcdefghijklmnopqrstuvwxyza <-- 加密第三个字符 / 左移一位
123+
例如,此时要加密字母a,那么会映射到字母b,再查表。
124+
125+
以此类推,循环往复。
126+
127+
```
128+
129+
转轮增加了密文的安全性,可以有效抵抗多种攻击。
130+
110131
### 标志位
111132
112133
使用 日本和制汉字 与 部分生僻字 组成二字标志位,用于标记密文的类型。

src/abracadabra.cpp

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ using base64 = cppcodec::base64_rfc4648;
1717
const string Map = "{\"basic\":{\"alphabet\":{\"a\":[\"请\",\"上\",\"中\",\"之\",\"等\",\"人\",\"到\",\"年\",\"个\",\"将\"],\"b\":[\"得\",\"可\",\"并\",\"发\",\"过\",\"协\",\"曲\",\"闭\",\"斋\",\"峦\"],\"c\":[\"页\",\"于\",\"而\",\"被\",\"无\",\"挽\",\"裕\",\"斜\",\"绪\",\"镜\"],\"d\":[\"由\",\"把\",\"好\",\"从\",\"会\",\"帕\",\"莹\",\"盈\",\"敬\",\"粒\"],\"e\":[\"的\",\"在\",\"了\",\"是\",\"为\",\"有\",\"和\",\"我\",\"一\",\"与\"],\"f\":[\"站\",\"最\",\"号\",\"及\",\"能\",\"迟\",\"鸭\",\"呈\",\"玻\",\"据\"],\"g\":[\"着\",\"很\",\"此\",\"但\",\"看\",\"浩\",\"附\",\"侃\",\"汐\",\"绸\"],\"h\":[\"名\",\"呢\",\"又\",\"图\",\"啊\",\"棉\",\"畅\",\"蒸\",\"玫\",\"添\"],\"i\":[\"对\",\"地\",\"您\",\"给\",\"这\",\"下\",\"网\",\"也\",\"来\",\"你\"],\"j\":[\"更\",\"天\",\"去\",\"用\",\"只\",\"矽\",\"萌\",\"镁\",\"芯\",\"夸\"],\"k\":[\"第\",\"者\",\"所\",\"两\",\"里\",\"氢\",\"羟\",\"纽\",\"夏\",\"春\"],\"l\":[\"自\",\"做\",\"前\",\"二\",\"他\",\"氦\",\"汀\",\"兰\",\"竹\",\"捷\"],\"m\":[\"家\",\"点\",\"路\",\"至\",\"十\",\"锂\",\"羧\",\"暑\",\"夕\",\"振\"],\"n\":[\"区\",\"想\",\"向\",\"主\",\"四\",\"铍\",\"烃\",\"惠\",\"芳\",\"岩\"],\"o\":[\"就\",\"新\",\"吗\",\"该\",\"不\",\"多\",\"还\",\"要\",\"让\",\"大\"],\"p\":[\"小\",\"如\",\"成\",\"位\",\"其\",\"硼\",\"酞\",\"褔\",\"苑\",\"笋\"],\"q\":[\"吧\",\"每\",\"机\",\"几\",\"总\",\"碳\",\"铂\",\"涓\",\"绣\",\"悦\"],\"r\":[\"起\",\"它\",\"内\",\"高\",\"次\",\"氮\",\"铵\",\"奏\",\"鲤\",\"淳\"],\"s\":[\"非\",\"元\",\"类\",\"五\",\"使\",\"氧\",\"醇\",\"迷\",\"霁\",\"琅\"],\"t\":[\"首\",\"进\",\"即\",\"没\",\"市\",\"氖\",\"酯\",\"琳\",\"绫\",\"濑\"],\"u\":[\"后\",\"三\",\"本\",\"都\",\"时\",\"月\",\"或\",\"说\",\"已\",\"以\"],\"v\":[\"种\",\"快\",\"那\",\"篇\",\"万\",\"钠\",\"炔\",\"柯\",\"睿\",\"琼\"],\"w\":[\"长\",\"按\",\"报\",\"比\",\"信\",\"硅\",\"烷\",\"静\",\"欣\",\"束\"],\"x\":[\"再\",\"带\",\"才\",\"全\",\"呀\",\"磷\",\"烯\",\"柔\",\"雪\",\"冰\"],\"y\":[\"业\",\"却\",\"版\",\"美\",\"们\",\"硫\",\"桉\",\"寒\",\"冻\",\"玖\"],\"z\":[\"像\",\"走\",\"文\",\"各\",\"当\",\"氯\",\"缬\",\"妃\",\"琉\",\"璃\"]},\"number\":{\"0\":[\"卡\",\"风\",\"水\",\"放\",\"花\",\"钾\",\"宏\",\"谊\",\"探\",\"棋\"],\"1\":[\"需\",\"头\",\"话\",\"曾\",\"楼\",\"钙\",\"吾\",\"恋\",\"菲\",\"遥\"],\"2\":[\"连\",\"系\",\"门\",\"力\",\"量\",\"钛\",\"苗\",\"氛\",\"鹤\",\"雀\"],\"3\":[\"书\",\"亿\",\"跟\",\"深\",\"方\",\"钒\",\"鸳\",\"鸯\",\"纸\",\"鸢\"],\"4\":[\"若\",\"低\",\"谈\",\"明\",\"百\",\"铬\",\"羯\",\"尧\",\"舜\",\"兆\"],\"5\":[\"关\",\"客\",\"读\",\"双\",\"回\",\"锰\",\"熙\",\"瀚\",\"渊\",\"灯\"],\"6\":[\"较\",\"品\",\"嘛\",\"单\",\"价\",\"钴\",\"阑\",\"珊\",\"雁\",\"鹂\"],\"7\":[\"山\",\"西\",\"动\",\"厂\",\"热\",\"锌\",\"鹃\",\"鸠\",\"昆\",\"仑\"],\"8\":[\"言\",\"笑\",\"度\",\"易\",\"身\",\"镓\",\"乾\",\"坤\",\"澈\",\"饺\"],\"9\":[\"份\",\"星\",\"千\",\"仍\",\"办\",\"锗\",\"彗\",\"聪\",\"慧\",\"磋\"]},\"symbol\":{\"+\":[\"集\",\"费\",\"传\",\"室\",\"拉\",\"瑞\",\"琴\",\"森\",\"辉\"],\"/\":[\"难\",\"界\",\"指\",\"管\",\"具\",\"善\",\"智\",\"蔬\",\"缎\"],\"?\":[\"相\",\"儿\",\"李\",\"早\",\"拿\"],\"-\":[\"科\",\"白\",\"段\",\"飞\",\"住\"],\".\":[\"利\",\"红\",\"板\",\"光\",\"约\"],\"(\":[\"变\",\"款\",\"林\",\"夹\",\"院\"],\")\":[\"服\",\"句\",\"声\",\"务\",\"游\"],\"[\":[\"股\",\"南\",\"社\",\"阿\",\"远\"],\"]\":[\"意\",\"换\",\"些\",\"必\",\"赛\"],\"<\":[\"届\",\"完\",\"乐\",\"彩\",\"讲\"],\">\":[\"展\",\"帮\",\"且\",\"物\",\"班\"],\",\":[\"何\",\"流\",\"密\",\"某\",\"房\"],\"|\":[\"语\",\"亚\",\"常\",\"除\",\"装\"],\"=\":[\"极\",\"载\",\"题\",\"刚\",\"气\",\"程\",\"舒\",\"雅\",\"益\"],\"@\":[\"米\",\"影\",\"德\",\"世\",\"坐\"],\"#\":[\"北\",\"招\",\"短\",\"活\",\"斯\"],\"!\":[\"值\",\"店\",\"树\",\"哪\",\"余\"],\"~\":[\"盘\",\"速\",\"座\",\"求\",\"创\"],\"`\":[\"梦\",\"足\",\"半\",\"视\",\"安\"],\"$\":[\"空\",\"歌\",\"派\",\"顶\",\"登\"],\"%\":[\"夜\",\"云\",\"感\",\"啦\",\"欲\"],\"^\":[\"边\",\"工\",\"眼\",\"街\",\"奖\"],\"&\":[\"获\",\"占\",\"理\",\"任\",\"实\"],\"*\":[\"知\",\"掉\",\"色\",\"讯\",\"克\"],\"_\":[\"直\",\"评\",\"往\",\"层\",\"园\"],\"{\":[\"留\",\"靠\",\"亦\",\"罗\",\"营\"],\"}\":[\"合\",\"尚\",\"产\",\"诚\",\"汨\"],\":\":[\"曱\",\"朩\",\"杉\",\"杸\",\"歩\"],\";\":[\"毋\",\"氕\",\"気\",\"氘\",\"氙\"],\" \":[\"叧\",\"叺\",\"叻\",\"叾\",\"吅\",\"叿\",\"吙\",\"呡\",\"呤\",\"呮\",\"呭\",\"呾\",\"呟\",\"吂\",\"吤\"],\"\\t\":[\"圠\",\"圡\",\"圢\",\"圤\",\"圥\",\"圦\",\"坆\",\"夨\",\"夨\",\"夬\",\"夳\",\"夶\",\"奀\",\"夻\",\"夼\"],\"\\n\":[\"孒\",\"孖\",\"尐\",\"尛\",\"尢\",\"尣\",\"巛\",\"巜\",\"幷\",\"弐\",\"彑\",\"彡\",\"彳\",\"忄\",\"扖\"]}},\"link\":{\"http\":[\"贴\",\"则\",\"老\",\"生\",\"达\"],\"://\":[\"商\",\"行\",\"周\",\"证\",\"经\"],\"magnet\":[\"事\",\"场\",\"同\",\"化\",\"找\"],\"udp\":[\"建\",\"手\",\"道\",\"间\",\"式\"],\"tcp\":[\"特\",\"城\",\"型\",\"定\",\"接\"],\"ftp\":[\"局\",\"问\",\"重\",\"叫\",\"通\"],\":?xt=urn:btih:\":[\"件\",\"少\",\"面\",\"金\",\"近\"],\"torrent\":[\"买\",\"听\",\"学\",\"见\",\"称\"],\"www\":[\"写\",\"选\",\"片\",\"体\",\"组\"],\"mailto\":[\"先\",\"仅\",\"别\",\"表\",\"现\"]},\"special\":{\"BIG\":[\"未\",\"哦\",\"部\",\"项\",\"谁\",\"分\",\"转\",\"字\",\"数\",\"心\",\"子\",\"处\",\"作\",\"因\",\"设\",\"环\",\"青\",\"雨\",\"泊\",\"注\",\"织\",\"赴\",\"茶\"],\"TYPE\":{\"LINK\":[\"应畑\",\"的凪\",\"开辺\",\"录込\",\"飞飴\",\"应仮\",\"的実\",\"开雫\",\"录気\",\"飞抜\",\"应杁\"],\"NORMAL\":[\"钟込\",\"均桜\",\"错桜\",\"妳桜\",\"钟飴\",\"均仮\",\"错実\",\"妳雫\",\"钟気\",\"均抜\",\"错杁\"],\"BASE64\":[\"奂込\",\"妍桜\",\"姾凪\",\"娂辺\",\"奂飴\",\"妍仮\",\"姾実\",\"娂雫\",\"奂気\",\"妍抜\",\"姾杁\"],\"DECRYPT\":[\"飞込\",\"电桜\",\"亖凪\",\"冇辺\",\"亖飴\",\"电仮\",\"飞実\",\"冇雫\",\"亖気\",\"电抜\",\"飞杁\"]}}}"; //字符串映射表
1818
const json Map_Obj = json::parse(Map); //JSON字符串映射表对象
1919

20+
int RoundFlip = 0;
2021
const string Normal_Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+=_-/?.>,<|`~!@#$%^&*(){}[];: \n\t1234567890"; //表内有映射的所有字符组成的字符串
2122
const string LETTERS = "abcdefghijklmnopqrstuvwxyz";
23+
string LETTERS_ROUND = "abcdefghijklmnopqrstuvwxyz";
2224
const string BIG_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2325
const string NUMBERS = "1234567890";
26+
string NUMBERS_ROUND = "1234567890";
2427
const string SYMBOLS = "+=_-/?.>,<|`~!@#$%^&*(){}[];: \n\t";
28+
string SYMBOLS_ROUND = "+=_-/?.>,<|`~!@#$%^&*(){}[];: \n\t";
2529
const string SIG_LINK = "应畑,的凪,开辺,录込,飞飴,应仮,的実,开雫,录気,飞抜,应杁";//链接类型的标志位列表
2630
const string SIG_NORMAL = "钟込,均桜,错桜,妳桜,钟飴,均仮,错実,妳雫,钟気,均抜,错杁";//普通类型的标志位列表
2731
const string SIG_BASE64 = "奂込,妍桜,姾凪,娂辺,奂飴,妍仮,姾実,娂雫,奂気,妍抜,姾杁";//Base64类型的标志位列表
@@ -57,11 +61,16 @@ string UrlEncode(const string& szToEncode);
5761
std::string GbkToUtf8(const char* src_str);
5862
std::vector<BYTE> readFile(const char* filename);
5963
PreCheckResult preCheck(string input);
64+
void rotateString(std::string& str);
65+
void LrotateString(std::string& str);
66+
inline string RoundKeyMatch(string keyIn);
67+
inline string DRoundKeyMatch(string keyIn);
68+
inline void RoundKey();
6069

6170

6271
int main(int argc, char *argv[]){
6372
SetConsoleOutputCP(CP_UTF8); //注意,由于使用了Windows.h,这个版本仅能在Windows平台使用。
64-
CLI::App app{"***Abracadabra v1.0.3***"}; //CLI11提供的命令行参数解析
73+
CLI::App app{"***Abracadabra v1.2.0***"}; //CLI11提供的命令行参数解析
6574

6675
string arg1 = "";
6776
PreCheckResult input;
@@ -338,6 +347,7 @@ string enMap(PreCheckResult input,bool forceLink,bool forceBase64,bool forceDire
338347
//加密操作开始
339348
//把加密字符加到结果字符串的后面
340349
TempStr1.append(GetCryptedText(temp));
350+
RoundKey();
341351

342352
i += cplen;
343353
}
@@ -459,10 +469,16 @@ DemapResult deMap(PreCheckResult input){
459469
strupr((char*)findtemp.c_str());
460470
//把找到的原文增加到字符串上
461471
TempStr1.append(findtemp);
472+
if(findtemp.length() <= 1){
473+
RoundKey();//轮换密钥
474+
}
462475
i = i + cplen + cplen2; //跳过两个字段
463476
continue;
464477
}else{
465478
TempStr1.append(findtemp); //把找到的原文增加到字符串上
479+
if(findtemp.length() <= 1){
480+
RoundKey();//轮换密钥
481+
}
466482
i+=cplen;
467483
continue;
468484
}
@@ -513,28 +529,28 @@ string GetCryptedText(string letter){//查表返回加密之后的字符串
513529
for (auto& el : Map_Obj["basic"]["alphabet"].items())
514530
{
515531
if(el.key() == letter){
516-
RandIndex = GetRandomIndex(el.value().size()); //随机获取一个下标
517-
return Map_Obj["basic"]["alphabet"][letter][RandIndex];
532+
RandIndex = GetRandomIndex(Map_Obj["basic"]["alphabet"][RoundKeyMatch(el.key())].size()); //随机获取一个下标
533+
return Map_Obj["basic"]["alphabet"][RoundKeyMatch(el.key())][RandIndex];
518534
}else if(letter[0] == toupper(el.key()[0])){//碰到大写字母
519-
RandIndex = GetRandomIndex(el.value().size());
535+
RandIndex = GetRandomIndex(Map_Obj["basic"]["alphabet"][RoundKeyMatch(el.key())].size());
520536
RandIndex2 = GetRandomIndex(Map_Obj["special"]["BIG"].size());
521-
return (string)Map_Obj["special"]["BIG"][RandIndex2] + (string)Map_Obj["basic"]["alphabet"][el.key()][RandIndex];
537+
return (string)Map_Obj["special"]["BIG"][RandIndex2] + (string)Map_Obj["basic"]["alphabet"][RoundKeyMatch(el.key())][RandIndex];
522538
}
523539
}
524540
}else if(NUMBERS.find(letter) != string::npos){
525541
for (auto& el : Map_Obj["basic"]["number"].items())
526542
{
527543
if(el.key() == letter){
528-
RandIndex = GetRandomIndex(el.value().size()); //随机获取一个下标
529-
return Map_Obj["basic"]["number"][letter][RandIndex];
544+
RandIndex = GetRandomIndex(Map_Obj["basic"]["number"][RoundKeyMatch(el.key())].size()); //随机获取一个下标
545+
return Map_Obj["basic"]["number"][RoundKeyMatch(el.key())][RandIndex];
530546
}
531547
}
532548
}else if(SYMBOLS.find(letter) != string::npos){
533549
for (auto& el : Map_Obj["basic"]["symbol"].items())
534550
{
535551
if(el.key() == letter){
536-
RandIndex = GetRandomIndex(el.value().size()); //随机获取一个下标
537-
return Map_Obj["basic"]["symbol"][letter][RandIndex];
552+
RandIndex = GetRandomIndex(Map_Obj["basic"]["symbol"][RoundKeyMatch(el.key())].size()); //随机获取一个下标
553+
return Map_Obj["basic"]["symbol"][RoundKeyMatch(el.key())][RandIndex];
538554
}
539555
}
540556
}
@@ -551,23 +567,23 @@ string FindOriginText(string letter){
551567
for (auto ell : el.value()){
552568
string str = (string)ell;
553569
if(letter == str){
554-
return el.key();
570+
return DRoundKeyMatch(el.key());
555571
}
556572
}
557573
}
558574
for (auto& el : Map_Obj["basic"]["number"].items()){
559575
for (auto ell : el.value()){
560576
string str = (string)ell;
561577
if(letter == str){
562-
return el.key();
578+
return DRoundKeyMatch(el.key());
563579
}
564580
}
565581
}
566582
for (auto& el : Map_Obj["basic"]["symbol"].items()){
567583
for (auto ell : el.value()){
568584
string str = (string)ell;
569585
if(letter == str){
570-
return el.key();
586+
return DRoundKeyMatch(el.key());
571587
}
572588
}
573589
}
@@ -650,6 +666,76 @@ std::vector<BYTE> readFile(const char* filename)
650666
return std::vector<BYTE>((std::istreambuf_iterator<char>(file)),
651667
std::istreambuf_iterator<char>());
652668
}
669+
670+
void rotateString(std::string& str) { //循环右移字符串
671+
str.append(str, 0, 2); // 将字符串的前2个字符追加到字符串的末尾
672+
str.erase(0, 2); // 从字符串开头删除前2个字符
673+
}
674+
675+
void LrotateString(std::string& str) { //循环左移字符串
676+
// 将字符串分为两部分
677+
int size = str.length();
678+
// 交换两部分的位置
679+
str.append(str.substr(0,size-1));
680+
str.erase(0,size-1);
681+
}
682+
683+
inline string RoundKeyMatch(string keyIn){ //查询轮换密钥的键值
684+
685+
size_t idx,idx2,idx3;
686+
687+
idx = LETTERS.find(keyIn);
688+
idx2 = NUMBERS.find(keyIn);
689+
idx3 = SYMBOLS.find(keyIn);
690+
691+
if(idx != string::npos){//判断给定字符的类型
692+
return LETTERS_ROUND.substr(idx,1);
693+
}else if(idx2 != string::npos){
694+
return NUMBERS_ROUND.substr(idx2,1);
695+
}else if(idx3 != string::npos){
696+
return SYMBOLS_ROUND.substr(idx3,1);
697+
}
698+
699+
return NULL_STR;
700+
701+
}
702+
703+
inline string DRoundKeyMatch(string keyIn){ //查询轮换密钥的键值
704+
705+
size_t idx,idx2,idx3;
706+
707+
idx = LETTERS_ROUND.find(keyIn);
708+
idx2 = NUMBERS_ROUND.find(keyIn);
709+
idx3 = SYMBOLS_ROUND.find(keyIn);
710+
711+
if(idx != string::npos){//判断给定字符的类型
712+
return LETTERS.substr(idx,1);
713+
714+
}else if(idx2 != string::npos){
715+
return NUMBERS.substr(idx2,1);
716+
717+
}else if(idx3 != string::npos){
718+
return SYMBOLS.substr(idx3,1);
719+
}
720+
return NULL_STR;
721+
}
722+
inline void RoundKey(){ //轮换密钥
723+
if(RoundFlip == 0){ //先向右移两位
724+
rotateString(LETTERS_ROUND);
725+
rotateString(NUMBERS_ROUND);
726+
rotateString(SYMBOLS_ROUND);
727+
RoundFlip = 1;
728+
return;
729+
}else if(RoundFlip == 1){ //再向左移一位
730+
LrotateString(LETTERS_ROUND);
731+
LrotateString(NUMBERS_ROUND);
732+
LrotateString(SYMBOLS_ROUND);
733+
RoundFlip = 0;
734+
return;
735+
}
736+
}
737+
738+
653739
inline int GetRandomIndex(int length){
654740
int Rand = distribution(generator);
655741
return Rand % length;

0 commit comments

Comments
 (0)