]> gitweb.hamatoma.de Git - reqt/commitdiff
rplenigma + rplrandom: fully tested
authorJ. Hamatoma <hama@siduction.net>
Mon, 2 Dec 2013 21:06:05 +0000 (22:06 +0100)
committerJ. Hamatoma <hama@siduction.net>
Mon, 2 Dec 2013 21:06:05 +0000 (22:06 +0100)
rplmath/rplenigma.cpp
rplmath/rplenigma.hpp
rplmath/rplmath.hpp

index 18f864351c06ef8c0322c56bfe49255ab4594d2e..cd96d7e3651963257db4457ff9ca8c21bb02a90e 100644 (file)
  * 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.
  *
@@ -68,11 +91,11 @@ QByteArray RplEnigma::readCertificate(const char* filename){
 }
 
 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;
@@ -98,16 +121,18 @@ void RplEnigma::encode(char* data, int size, const char* charSet, QByteArray& bo
     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.
  *
@@ -128,13 +153,14 @@ void RplEnigma::decode(char* data, int size, const char* charSet, QByteArray& bo
     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];
         }
     }
 }
@@ -175,7 +201,7 @@ void RplEnigma::addByteSecret(QByteArray byteSecret){
         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));
         }
@@ -232,3 +258,113 @@ void RplEnigma::setSeed(u_int64_t seed){
     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
+}
index 9fa51b3fe037e4178397f8ba9e42e5b192d7827b..0b7709f5641c1e168e94c44c79200a71eae0e5a5 100644 (file)
@@ -3,12 +3,23 @@
 
 class RplEnigma {
 public:
-    static const char* SET_32_127;      ///< ' ' .. chr(127)
-    static const char* SET_DECIMALS;    ///< '0'..'9'
-    static const char* SET_HEXDIGITS;   ///< '0'..'9' 'a'..'f'
-    static const char* SET_ALPHANUM;    ///< '0'..'9' 'A'..'Z' a'..'z' '_'
-    static const char* SET_FILENAME;    ///< '0'..'9' 'A'..'Z' z'..'z' '_'
-    static const char* SET_32_255;      ///< ' ' .. chr(255)
+    ///> '0'..'9'
+    static const char* SET_DECIMALS;
+    ///> '0'..'9' 'a'..'f'
+    static const char* SET_HEXDIGITS;
+    ///> '0'..'9' 'A'..'Z' a'..'z' '_'
+    static const char* SET_ALPHANUM;
+    ///> '0'..'9' 'A'..'Z' z'..'z' '_'
+    static const char* SET_FILENAME;
+    ///> ' ' .. chr(127)
+    static const char* SET_32_127;
+    ///> ' ' .. chr(255)
+    static const char* SET_32_255;
+    ///> TAB, CR, NL, ' '..chr(127)
+    static const char* SET_PRINTABLE_127;
+    ///> TAB, CR, NL, ' '..chr(255)
+    static const char* SET_PRINTABLE_255;
+
 protected:
     typedef struct {
         int m_count;
index 14f2e86dc596fb938bd2f9a69836d87832924c83..a3702d902c04cb127bd918ec871a09427091017e 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef RPLMATH_HPP
 #define RPLMATH_HPP
 
+#ifndef RPLCORE_HPPP
+#include "rplcore/rplcore.hpp"
+#endif
 #include "rplrandom.hpp"
 #include "rplenigma.hpp"