Created
October 19, 2015 22:34
-
-
Save apsun/7744d9381e32976cad05 to your computer and use it in GitHub Desktop.
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
#define BLOCK_SIZE 3 // Higher means longer time to find a seed, but smaller output | |
#define SPLIT_NON_ALPHA 0 // Highly recommend setting to 1 if BLOCK_SIZE > 3 | |
#define DELIMITER '|' // Used to store encrypted data for later use | |
#define LINE_DELIMITER '\n' // Separates blocks, cannot be the same as DELIMITER | |
#define ENCRYPT_ENABLED 1 | |
#define DECRYPT_ENABLED 0 | |
#define META_ENCRYPT 1 // So you can copy-paste the output from the console below | |
#define ENCRYPT_ME "" | |
#define DECRYPT_ME "" | |
struct EncryptedData { | |
char firstChar; | |
int length; | |
int charRange; | |
unsigned int seed; | |
}; | |
void printEncryptedData(EncryptedData); | |
void printMetaDataString(const string); | |
unsigned int findSeed(char*, int, int, unsigned int, unsigned int); | |
int findMsgRange(char*, int); | |
EncryptedData encryptChar(char); | |
EncryptedData encryptMsg(char*); | |
char* decryptMsg(EncryptedData); | |
const string toString(EncryptedData); | |
EncryptedData parseString(const string); | |
vector<EncryptedData> blockEncryptMsg(char*); | |
const string encryptDataString(char*); | |
const string decryptDataString(const string); | |
int main() | |
{ | |
#if ENCRYPT_ENABLED | |
#if META_ENCRYPT | |
printMetaDataString(encryptDataString(ENCRYPT_ME)); | |
#else | |
cout << encryptDataString(ENCRYPT_ME) << endl; | |
#endif | |
cout << endl; | |
#elif DECRYPT_ENABLED | |
cout << decryptDataString(DECRYPT_ME) << endl << endl; | |
#else | |
cout << ENCRYPT_ME << endl; | |
#endif | |
system("pause"); | |
return 0; | |
} | |
void printEncryptedData(EncryptedData data) { | |
cout << "First char: " << data.firstChar << endl; | |
cout << "Message length: " << data.length << endl; | |
cout << "Char range: " << data.charRange << endl; | |
cout << "Seed: " << data.seed << endl; | |
} | |
void printMetaDataString(const string text) { | |
stringstream str(text); | |
string item; | |
int num = 0; | |
while (getline(str, item, LINE_DELIMITER)) { | |
if (num++ > 0) cout << '\\' << endl; | |
cout << '\"' << item << "\\n\""; | |
} | |
cout << endl; | |
} | |
unsigned int findSeed(char text[], int length, int range, unsigned int start, unsigned int end) { | |
if (length == 0) return 0; | |
if (range++ == 0) return 0; | |
char *deltas = new char[--length]; | |
for (int i = 0; i < length; ++i) | |
deltas[i] = text[i+1] - text[0]; | |
unsigned int seed = 0; | |
bool found = false; | |
for (unsigned int i = start; i < end; ++i) { | |
srand(i); | |
int firstRnd = rand() % range; | |
for (int j = 0; j < length; ++j) | |
if (rand() % range - firstRnd != deltas[j]) | |
goto outer; | |
seed = i; | |
found = true; | |
break; | |
outer:; | |
} | |
delete[] deltas; | |
if (!found) throw exception("No seed found"); | |
return seed; | |
} | |
int findMsgRange(char text[], int length) { | |
if (length == 0) return 0; | |
char min = text[0], max = text[0]; | |
for (int i = 1; i < length; ++i) { | |
char curr = text[i]; | |
if (curr < min) min = curr; | |
if (curr > max) max = curr; | |
} | |
return max - min; | |
} | |
EncryptedData encryptChar(char myChar) { | |
EncryptedData data; | |
data.charRange = 0; | |
data.length = 1; | |
data.seed = 0; | |
data.firstChar = myChar; | |
return data; | |
} | |
EncryptedData encryptMsg(char text[]) { | |
int length = strlen(text); | |
int range = findMsgRange(text, length); | |
unsigned int seed = findSeed(text, length, range, 0, UINT_MAX); | |
EncryptedData data; | |
data.length = length; | |
data.seed = seed; | |
data.charRange = range; | |
data.firstChar = text[0]; | |
return data; | |
} | |
char* decryptMsg(EncryptedData data) { | |
unsigned int seed = data.seed; | |
int range = data.charRange + 1; | |
char firstChar = data.firstChar; | |
int length = data.length; | |
srand(seed); | |
int first = rand() % range; | |
char *msg = new char[length + 1]; | |
msg[0] = firstChar; | |
for (int i = 1; i < length; ++i) | |
msg[i] = firstChar + rand() % range - first; | |
msg[length] = '\0'; | |
return msg; | |
} | |
const string toString(EncryptedData data) { | |
stringstream str; | |
str << static_cast<int>(data.firstChar) << DELIMITER; | |
str << data.length << DELIMITER; | |
str << data.charRange << DELIMITER; | |
str << data.seed; | |
const string temp = str.str(); | |
return temp; | |
} | |
EncryptedData parseString(const string encryptedString) { | |
stringstream str(encryptedString); | |
string item; | |
EncryptedData data; | |
getline(str, item, DELIMITER); | |
data.firstChar = static_cast<char>(atoi(item.c_str())); | |
getline(str, item, DELIMITER); | |
data.length = atoi(item.c_str()); | |
getline(str, item, DELIMITER); | |
data.charRange = atoi(item.c_str()); | |
getline(str, item, DELIMITER); | |
data.seed = atoi(item.c_str()); | |
return data; | |
} | |
vector<EncryptedData> blockEncryptMsg(char text[]) { | |
EncryptedData spEncrypt = encryptChar(' '); | |
int length = strlen(text); | |
vector<EncryptedData> data; | |
char buffer[BLOCK_SIZE+1]; | |
int ti = 0; | |
cout << "-------------------------------" << endl; | |
while (ti < length) { | |
#if SPLIT_NON_ALPHA | |
bool space = false, other = false; | |
char specialChar; | |
#endif | |
int i = 0; | |
while (i < BLOCK_SIZE) { | |
if (ti >= length) { | |
break; | |
} | |
#if SPLIT_NON_ALPHA | |
if (!isalnum(text[ti])) { | |
if (text[ti] == ' ') { | |
space = true; | |
} else { | |
other = true; | |
specialChar = text[ti]; | |
} | |
++ti; | |
break; | |
} | |
#endif | |
buffer[i++] = text[ti++]; | |
} | |
if (i > 0) { | |
buffer[i] = '\0'; | |
data.push_back(encryptMsg(buffer)); | |
cout << buffer; | |
} | |
#if SPLIT_NON_ALPHA | |
if (space) { data.push_back(spEncrypt); cout << ' '; } | |
else if (other) { data.push_back(encryptChar(specialChar)); cout << specialChar; } | |
#endif | |
} | |
cout << endl << "-------------------------------" << endl; | |
return data; | |
} | |
const string encryptDataString(char text[]) { | |
vector<EncryptedData> blocks = blockEncryptMsg(text); | |
stringstream str; | |
for (int i = 0; i < blocks.size(); ++i) { | |
str << toString(blocks[i]) << LINE_DELIMITER; | |
} | |
const string temp = str.str(); | |
return temp; | |
} | |
const string decryptDataString(const string text) { | |
stringstream str(text); | |
string item; | |
stringstream out; | |
while (getline(str, item, LINE_DELIMITER)) { | |
char *decrypted = decryptMsg(parseString(item)); | |
out << decrypted; | |
delete[] decrypted; | |
} | |
const string temp = out.str(); | |
return temp; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment