Last active
December 28, 2018 17:37
-
-
Save Johann150/54dff73341c22a8797da9fde996a8085 to your computer and use it in GitHub Desktop.
small program that implements some en-/decryption algorithms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
vigen - Vigenère Cipher | |
mat12 - from https://youtu.be/6ZYnA6tguec | |
*/ | |
#include<iostream> | |
#include<string> | |
#include<cmath> | |
#include<random> | |
#include<sstream> | |
#include<ctime> | |
#define COORD(X,Y) (((X)%width)+(Y)*width) | |
void mat12(int,int,std::string&); | |
void _mat12(int,int,int,std::string&); | |
void vigen(std::string key,std::string&); | |
void _vigen(std::string key,std::string&); | |
void usage(char* prog){ | |
std::cout<<"USAGE:\n"<<prog<< | |
" \"<algorithm>\" [\"<message>\"]\n\n" | |
"available en-/decryption algorithms:\n" | |
"\tmat12(<message offset>,<key offset>) mat12 encryption\n" | |
"\t-mat12(<message offset>,<key offset>,<matrix size>) mat12 decryption\n" | |
"\tvigen(<key>) vigenere encryption\n" | |
"\t-vigen(<key>) vigenere decryption\n\n" | |
"<algorithm> can consist of multiple algorithms chained together, e.g.\"vigen(abc)mat12(4,2)\".\n" | |
"The algorithms will be performed on the message in the given order.\n\n" | |
"If no message is entered, the program will prompt for a message when starting."<<std::endl; | |
} | |
int main(int argc,char** argv){ | |
std::string message=""; | |
if(argc==1){ | |
// nothing was provided | |
usage(argv[0]); | |
return 1; | |
} | |
if(argc==2){ | |
// message was not provided | |
std::cout<<"message> "; | |
std::getline(std::cin,message); | |
}else{ | |
message=argv[2]; | |
} | |
if(message.length()==0){ | |
usage(argv[0]); | |
return 2; | |
} | |
std::stringstream strs; | |
strs<<argv[1]; | |
while(strs.peek()!=-1){ | |
std::string s; | |
std::getline(strs,s,'('); | |
if(s=="mat12"){ | |
int m,k; | |
strs>>m; | |
strs.ignore(255,','); | |
strs>>k; | |
strs.ignore(255,')'); | |
mat12(m,k,message); | |
}else if(s=="-mat12"){ | |
int m,k,s; | |
strs>>m; | |
strs.ignore(255,','); | |
strs>>k; | |
strs.ignore(255,','); | |
strs>>s; | |
strs.ignore(255,')'); | |
_mat12(m,k,s,message); | |
}else if(s=="vigen"){ | |
std::string k; | |
std::getline(strs,k,')'); | |
vigen(k,message); | |
}else if(s=="-vigen"){ | |
std::string k; | |
std::getline(strs,k,')'); | |
_vigen(k,message); | |
}else{ | |
std::cout<<"unknown encryption \""<<s<<"\"; ignored"<<std::endl; | |
return 1; | |
} | |
} | |
std::cout<<message<<std::endl; | |
return 0; | |
} | |
void mat12(int m,int k,std::string& message){ | |
if(m<0||k<=0){ | |
std::cout<<"invalid keys for mat12; mat12 skipped"<<std::endl; | |
return; | |
}else if(message.empty()){ | |
return; | |
} | |
int width=message.length(); | |
// random numbers | |
std::mt19937 rng; | |
std::random_device rd; | |
if(rd.entropy()==0.0){ | |
std::cout<<"CAUTION: No random device available. Using system time to seed random number generation instead.\n"; | |
rng.seed(time(nullptr)); | |
}else{ | |
rng.seed(std::random_device()()); | |
} | |
std::uniform_int_distribution<std::mt19937::result_type> dist(0,width-1); | |
std::uniform_int_distribution<std::mt19937::result_type> char_dist(32,126); | |
// +1 for null terminator | |
char matrix[width*width+1]{0}; | |
for(int i=0;i<message.size();++i){ | |
// set message letter | |
char c=message[i]; | |
matrix[COORD(m,i)]=c; | |
// random next message position | |
int new_m=dist(rng); | |
// set key letter | |
matrix[COORD(m+k,i)]=c+(new_m-m); | |
m=new_m; | |
for(int j=0;j<width;++j){ | |
if(matrix[COORD(j,i)]==0){ | |
matrix[COORD(j,i)]=char_dist(rng); | |
} | |
} | |
} | |
message=matrix; | |
} | |
void _mat12(int m,int k,int width,std::string& message){ | |
if(m<0||k<=0||width<=0){ | |
std::cout<<"invalid keys for -mat12; -mat12 skipped"<<std::endl; | |
return; | |
}else if(message.empty()){ | |
return; | |
} | |
std::stringstream strs; | |
for(int i=0;i<width;++i){ | |
// find message letter | |
char msg=message[COORD(m,i)]; | |
strs<<msg; | |
if(COORD(m+k,i)<message.size()){ | |
// find key letter | |
char key=message[COORD(m+k,i)]; | |
// compute next column from key | |
m+=key-msg; | |
}else{ | |
break; | |
} | |
} | |
message=strs.str(); | |
} | |
void vigen(std::string key,std::string& message){ | |
if(key.empty()){ | |
std::cout<<"invalid key for vigen; vigen skipped"; | |
return; | |
}else if(message.empty()){ | |
return; | |
} | |
size_t k=0; | |
for(size_t i=0;i<message.size();++i){ | |
message[i]+=key[k]-' '; | |
k=(k+1)%key.size(); | |
} | |
} | |
void _vigen(std::string key,std::string& message){ | |
if(key.empty()){ | |
std::cout<<"invalid key for -vigen; -vigen skipped"; | |
return; | |
}else if(message.empty()){ | |
return; | |
} | |
size_t k=0; | |
for(size_t i=0;i<message.size();++i){ | |
message[i]-=key[k]-' '; | |
k=(k+1)%key.size(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment