Skip to content

Instantly share code, notes, and snippets.

@ammarfaizi2
Last active June 11, 2018 23:41
Show Gist options
  • Save ammarfaizi2/e746f1fc3cfc5d971755da8145c02df3 to your computer and use it in GitHub Desktop.
Save ammarfaizi2/e746f1fc3cfc5d971755da8145c02df3 to your computer and use it in GitHub Desktop.
#include <string>
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = 0; j < i; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
static std::string strrev(std::string line)
{
std::string::reverse_iterator it;
std::string result = "";
for (it = line.rbegin(); it < line.rend(); it++)
{
result += *it;
}
return result;
}
class TeaEncrypt
{
public:
/**
* Tea Encrypt
*
* salt generator Method
*/
static std::string saltGenerator(int n = 5)
{
srand(time(0));
std::string salt;
for(auto i = 0; i < n; i++) {
salt += (char) rand() % 255;
}
return salt;
}
/**
* Tea Encrypt
*
* Encryption Method
*/
static std::string Encrypt(std::string data, std::string key, bool isBinarySafe = true)
{
std::string encrypted, newKey, salt = saltGenerator();
int cost = 1;
// Generate new Key
for(auto it = key.begin(), jt = salt.begin(); it != key.end(); it++ ) {
newKey += (char) (((int) *it) ^ ((int) *jt++));
if(jt == salt.end()) {
jt = salt.begin();
}
}
// Encrypt Our Data
for(int it = 0, jt = 0, kt = 0; it < data.length(); it++) {
// auto
// iit = std::distance(data.begin(), it),
// ijt = std::distance(salt.begin(), jt),
// ikt = std::distance(newKey.begin(), kt);
// std::cout << it << " ";
// std::cout << jt << " ";
encrypted += (char) (
(data[it]) ^ (newKey[jt++]) ^ (salt[kt++]) ^ (it << jt) ^ (kt >> jt) ^
(data.length() % cost) ^ (cost >> jt) ^ (cost >> it) ^ (cost >> kt) ^
(cost ^ (data.length() % (it + jt + kt + 1))) ^
((cost << it) % 2) ^ ((cost << jt) % 2) ^ ((cost << kt) % 2) ^
((cost * (it + jt + kt)) % 3)
);
cost++;
if(jt == newKey.length()) {
jt = 0;
}
if(kt == 5) {
kt = 0;
}
}
encrypted += salt;
if(isBinarySafe) {
unsigned char *t = (unsigned char *) encrypted.c_str();
return strrev(base64_encode(t, encrypted.length()));
} else {
return encrypted;
}
}
/**
* Tea Encrypt
*
* Decrypt Method
*/
static std::string Decrypt(std::string data, std::string key, bool isBinarySafe = true)
{
if (isBinarySafe)
{
data = base64_decode(strrev(data));
}
std::string decrypted, newKey, salt = data.substr(data.length() - 5, data.length());
int cost = 1;
data = data.substr(0, data.length() - 5);
for(auto it = key.begin(), jt = salt.begin(); it != key.end(); it++ ) {
newKey += (char) (((int) *it) ^ ((int) *jt++));
if( jt == salt.end() ) {
jt = salt.begin();
}
}
for(int it = 0, jt = 0, kt = 0; it < data.length(); it++) {
// auto iit = std::distance(data.begin(), it),
// ijt = std::distance(salt.begin(), jt),
// ikt = std::distance(newKey.begin(), kt);
// decrypted += (char) (
// ((int) *it) ^ ((int) *jt++) ^ ((int) *kt++) ^ (iit << ijt) ^ (ikt >> ijt) ^
// (data.length() % cost) ^ (cost >> ijt) ^ (cost >> iit) ^ (cost >> ikt) ^
// (cost ^ (data.length() % (iit + ijt + ikt + 1))) ^
// ((cost << iit) % 2) ^ ((cost << ijt) % 2) ^ ((cost << ikt) % 2) ^
// ((cost * (iit + ijt + ikt)) % 3)
// );
decrypted += (char) (
(data[it]) ^ (newKey[jt++]) ^ (salt[kt++]) ^ (it << jt) ^ (kt >> jt) ^
(data.length() % cost) ^ (cost >> jt) ^ (cost >> it) ^ (cost >> kt) ^
(cost ^ (data.length() % (it + jt + kt + 1))) ^
((cost << it) % 2) ^ ((cost << jt) % 2) ^ ((cost << kt) % 2) ^
((cost * (it + jt + kt)) % 3)
);
cost++;
if(jt == newKey.length()) {
jt = 0;
}
if(kt == 5) {
kt = 0;
}
}
return decrypted;
}
};
int main() {
std::string data_input;
std::cout << "What Should We Encrypt?\n -> ";
std::getline(std::cin, data_input);
auto data = TeaEncrypt::Encrypt(data_input,"Some Key", true);
std::cout << "\nLet\'s Encrypt, Result Was: " << data << "\n";
std::cout << "Let\'s Decrypt It Back, Result Was: " << TeaEncrypt::Decrypt(data, "Some Key", true) << "\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment