* and a 64 bit integer arithmetic is available.
*
*/
+const char* RplEnigma::SET_DECIMALS = "0123456789";
+const char* RplEnigma::SET_HEXDIGITS = "0123456789abcdef";
+const char* RplEnigma::SET_ALPHANUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz_";
+const char* RplEnigma::SET_FILENAME = " !^°$%&=+~#-.0123456789ABCDEFGHIJKLM"
+ "NOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
+const char* RplEnigma::SET_32_127 = " !\"#$%&'()*+,-./0123456789:;<=>?@"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f";
+const char* RplEnigma::SET_32_255 = " !\"#$%&'()*+,-./0123456789:;<=>?@"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+const char* RplEnigma::SET_PRINTABLE_127 = "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f";
+const char* RplEnigma::SET_PRINTABLE_255 = "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+
/**
* @brief Constructor.
*
}
inline void buildBooster(QByteArray& booster, const char* charSet){
- int size = 256;
+ int size = 257;
booster.fill(0, size);
int ix = 0;
- char cc;
- while( (cc = *charSet++) != '\0'){
+ unsigned char cc;
+ while( (cc = (unsigned char) *charSet++) != '\0'){
booster[cc] = ++ix;
}
booster[0] = ix;
if (booster.length() == 0){
buildBooster(booster, charSet);
}
- int lengthOfCharSet = booster.at(0);
+ int lengthOfCharSet = (int) (unsigned char) booster.at(0);
for (int ii = 0; ii < size; ii++){
- char cc = *data;
+ unsigned char cc = (unsigned char) data[ii];
int ix = booster.at(cc);
if (ix != 0){
- ix = (ix + nextInt(lengthOfCharSet)) % lengthOfCharSet;
- *data++ = charSet[ix];
+ int next = nextInt(lengthOfCharSet);
+ int ix2 = (ix - 1 + next) % lengthOfCharSet;
+ data[ii] = charSet[ix2];
}
}
}
+
/**
* @brief Decodes a string in place with a given character set.
*
if (booster.length() == 0){
buildBooster(booster, charSet);
}
- int lengthOfCharSet = booster.at(0);
+ int lengthOfCharSet = (int) (unsigned char) booster.at(0);
for (int ii = 0; ii < size; ii++){
- char cc = *data;
+ unsigned char cc = (unsigned char) data[ii];
int ix = booster.at(cc);
if (ix != 0){
- ix = (lengthOfCharSet + ix - nextInt(lengthOfCharSet)) % lengthOfCharSet;
- *data++ = charSet[ix];
+ int next = nextInt(lengthOfCharSet);
+ int ix2 = (lengthOfCharSet + ix -1 - next) % lengthOfCharSet;
+ data[ii] = charSet[ix2];
}
}
}
for (ix = start; ix < oldSize; ix++){
sum += ix + byteSecret.at(ix);
}
- for (ix = oldSize; ix < newSize; ix--){
+ for (ix = oldSize; ix < newSize; ix++){
sum += ix + 7;
byteSecret[ix] = (char) (sum + byteSecret.at(ix-1));
}
m_random->setSeed(seed);
m_randomCalls = 0;
}
+
+// ------------------
+#if ! defined RPL_TEST
+#define RPL_TEST
+#endif
+#ifdef RPL_TEST
+#include "rplcore/rpltest.hpp"
+/**
+ * @brief Unit test for <code>RplEnigma</code>.
+ */
+class TestRplEnigma : public RplTest
+{
+public:
+ TestRplEnigma() : RplTest("RplEnigma"){}
+
+public:
+ void testOneCharset(const char* value, const char* charSet, const char* expected){
+ RplEnigma enigma;
+ enigma.addByteSecret(QByteArray("Geheim"));
+ enigma.setSeed(0);
+ QByteArray encoded = value;
+ QByteArray booster;
+ enigma.encode(encoded.data(), encoded.length(), charSet, booster);
+ //printString(encoded.constData());
+ QByteArray decoded = encoded;
+ enigma.setSeed(0);
+ enigma.decode(decoded.data(), decoded.length(), charSet, booster);
+ checkE(value, decoded.constData());
+ checkE(expected, encoded);
+ }
+
+ void printCharSets(){
+ QByteArray value;
+ value.reserve(256);
+ unsigned char cc;
+ for (cc = ' '; cc <= 127; cc++){
+ if (cc == '"' || cc == '\\')
+ value.append('\\');
+ value.append(cc);
+ }
+ printf ("%s\n", value.constData());
+ value.resize(0);
+ for (cc = 128; cc >= 128; cc++){
+ char buf[10];
+ if (cc % 32 == 0)
+ value.append("\n");
+ sprintf(buf, "\\x%02x", cc);
+ value.append(buf);
+ }
+ printf ("%s\n", value.constData());
+ }
+ void printString(const char* value){
+ QByteArray v;
+ unsigned char cc;
+ while( (cc = (unsigned char) *value++) != 0){
+ if (cc == '\\' || cc == '"'){
+ v.append('\\');
+ v.append(cc);
+ } else if (cc >= 127) {
+ char buffer[10];
+ sprintf(buffer, "\\x%02x", cc);
+ v.append(buffer);
+ } else {
+ v.append(cc);
+ }
+ }
+ printf("%s\n", v.constData());
+ }
+ void testOneBytes(const char* bytes){
+ RplEnigma enigma;
+ enigma.addByteSecret("Hello World");
+ enigma.setSeed(0x1234);
+
+ QByteArray encoded(bytes);
+ enigma.change(encoded);
+
+ enigma.setSeed(0x1234);
+ QByteArray decoded(encoded);
+ enigma.change(decoded);
+ checkE(bytes, decoded);
+ }
+
+ void testBytes(){
+ testOneBytes("abcdefg");
+ testOneBytes("01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ }
+
+ void testCharSet(){
+ //testOneCharset("&()[]{}Weiß der Geier/Kuckuck?", RplEnigma::SET_32_255, "2Kc\x9a\xfeQ\xd7\xa84sx)*\xfb\xd2z\xf4\"W\xb0\xee\xb0\xd1\x84\xace\xf8_u*T");
+ testOneCharset("\\Weiß der Geier/Kuckuck?", RplEnigma::SET_32_127, "(Z?hßaZ_#/QZ+Oi|SI^=<,)A");
+ testOneCharset("01234567890abcdef", RplEnigma::SET_HEXDIGITS, "c4c25b08735c53a63");
+ testOneCharset("data$1%3.^~", RplEnigma::SET_FILENAME, "^voazo-n%$b");
+ testOneCharset("Weiß der Geier!", RplEnigma::SET_ALPHANUM, "weyß BCk 19NoO!");
+ testOneCharset("12345678901234567890", RplEnigma::SET_DECIMALS, "97394833084815683977");
+ testOneCharset("000000000000000000000000000", RplEnigma::SET_DECIMALS, "850592651836811261879625929");
+ }
+
+ virtual void doIt(){
+ testBytes();
+ testCharSet();
+ }
+};
+
+#endif
+void testRplEnigma(){
+#ifdef RPL_TEST
+ TestRplEnigma test;
+ test.run();
+#endif
+}