Last active
March 26, 2020 23:16
-
-
Save NotStatilko/1b2e82f26e20a02ee334f9d5076f9486 to your computer and use it in GitHub Desktop.
Permutation.Cipher
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
/* | |
Try on SoloLearn! https://code.sololearn.com/com054IyaO02 | |
| NonSense // Input text | |
| NonSes // Unique symbols | |
| eoSnNs // Shuffled unique #1 | |
| nsNoeS // Shuffled unique #2 | |
|e|o|S|n|N|s| // Pairs (vertical) | |
|n|s|N|o|e|S| // ^^^^^^^^^^^^^^^^ | |
| enosSNnoNesS // Secret Key (based on pairs) | |
! Now, in the text, the letters change based on the pairs. | |
'e' changes to 'n', 'o' to 's', and so on. | |
| NonSense -> Cipher -> esoNnoSn // Encrypted Text | |
*/ | |
#include <algorithm> | |
#include <iostream> | |
#include <cstdlib> | |
#include <ctime> | |
class PermutationCipher{ | |
private: | |
std::string key; | |
std::string text; | |
std::string shuffle(std::string str){ | |
srand(time(0)); | |
std::string shuffled; | |
while (str.size()){ | |
int rnd_indx = 1 + (rand() % str.size() - 1); | |
shuffled += str[rnd_indx]; | |
str.erase(rnd_indx,1); | |
} | |
return shuffled; | |
} | |
std::string cipher(char mode){ | |
std::string encrypted; | |
int key_shift = (mode == 'e' ? 1 : -1); | |
for (char symbol : this->text){ | |
int symbol_position = this->key.find(symbol); | |
bool cipher_mode; | |
if (mode == 'e') | |
cipher_mode = (symbol_position + 1) % 2; | |
else | |
cipher_mode = !((symbol_position + 1) % 2); | |
if (cipher_mode){ | |
encrypted += this->key[symbol_position + key_shift]; | |
} | |
else{ | |
symbol_position = key.find(symbol,symbol_position + 1); | |
encrypted += this->key[symbol_position + key_shift]; | |
} | |
} | |
return encrypted; | |
} | |
public: | |
PermutationCipher(std::string text){ | |
this->text = text; | |
create_key(); | |
} | |
std::string create_key(){ | |
std::string text = this->text; | |
sort(text.begin(), text.end()); // get unique symbols | |
text.erase(unique(text.begin(), text.end()), text.end()); | |
std::string shuffled0 = shuffle(text); // shuffle unique | |
std::string shuffled1 = shuffle(shuffled0); | |
std::string new_key; | |
for (int i = 0; i < shuffled0.size(); i++){ | |
new_key += shuffled0[i]; | |
new_key += shuffled1[i]; | |
} | |
this->key = new_key; | |
return new_key; | |
} | |
void set_key(std::string &key){ | |
this->key = key; | |
} | |
void set_key(std::string key){ | |
this->key = key; | |
} | |
std::string get_key(){ | |
return key; | |
} | |
std::string get_text(){ | |
return text; | |
} | |
std::string encrypt(){ | |
text = cipher('e'); | |
return text; | |
} | |
std::string decrypt(){ | |
text = cipher('d'); | |
return text; | |
} | |
}; | |
int main(void){ | |
PermutationCipher percipher("Hello-World!-I-am-NonSense!"); // Encrypt | |
/* | |
Spaces can be used along with any other characters. | |
I use a dash instead for a more clear output in the terminal. | |
*/ | |
PermutationCipher percipher2(percipher.get_text()); // Decrypt | |
percipher2.set_key(percipher.get_key()); | |
std::cout << "Key: " << percipher.get_key() << std::endl; | |
std::cout << "Encrypted: " << percipher.encrypt() << std::endl; | |
std::cout << "Decrypted: " << percipher.decrypt() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment