#ifndef SCRAMBLER_H
#define SCRAMBLER_H
#include <QDateTime>
#include <iostream>
#include <math.h>
#include <QDebug>
class Scrambler
{
private:
int _saltLength;
qlonglong _seed;
char _minChar;
int _range;
public:
Scrambler(int saltLength = 4, char minChar = ' ', char maxChar = (char) 127): _saltLength(saltLength), _seed(0x1234567890abcdefLL), _minChar(minChar), _range(maxChar - minChar + 1)
{
}
public:
qlonglong trueRandom(){
qlonglong dummy = 0x1234567887654321LL;
return _seed ^ qlonglong(QDateTime::currentMSecsSinceEpoch()) ^ qlonglong(&dummy) ^ + dummy;
}
int random(int minValue, int maxValue)
{
_seed = 0x7f293278193 * _seed + 0x8585205a;
int rc = abs(int(_seed) ^ int(_seed >> 32));
return minValue + (rc % (maxValue - minValue));
}
QString getRandomString(int length)
{
_seed = trueRandom();
QString rc;
for (int ix = 0; ix < length; ix++){
rc += QChar(ushort(_minChar + random(0, _range)));
}
return rc;
}
qlonglong getSalt(QString string)
{
qlonglong rc = 0;
for (int ix = 0; ix < _saltLength; ix++){
rc = (rc << 8) + (rc >> (64 - 8)) + string[ix].unicode();
}
return rc;
}
QString encode(QString clearText)
{
QString rc = getRandomString(_saltLength);
_seed = getSalt(rc);
for (int ix = 0; ix < clearText.length(); ix++){
ushort value = clearText[ix].unicode() - ushort(_minChar);
QChar cc(_minChar + (value + random(0, _range)) % _range);
rc += cc;
}
return rc;
}
QString decode(QString encoded)
{
QString rc;
_seed = getSalt(encoded);
for (int ix = _saltLength; ix < encoded.length(); ix++){
ushort value = encoded[ix].unicode() - ushort(_minChar);
QChar cc(_minChar + (_range + value - random(0, _range)) % _range);
rc += cc;
}
return rc;
}
void testOne(QString string)
{
QString encoded = encode(string);
QString decoded = decode(encoded);
if (decoded != string){
qDebug() << "+++ failed: " << string << " / " << decoded;
} else {
qDebug() << string << " -> " << encoded;
}
}
void test()
{
testOne("abc");
testOne(" !\"\'?\\$%&/()=");
for (int len = 3; len < 127; len++){
QString string = getRandomString(len);
testOne(string);
}
testOne("This is the end.");
}
};
#endif // SCRAMBLER_H