Last active
June 11, 2018 23:41
-
-
Save ammarfaizi2/e746f1fc3cfc5d971755da8145c02df3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#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