Skip to content

Instantly share code, notes, and snippets.

@Johann150
Last active December 28, 2018 17:37
Show Gist options
  • Save Johann150/54dff73341c22a8797da9fde996a8085 to your computer and use it in GitHub Desktop.
Save Johann150/54dff73341c22a8797da9fde996a8085 to your computer and use it in GitHub Desktop.
small program that implements some en-/decryption algorithms
/*
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