From 12f4fed6c351581cdeaf64b51a8dacfd5d05074c Mon Sep 17 00:00:00 2001 From: "J. Hamatoma" Date: Mon, 2 Dec 2013 22:06:05 +0100 Subject: [PATCH] rplenigma + rplrandom: fully tested --- rplmath/rplenigma.cpp | 160 ++++++++++++++++++++++++++++++++++++++---- rplmath/rplenigma.hpp | 23 ++++-- rplmath/rplmath.hpp | 3 + 3 files changed, 168 insertions(+), 18 deletions(-) diff --git a/rplmath/rplenigma.cpp b/rplmath/rplenigma.cpp index 18f8643..cd96d7e 100644 --- a/rplmath/rplenigma.cpp +++ b/rplmath/rplenigma.cpp @@ -25,6 +25,29 @@ * 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 RplEnigma. + */ +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 +} diff --git a/rplmath/rplenigma.hpp b/rplmath/rplenigma.hpp index 9fa51b3..0b7709f 100644 --- a/rplmath/rplenigma.hpp +++ b/rplmath/rplenigma.hpp @@ -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; diff --git a/rplmath/rplmath.hpp b/rplmath/rplmath.hpp index 14f2e86..a3702d9 100644 --- a/rplmath/rplmath.hpp +++ b/rplmath/rplmath.hpp @@ -8,6 +8,9 @@ #ifndef RPLMATH_HPP #define RPLMATH_HPP +#ifndef RPLCORE_HPPP +#include "rplcore/rplcore.hpp" +#endif #include "rplrandom.hpp" #include "rplenigma.hpp" -- 2.39.5