Skip to content

Instantly share code, notes, and snippets.

@akasakakona
Last active July 9, 2023 07:00
Show Gist options
  • Save akasakakona/b223e801a5b6857abf82eae4d4fa31b6 to your computer and use it in GitHub Desktop.
Save akasakakona/b223e801a5b6857abf82eae4d4fa31b6 to your computer and use it in GitHub Desktop.
Witch From Mercury DNA Cipher Encode/Decode C++ Implementation

Witch From Mercury DNA Cipher Encode/Decode C++ Implementation

Simple Explanation of the DNA Cipher

  1. Each character is expressed by a 3-letter codon.
  2. Each codon is expressed by a 3-digit number in base 4. A is 0, C is 1, G is 2, T is 3.
    • Example: ACG = 0*4^2 + 1*4^1 + 2*4^0 = 6, which represents the 7th letter of the alphabet, G. (since we start from 0)
  3. Lower case letters are expressed by the numbers 0-25, upper case letters are expressed by the numbers 37-62. So lower case start with AAA and upper case start with GCC.
  4. The numbers 26-30 represent the characters ' ', '.', ',', '!', and '?' respectively.
  5. The numbers 31-36 are not used, so are numbers greater than 62.

Usage

Simply compile the program using GCC and run it. It will prompt you for a message to encode or decode, and then it will print the result.

Example

Take this screenshot from the anime as an example: vlcsnap-2023-07-06-23h21m09s201 It should produce the following result:

Enter 'encode' or 'decode': decode
Enter DNA code: GTCCGGCCGAGAAGTAGTCGGAAAAGTCCGAAACGAC
Message: I will alway
Would you like to encode/decode another message? (y/n): y

Enter 'encode' or 'decode': decode
Enter DNA code: GTAATGCCGCGGAAACACACACGGATGCCACACCGGCATATGATAAAACATATGACACAGCTG
Message: How are our tomatoes?
Would you like to encode/decode another message? (y/n): y

Enter 'encode' or 'decode': encode
Enter message: How are our tomatoes?
DNA code: GTAATGCCGCGGAAACACACACGGATGCCACACCGGCATATGATAAAACATATGACACAGCTG
Would you like to encode/decode another message? (y/n): n

Credits

#include <iostream>
#include <cmath>
void validateDNA(std::string& s);
void validateMSG(std::string& s);
void decode(std::string& s);
void encode(std::string& s);
int main() {
do{
std::string mode = "";
do{
std::cout << "Enter 'encode' or 'decode': ";
std::cin >> mode;
if(mode != "encode" && mode != "decode"){
std::cout << "Invalid mode. Please try again." << std::endl;
mode.clear();
}
}while(mode.empty());
std::cin.ignore();
if(mode == "encode"){
std::string msg = "";
do{
std::cout << "Enter message: ";
std::getline(std::cin, msg);
validateMSG(msg);
if(msg.empty()){
std::cout << "Invalid message. Please try again." << std::endl;
}
}while(msg.empty());
encode(msg);
}
else if(mode == "decode"){
std::string code = "";
do{
std::cout << "Enter DNA code: ";
std::cin >> code;
validateDNA(code);
if(code.empty()){
std::cout << "Invalid code. Please try again." << std::endl;
}
}while(code.empty());
decode(code);
}
std::cout << "Would you like to encode/decode another message? (y/n): ";
char c;
std::cin >> c;
if(c == 'n'){
break;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << std::endl;
}while(true);
}
void decode(std::string& s){
std::string codon = "";
std::string message = "";
for(size_t i = 0; i < s.length(); i+=3){
unsigned val = 0;
codon = s.substr(i, 3);
for(size_t j = 0; j < codon.length(); j++){
switch(codon[j]){
case 'A':
val += 0;
break;
case 'C':
val += 1 * pow(4, 2-j);
break;
case 'G':
val += 2 * pow(4, 2-j);
break;
case 'T':
val += 3 * pow(4, 2-j);
break;
}
}
if(val > 36 && val < 63){
message += 'A' + val - 37;
}
else if(val < 26){
message += 'a' + val;
}
else if(val >= 26 && val < 31){
switch(val){
case 26:
message += ' ';
break;
case 27:
message += '.';
break;
case 28:
message += ',';
break;
case 29:
message += '!';
break;
case 30:
message += '?';
break;
}
}
else{
std::cout << "Invalid DNA codon: " << codon << ". Replacing with '*'." << std::endl;
message += '*';
}
}
std::cout << "Message: " << message << std::endl;
}
void validateDNA(std::string& s){
for(size_t i = 0; i < s.length(); i++){
if(s[i] != 'A' && s[i] != 'C' && s[i] != 'G' && s[i] != 'T'){
s.clear();
return;
}
}
if(s.length() % 3 != 0){
s = s.substr(0, s.length() - (s.length() % 3));
}
}
void validateMSG(std::string& s){
for(size_t i = 0; i < s.length(); i++){
if(!isalpha(s[i]) && s[i] != ' ' && s[i] != '.' && s[i] != ',' && s[i] != '!' && s[i] != '?'){
s.clear();
}
}
}
void encode(std::string& s){
std::string code = "";
for(size_t i = 0; i < s.length(); i++){
unsigned val = 0;
if(isupper(s[i])){
val = s[i] - 'A' + 37;
}
else if(islower(s[i])){
val = s[i] - 'a';
}
else{
switch(s[i]){
case ' ':
val = 26;
break;
case '.':
val = 27;
break;
case ',':
val = 28;
break;
case '!':
val = 29;
break;
case '?':
val = 30;
break;
}
}
std::string codon = std::string(3, ' ');
for(size_t j = 0; j < 3; j++){
switch(val % 4){
case 0:
codon[2-j] = 'A';
break;
case 1:
codon[2-j] = 'C';
break;
case 2:
codon[2-j] = 'G';
break;
case 3:
codon[2-j] = 'T';
break;
}
val /= 4;
}
code += codon;
}
std::cout << "DNA code: " << code << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment