Skip to content

Instantly share code, notes, and snippets.

@apsun
Created October 19, 2015 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apsun/7744d9381e32976cad05 to your computer and use it in GitHub Desktop.
Save apsun/7744d9381e32976cad05 to your computer and use it in GitHub Desktop.
#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