#include <string>
#include <iostream>
#include <vector>
std::string decode(const std::string &in);
void selector();
void options();
std::string encode(const std::string &in);
std::string standardize(std::string raw);
void factorize(int64_t num);
bool isPrime(int64_t num);
bool quit = false;

////THIS PROGRAM IS IN BETA AND SHOULD NOT BE SHARED WITH ANYONE THAT IS NOT A DEVELOPER!
////THIS PROGRAM ENCODES, DECODES, AND FACTORIZES STATION INTELLIGENCE USING SECURE, TOP SECRET ALGORITHMS UNBREAKABLE WITHOUT THIS PROGRAM.

////DO NOT RUN WITHOUT AUTHORIZATION: PROGRAM CRITICAL TO SECRET INTELLIGENCE!!
////ANY MODIFICATIONS TO PROGRAM WILL RESULT IN FAILURE DURING RUNTIME, CODE IS PURPOSELY UNMODIFIABLE AND ENCODED TO REMAIN SECURE (PROGRAM WILL DECODE DATA AUTOMATICALLY)!
int main() {
   std::cout << decode("V2VsY29tZSB0byB0aGUgU3BhY2UgU3RhdGlvbiBQcml2YXRlIEVuY29kaW5nIGFuZCBDcmFja2VyIFN5c3RlbSAoU1NQRUNTKQ==") << "\n";
   std::cout << "-------------------------------------------------------------------------" << "\n";

   while (!quit)
      selector();

   return 0;
}

//COMMAND SELECT - AVAILABLE COMMANDS TO BE CHOSEN
void selector() {
   std::cout << "\n";
   std::cout << decode("RW50ZXIgYSB0YXNrIG9yIHR5cGUgJ29wdGlvbnMnIGZvciBhIGNvbW1hbmQgbGlzdDog");
   std::string in;
   std::cin >> in;
   in = standardize(in);

   if (in == decode("ZW5jb2Rl")) {
      std::cout << "\n";
      std::cout << decode("U3RyaW5nIHRvIGJlIGVuY29kZWQgKG5vIHNwYWNlcyk6IA==");
      std::cin >> in;
      for (int i = 0; i < 10; ++i)
         in = encode(in);
      std::cout << "\n";
      std::cout << decode("T3V0cHV0OiA=") << in << "\n";
   }

   if (in == decode("ZmFjdG9yaXpl")) {
      std::cout << "\n";
      std::cout << decode("V2hhdCBudW1iZXIgd291bGQgeW91IGxpa2UgdG8gZmFjdG9yaXplOiA=");
      std::cin >> in;
      std::cout << "\n";
      factorize(stoll(in));
   }

   if (in == decode("b3B0aW9ucw=="))
      options();

   if (in == decode("ZGVjb2Rl")) {
      std::cout << "\n";
      std::cout << decode("U3RyaW5nIHRvIGJlIGRlY29kZWQ6IA==");
      std::cin >> in;
      for (int i = 0; i < 10; ++i)
         in = decode(in);
      std::cout << "\n";
      if (in == "")
         std::cout << decode("QmFkIGlucHV0OiBubyBwb3NzaWJsZSBzb2x1dGlvbnMgZm91bmQ=") << "\n";
      else
         std::cout << decode("T3V0cHV0OiA=") << in << "\n";
   }

   if (in == decode("cXVpdA=="))
      quit = true;
}

//OPTIONS - LIST OF COMMAND INPUTS
void options() {
   std::cout << "\n";
   std::cout << decode("b3B0aW9ucw==") << ": ";
   std::cout << decode("ZW5jb2Rl") << ", ";
   std::cout << decode("ZGVjb2Rl") << ", ";
   std::cout << decode("ZmFjdG9yaXpl") << ", ";
   std::cout << decode("cXVpdA==") << "\n";
}

//DECODER - DECODES IN BASE64
std::string decode(const std::string &in) {
   std::string val;
   std::vector<int> T(256, -1);
   for (int i = 0; i<64; ++i)
      T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
   int vala = 0, valb = -8;
   for (unsigned char c : in) {
      if (T[c] == -1)
         break;
      vala = (vala << 6) + T[c];
      valb += 6;
      if (valb >= 0) {
         val.push_back(char((vala >> valb) & 0xFF));
         valb -= 8;
      }
   }
   return val;
}

//ENCODER - ENCODES IN BASE64
std::string encode(const std::string &in) {
   std::string val;
   int vala = 0, valb = -6;
   for (unsigned char c : in) {
      vala = (vala << 8) + c;
      valb += 8;
      while (valb >= 0) {
         val.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(vala >> valb) & 0x3F]);
         valb -= 6;
      }
   }
   if (valb>-6)
      val.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((vala << 8) >> (valb + 8)) & 0x3F]);
   while (val.size() % 4)
      val.push_back('=');
   return val;
}

//TEXT STANDARDIZER - FORCES ANY COMMAND INPUT TO LOWERCASE, DOES NOT EFFECT ENCODE/DECODE INPUTS
std::string standardize(std::string raw)
{
   std::string clean;
   for (int i = 0; i < raw.size(); ++i)
   {
      char c = raw[i];
      if (c >= 'A' && c <= 'Z')
         clean += tolower(c);
      else if (c >= 'a' && c <= 'z')
         clean += c;
   }
   return clean;
}

//FACTORIZER - CHECKS THE NUMBER / 2 < NUM - 1 FOR A NEW NUMBER WITH NO REMAINDER AND IS PRIME, AND IF IT EXISTS, CHECKS NUMBER / PRIME FOR A POSSIBLE PRIME PAIR.
void factorize(int64_t numToFactorize)
{
   for (int64_t i = 2; i < numToFactorize; ++i)
   {
      if ((numToFactorize % i == 0) && isPrime(i))
      {
         int64_t q = numToFactorize / i;
         if (isPrime(q))
         {
            std::cout << decode("aSBpcyA=") << i << decode("IGFuZCBqIGlzIA ==") << q << "\n";
            return;
         }
      }
   }
   std::cout << decode("Tm8gcGFpciBvZiBwcmltZSBmYWN0b3JzIGZvdW5kLi4uIEFyZSB5b3Ugc3VyZSA=") << numToFactorize << decode("IGlzIHRoZSBwcm9kdWN0IG9mIHR3byBwcmltZXM/");
}

//PRIME CHECKER - DECIDES IF A NUMBER IS A PRIME OR NOT BY TAKING THE NUMBER / 2 < NUMBER - 1 AND SEEING IF THERE IS ALWAYS A REMAINDER.
bool isPrime(int64_t num) {
   for (int64_t i = 2; i < num; ++i)
      if (num % i == 0)
         return false;
   return true;
}