Hi everybody, I wrote a encryption algorithm (uses a single password to encrypt and decrypt) and would really like to test how it stands up to people who knows how to reverse engineer an encrypted string. Any suggestions and comments is welcome :) Thank you very much!
/*
* This algorith encrypts a string explicitly using the password provided.
* It shifts the original letter by a value determined beforehand (nPwordShifts)
*
* The algorithm to calculate the shifts:
*
* (nPword total calculated in function nCalculatePwordTotal)
*
* Shift = ( floor( nPwordTotal / int(nCurrentLetter) ) ) + ( nPwordTotal % int(nCurrenLetter) );
*
* At encryption the shift is added to the current letter and at decryption the shift is deducted from the current letter.
*
* The '~' (tilde) character is used when the shift is greater than 186 (186 will cause the letter to be in the extended ASCII range
* or if the shift is bigger not even in the ASCII range). For each '~' (tilde) character 93 will be deducted from the shift value.
*
*/
#include <string>
int nCalculatePwordTotal(std::string cPassword)
{
int nPwordTotal=0;
int nLength=cPassword.length();
for (int nIndex=0; nIndex<nLength; nIndex++)//This forces the password letter to be in the correct order
{
if (nIndex%2==0)
{
nPwordTotal+=int(cPassword[nIndex]);
}
else
{
nPwordTotal+= 2 * int(cPassword[nIndex]);
}
}
return nPwordTotal;
}
int* CalculatnPasswordShifts(int nLength, std::string cPassword)
{
int nPwordTotal=nCalculatePwordTotal(cPassword);
int* nPwordShifts = newint[nLength];
for (int nIndex=0; nIndex<nLength; nIndex++)
{
nPwordShifts[nIndex] = int(nPwordTotal / int(cPassword[nIndex])); //All letters of password need to be correct
nPwordShifts[nIndex] += nPwordTotal % int(cPassword[nIndex]);
}
return nPwordShifts;
}
std::string Encryption(std::string cOriginal, std::string cPassword)
{
int nLength=cPassword.length();
int* nPwordShifts = CalculatnPasswordShifts(nLength, cPassword);
int nCurrentP=nLength; //Current letter in pword used
nCurrentP--;
nLength = cOriginal.length();
std::string cChanged; //Will store changed std::string
for (int nIndex=0; nIndex < nLength; nIndex++)
{
int nASCII = int(cOriginal[nIndex]);
nASCII += nPwordShifts[nCurrentP];
if (nASCII < 126)
{
cChanged+=char(nASCII);
}
else
{
nASCII-=93;
while (nASCII > 125)
{
cChanged+='~'; // Prevents overflow
nASCII -= 93;
}
cChanged+=char(nASCII);
}
if (nCurrentP == 0)
{
nCurrentP = cPassword.length();
nCurrentP--;
}
else
{
nCurrentP--;
}
}
delete[] nPwordShifts;
return cChanged;
}
std::string Decryption(std::string cOriginal, std::string cPassword)
{
int nLength=cPassword.length();
int *nPwordShifts = CalculatnPasswordShifts(nLength, cPassword);
int nCurrentP=nLength; //Current letter in pword used
nCurrentP--;
nLength = cOriginal.length();
std::string cChanged; //Will store changed std::string
for (int nIndex=0; nIndex<nLength; nIndex++)
{
int nTemp=0;
while (cOriginal[nIndex] == '~')
{
nIndex++;
nTemp += 93;
}
int nASCII = int(cOriginal[nIndex]);
nASCII -= nPwordShifts[nCurrentP];
if (nASCII > 31)
{
cChanged+=char(nASCII);
}
else
{
nASCII+= 93;
nASCII+= nTemp;
cChanged+=char(nASCII);
}
if (nCurrentP == 0)
{
nCurrentP = cPassword.length();
nCurrentP--;
}
else
{
nCurrentP--;
}
}
delete[] nPwordShifts;
return cChanged;
}
Reading code with no description of how the algorithm works and with poor variable names is a real pain.
Some notes:
Your functions are long, I see a lot of duplicated code between the function. This is a sign that you need to refactor and make new functions to handle this duplicated code. This will also make your code easier to read and follow.
Memory leaks. You have them. Deal with them, or don't make explicit calls to new.
Thanks for the suggestions, I updated the script where I removed duplicate code, added description of the algorithm and also fixed the memory leaks. Also here is a encrypted string :
I should add the "~" character is the only character in the printable part of the ASCII table (excluding the extended ASCII table) that is doesn't support as it uses the "~" character as a marker (explained in the top comment section of the script). Running the script that helios provided with anything else except "~" will output 1, meaning it is functioning correctly. Also only using one character as the password will only shift all the letters by one making the encryption very weak.