From ed590e4caf32165299d8b225c2be670c32021386 Mon Sep 17 00:00:00 2001 From: hama Date: Thu, 12 Nov 2015 22:02:16 +0100 Subject: [PATCH] codec() works --- base/ReRandomizer.cpp | 284 ++++++++++----------------------------- base/ReRandomizer.hpp | 66 +++++---- base/ReTest.cpp | 103 ++++++++------ base/ReTest.hpp | 31 ++--- base/rebase.hpp | 36 +++++ cunit/allTests.cpp | 2 +- cunit/cuReRandomizer.cpp | 93 +++++++------ os/ReCryptFileSystem.cpp | 10 +- 8 files changed, 276 insertions(+), 349 deletions(-) diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index 2376266..9ac4f6f 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -19,8 +19,6 @@ enum { LOC_UPDATE_1, // 22204 }; -const char ReNameScrambler::ESC = '%'; - const int64_t ReRandomizer::m_primes64[] = { 7919787109669756829L, // 6de8 bc6a 5895 5f9d 8190338840038832831L, // 71a9edc7de997abf @@ -150,24 +148,6 @@ const int64_t ReRandomizer::m_primes64[] = { }; const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes64 / sizeof ReRandomizer::m_primes64[0]; -const int ReNameScrambler::m_indexOfNodeChar[] = { -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, 12, - -1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, -1, -1, 23, -1, -1, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, }; -const char ReNameScrambler::m_nodeChars[] = { ' ', '!', '#', '$', '%', '&', - '\'', '(', ')', '+', ',', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '=', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', - 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', '{', '|', '}', '~', '\x7f', }; -const int ReNameScrambler::m_countNodeChars = - sizeof ReNameScrambler::m_nodeChars; - /** * Returns the hash value as hex string. @@ -535,6 +515,39 @@ const char* ReRandomizer::nextString(int minLength, int maxLength, return buffer.constData(); } +/** + * Convert a clear text into scrambled data and vice versa. + * + * + * + * @param target OUT: the target buffer + * @param source the source to scramble. May be identical target + * @param length the length of source in byte + */ +void ReRandomizer::codec(uint8_t* target, const uint8_t*source , int length) +{ + int64_converter_t data; + for (int ii = length / sizeof data - 1; ii >= 0; ii--){ + data.fromBytes(source); + data.m_int ^= nextSeed64(); + data.toBytes(target); + source += sizeof data; + target += sizeof data; + } + int rest = length % sizeof(seed_t); + if (rest > 0){ + data.m_int = nextSeed64(); + for (int ii = 0; ii < rest; ii++){ + *target++ = *source++ ^ data.m_bytes[ii]; + } + } +} + /** * @brief Builds a random permutation of an array. * @@ -1033,7 +1046,8 @@ ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger) m_contentSeed(), m_buffer(), m_header(), - m_logger(logger) + m_logger(logger), + m_salt(0) { m_contentRandom.saveSeed(m_contentSeed); m_buffer.reserve(256); @@ -1041,141 +1055,18 @@ ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger) } /** - * Constructor. + * Returns the pseudo random generator used for data encryption. * - * @param nameRandom a pseudo random generator - * @param logger the logger + * @param doReset true: the random generator is reset + * @return the random generator for data encryption */ -ReNameScrambler::ReNameScrambler(ReRandomizer& nameRandom, ReLogger* logger) : - m_nameRandom(nameRandom), - m_nameSeed(), - m_logger(logger) +ReRandomizer& ReByteScrambler::contentRandom(bool doReset) { - nameRandom.saveSeed(m_nameSeed); -} - -/** - * Makes the clear text name from an encoded name. - * - * @param name the encoded name - * @return the clear text name - */ -QByteArray& ReNameScrambler::decodeName(const QByteArray& name) -{ - //@ToDo - m_buffer = name; - return m_buffer; -} - -/** - * Makes a clear text filename. - * - * @param name encrypted filename - * @return the clear text filename - */ -QString ReNameScrambler::decodeName(const QString& name) { - QString rc = name; - return rc; -} - -/** - * Decodes a block of file content. - * - * @param source the source block - * @param target OUT: the target block
- * Can be identical to source (in place replacement) - * @param offset decoding start at this content - * @return true: successful
- * false: otherwise - */ -bool ReByteScrambler::decodeContent(const QByteArray& source, - QByteArray& target, int start) { - bool rc = true; - int offset = 0; - target.resize(0); - if (rc){ - target.resize(source.length() - offset); - int64_t* trg = reinterpret_cast(target.data()); - int count = (source.length() - offset) / sizeof(int64_t); - const int64_t* src = reinterpret_cast(source.constData() - + offset); - int64_t last = ReRandomizer::m_primes64[0]; - if (start > 0){ - memcpy(trg, src, start); - start /= sizeof(int64_t); - src += offset; - trg += offset; - } - for (int ix = start; ix < count; ix++) { - int64_t last2 = last; - last = *src++; - int64_t rand = m_contentRandom.nextSeed64(); - *trg++ = last ^ rand ^ last2; - TRACE_IT(("ix: %d last: %016lx rand %016lx src: %016lx trg: %016lx\n", - ix, last2, rand, src[-1], trg[-1])); - } - int countTail = (source.length() - offset) % sizeof(int64_t); - if (countTail != 0){ - char* trgTail = reinterpret_cast(trg); - char lastTail = (char) last; - const char* srcTail = reinterpret_cast(src); - for (int ix = 0; ix < countTail; ix++){ - char last2 = lastTail; - lastTail = *srcTail++; - char rand = m_contentRandom.nextChar(); - *trgTail++ = lastTail ^ rand ^ last2; - TRACE_IT(("ix: %d last: %02x rand %2x src: %02x trg: %02x\n", - ix, (uint8_t) last2, (uint8_t) rand, - (uint8_t) srcTail[-1], (uint8_t) trgTail[-1])); - } - } - } - return rc; -} - -/** - * Encodes a buffer of file content. - * - * @param source the source buffer - * @param target OUT: the target buffer. - * May be identical to source (in place processing) - * @param start the encryption begins at this index - */ -void ReByteScrambler::encodeContent(const QByteArray& source, - QByteArray& target, int start) { - target.resize(source.length()); - int64_t* trg = reinterpret_cast(target.data()); - int count = source.length() / sizeof(int64_t); - const int64_t* src = reinterpret_cast(source.constData()); - int64_t last = ReRandomizer::m_primes64[0]; - - if (start > 0){ - memcpy(trg, src, start); - start /= sizeof(int64_t); - src += start; - trg += start; - } - for (int ix = start; ix < count; ix++) { - int64_t rand = m_contentRandom.nextSeed64(); - IF_TRACE(int64_t last2 = last); - last = *trg++ = *src++ ^ rand ^ last; - TRACE_IT(("ix: %d last: %016lx rand %016lx src: %016lx trg: %016lx\n", - ix, last2, rand, src[-1], trg[-1])); - } - int countTail = source.length() % sizeof(int64_t); - if (countTail != 0){ - char* trgTail = reinterpret_cast(trg); - char lastTail = (char) last; - const char* srcTail = reinterpret_cast(src); - for (int ix = 0; ix < countTail; ix++){ - char rand = m_contentRandom.nextChar(); - IF_TRACE(char last2 = lastTail); - lastTail = *trgTail++ = *srcTail++ ^ rand ^ lastTail; - TRACE_IT(("ix: %d last: %02x rand %2x src: %02x trg: %02x\n", - ix, (uint8_t) last2, (uint8_t) rand, - (uint8_t) srcTail[-1], (uint8_t) trgTail[-1])); - } + if (doReset){ + m_contentRandom.reset(); + m_contentRandom.modifySeed(m_salt); } + return m_contentRandom; } /** @@ -1183,15 +1074,18 @@ void ReByteScrambler::encodeContent(const QByteArray& source, * * @param metaInfoLength the length of the "reserved area" * @param markerLength length of a mark to ensure header's integrity + * @param encryptedFrom the first index from which data are encrypted. + * the first possible index is behind the marker * @param header the header with the initializing info. If NULL the * internal header will be used * @param info OUT: the reserved area in the header * @return true: success */ bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength, - const QByteArray* header, QByteArray& info) + int encryptedFrom, const QByteArray* header, QByteArray& info) { TRACE("initFromHeader():\n"); + encryptedFrom = max(encryptedFrom, encryptedFrom < sizeof(int64_t) + markerLength); bool rc = true; if (header == NULL) header = &m_header; @@ -1201,9 +1095,9 @@ bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength, header->length(), headerLength); rc = false; } else { - int64_t random = * reinterpret_cast(header->constData()); + m_salt = * reinterpret_cast(header->constData()); m_contentRandom.reset(); - m_contentRandom.modifySeed(random); + m_contentRandom.modifySeed(m_salt); QByteArray marker; marker.append(reinterpret_cast(header->constData()+ sizeof(int64_t)), markerLength); @@ -1237,7 +1131,6 @@ bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength, /** * Initializes the scrambler header. * - * * Format of the header: *
random (8 byte)
  * marker (m_markerLength byte)
@@ -1246,79 +1139,44 @@ bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength,
  *
  * @param metaInfoLength	the length of the "reserved area"
  * @param markerLength		length of a mark to ensure header's integrity
+ * @param encryptedFrom		the first index from which data are encrypted.
+ *							the first possible index is behind the marker
  * @param info				the content of the "reserved area". If too few space
  *							the content will be cut
  */
 void ReByteScrambler::initHeader(int metaInfoLength, int markerLength,
-								 const QByteArray& info)
+			int encryptedFrom, const QByteArray& info)
 {
 	TRACE("initHeader():\n");
-	int64_t random = m_realRandom.nextSeed64();
+	encryptedFrom = max(encryptedFrom, encryptedFrom < sizeof(int64_t) + markerLength);
+	m_salt = m_realRandom.nextSeed64();
 	m_contentRandom.reset();
-	m_contentRandom.modifySeed(random);
+	m_contentRandom.modifySeed(m_salt);
 	int headerLength = sizeof(int64_t) + markerLength + metaInfoLength;
 	m_header.fill(' ', headerLength);
-	* reinterpret_cast(m_header.data()) = random;
+	* reinterpret_cast(m_header.data()) = m_salt;
 	if (markerLength > 0){
 		m_buffer.resize(0);
 		m_contentRandom.nextString(markerLength, markerLength, m_buffer);
 		memcpy(m_header.data() + sizeof(int64_t), m_buffer, markerLength);
 	}
 	char last = 0x47;
-	char* trg = reinterpret_cast(m_header.data() + sizeof (int64_t) + markerLength);
-	int infoLength = min(info.length(), metaInfoLength - 1);
-	TRACE2("info: length: %d reserved: %d\n", infoLength, metaInfoLength);
-	*trg++ = infoLength;
-	for (int ix = 0; ix < infoLength && ix < metaInfoLength; ix++){
-		last = *trg++ = m_contentRandom.nextChar() ^ info.at(ix) ^ last;
+	char* trg;
+	if (info.length() > 0){
+		int offset = sizeof(int64_t) + markerLength;
+		trg = reinterpret_cast(m_header.data() + offset);
+		memcpy(trg, info, min(m_header.length() - offset, info.length()));
 	}
-	TRACE_IT(("random: %016lx marker: %s\n", random,
-			   m_buffer.constData()));
-	IF_TRACE(m_contentRandom.dump());
-}
-/**
- * Encode a filename.
- *
- * Method:
- * 
  • Invert the name without extension (first char becomes the last), - * add the extension
  • - *
  • Replace the "unconvertable" chars (< 127) into "%xx" ('%' with 2 hexdigits)
  • - *
  • exchange the char with a value generated by the pseudo random generator
  • - *
- * @param node clear text filename - * @return the encrypted filename - */ -QByteArray& ReNameScrambler::encodeName(const QByteArray& node) { - QByteArray rc; - int length = node.length(); - int nameLength = rc.lastIndexOf('.'); - if (nameLength < 0) - nameLength = node.length(); - const char* src = node.constData(); - unsigned char cc; - int ix2 = nameLength - 1; - for (int ix = 0; ix < length; ix++) { - cc = (unsigned char) src[ix >= nameLength ? ix : ix2--]; - if (cc != ESC && cc < 128) { - m_buffer.append(cc); - } else { - m_buffer.append(ESC); - char hex[3]; - snprintf(hex, sizeof hex, "%02x", cc); - m_buffer.append(hex, 2); + if (encryptedFrom < m_header.length()){ + char* trg = reinterpret_cast(m_header.data() + encryptedFrom); + int infoLength = min(info.length(), metaInfoLength - 1); + TRACE2("info: length: %d reserved: %d\n", infoLength, metaInfoLength); + *trg++ = infoLength; + for (int ix = 0; ix < infoLength && ix < metaInfoLength; ix++){ + last = *trg++ = m_contentRandom.nextChar() ^ info.at(ix) ^ last; } } - m_nameRandom.reset(); - char* trg = m_buffer.data(); - int pred = 0; - for (int ix = 0; ix < length; ix++) { - int ix2 = (m_indexOfNodeChar[(int) *trg] + pred - + m_nameRandom.nextInt(m_countNodeChars - 1)) % m_countNodeChars; - *trg = m_nodeChars[ix2]; - pred = ix2; - } - return m_buffer; + TRACE_IT(("random: %016lx marker: %s\n", m_salt, + m_buffer.constData())); + IF_TRACE(m_contentRandom.dump()); } - - - diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index c541121..24926c7 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -72,7 +72,6 @@ private: int64_t m_sumLength; QByteArray m_rest; }; - /** * This implements an abstract base class for random generators. */ @@ -87,6 +86,30 @@ public: ReRandomizer(const char* name); virtual ~ReRandomizer(); public: + void codec(uint8_t* target, const uint8_t* source, int length); + /** Encode/decode data in a buffer. + * @param buffer IN/OUT: data to encode/decode + */ + inline void codec(QByteArray& buffer){ + codec((uint8_t*)buffer.data(), (const uint8_t*) buffer.constData(), + buffer.length()); + } + /** Encode/decode data. + * @param target OUT: target for the de/encoded data + * @param source source of the de/encoded data + * @param start first index to encode/decode. The data lying in front + * will be copied + */ + inline void codec(QByteArray& target, const QByteArray source, int start = 0){ + target.resize(source.length()); + if (start > 0) + memcpy((uint8_t*)target.data(), (const uint8_t*) source.constData(), + min(source.length(), start)); + if (start < source.length()) + codec((uint8_t*)target.data() + start, + (const uint8_t*) source.constData() + start, + target.length() - start); + } const QByteArray& name() const; seed_t nearTrueRandom(); char nextChar(); @@ -299,19 +322,24 @@ private: /** * A processing unit for encoding/decoding of binary data. + * + * The scrambler administrates a header containing a 64 bit random value (salt). + * Encryption is done with this salt. + * Furthermore an optional marker is set (with a given length). This is was + * distinguishes a valid header from wrong data. + * Encryption of the rest of the header is optional. + * */ class ReByteScrambler{ public: ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger); public: - bool decodeContent(const QByteArray& source, QByteArray& target, - int offset = 0); - void encodeContent(const QByteArray& source, QByteArray& target, - int offset = 0); - void initHeader(int metaInfoLength, int markerLength, - const QByteArray& info = ReStringUtils::m_empty); - bool initFromHeader(int metaInfoLength, int markerLength, + ReRandomizer& contentRandom(bool doReset); + bool initFromHeader(int metaInfoLength, int markerLength, int encryptFrom, const QByteArray* header, QByteArray& info); + void initHeader(int metaInfoLength, int markerLength, int encryptFrom, + const QByteArray& info = ReStringUtils::m_empty); + protected: ReRandomizer& m_contentRandom; ReKISSRandomizer m_realRandom; @@ -319,27 +347,7 @@ protected: QByteArray m_buffer; QByteArray m_header; ReLogger* m_logger; -}; - -class ReNameScrambler{ -public: - ReNameScrambler(ReRandomizer& nameRandom, ReLogger* logger); -public: - QByteArray& decodeName(const QByteArray& name); - QString decodeName(const QString& name); - QByteArray& encodeName(const QByteArray& name); - QString encodeName(const QString& name); -protected: - ReRandomizer& m_nameRandom; - QByteArray m_nameSeed; - QByteArray m_buffer; - ReLogger* m_logger; -public: - static const char ESC; -public: - static const int m_indexOfNodeChar[]; - static const char m_nodeChars[]; - static const int m_countNodeChars; + ReRandomizer::seed_t m_salt; }; #endif /* RANDOMIZER_H_ */ diff --git a/base/ReTest.cpp b/base/ReTest.cpp index c83bf7f..2035625 100644 --- a/base/ReTest.cpp +++ b/base/ReTest.cpp @@ -30,11 +30,11 @@ class ReTest; * @param name */ ReTest::ReTest(const char* name) : - m_errors(0), - m_name(name), - m_logger(), - m_memoryAppender(1024), - m_memoryLogger() { + m_errors(0), + m_name(name), + m_logger(), + m_memoryAppender(1024), + m_memoryLogger() { m_memoryAppender.setAutoDelete(false); m_logger.buildStandardAppender(getTempDir("retest")); log(QByteArray("Start of ") + m_name); @@ -74,10 +74,10 @@ ReTest::~ReTest() { * @return true: equal */ bool ReTest::assertEquals(int expected, int current, const char* file, - int lineNo) { + int lineNo) { if (expected != current) error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, - current, (unsigned int) expected, (unsigned int) current); + current, (unsigned int) expected, (unsigned int) current); return expected == current; } @@ -93,10 +93,10 @@ bool ReTest::assertEquals(int expected, int current, const char* file, * @return true: equal */ bool ReTest::assertEquals(int64_t expected, int64_t current, const char* file, - int lineNo) { + int lineNo) { if (expected != current) error("%s-%d: error: %lld != %lld / %llx != %llx)", file, lineNo, - expected, current, (quint64) expected, (quint64) current); + expected, current, (quint64) expected, (quint64) current); return expected == current; } @@ -112,10 +112,10 @@ bool ReTest::assertEquals(int64_t expected, int64_t current, const char* file, * @return true: equal */ bool ReTest::assertEquals(qreal expected, qreal current, const char* file, - int lineNo) { + int lineNo) { if (expected != current) error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, - current, (unsigned int) expected, (unsigned int) current); + current, (unsigned int) expected, (unsigned int) current); return expected == current; } @@ -131,9 +131,9 @@ bool ReTest::assertEquals(qreal expected, qreal current, const char* file, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const ReString& current, - const char* file, int lineNo) { + const char* file, int lineNo) { bool equal = assertEquals(expected, current.toUtf8().constData(), file, - lineNo); + lineNo); return equal; } @@ -149,9 +149,9 @@ bool ReTest::assertEquals(const char* expected, const ReString& current, * @return true: equal */ bool ReTest::assertEquals(const ReString& expected, const ReString& current, - const char* file, int lineNo) { + const char* file, int lineNo) { bool equal = assertEquals(expected.toUtf8().constData(), - current.toUtf8().constData(), file, lineNo); + current.toUtf8().constData(), file, lineNo); return equal; } @@ -167,7 +167,7 @@ bool ReTest::assertEquals(const ReString& expected, const ReString& current, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const char* current, - const char* file, int lineNo) { + const char* file, int lineNo) { bool equal = strcmp(expected, current) == 0; if (!equal) { if (strchr(expected, '\n') != NULL || strchr(current, '\n')) { @@ -187,11 +187,11 @@ bool ReTest::assertEquals(const char* expected, const char* current, *ptr = '\0'; if (ix < 10) error("%s-%d: error: diff at index %d\n%s\n%s\n%s", file, - lineNo, ix, expected, current, pointer); + lineNo, ix, expected, current, pointer); else error("%s-%d: error: diff at index %d\n%s\n...%s\n...%s\n%s", - file, lineNo, ix, current, expected + ix - 10 + 3, - current + ix - 10 + 3, pointer); + file, lineNo, ix, current, expected + ix - 10 + 3, + current + ix - 10 + 3, pointer); } } return equal; @@ -209,7 +209,7 @@ bool ReTest::assertEquals(const char* expected, const char* current, * @return true: equal */ bool ReTest::assertEquals(const QList& expected, - const QList& current, const char* file, int lineNo) { + const QList& current, const char* file, int lineNo) { int nMax = expected.size(); bool rc = true; if (current.size() < nMax) @@ -219,7 +219,7 @@ bool ReTest::assertEquals(const QList& expected, error("%s-%d: difference in line %d", file, lineNo, ix + 1); m_errors--; assertEquals(expected.at(ix).constData(), - current.at(ix).constData(), file, lineNo); + current.at(ix).constData(), file, lineNo); rc = false; break; } @@ -227,10 +227,10 @@ bool ReTest::assertEquals(const QList& expected, if (rc) { if (expected.size() > nMax) error("%s-%d: less lines than expected (%d):\n%s", file, lineNo, - nMax, expected.at(nMax).constData()); + nMax, expected.at(nMax).constData()); else if (expected.size() < nMax) error("%s-%d: more lines than expected (%d):\n%s", file, lineNo, - nMax, current.at(nMax).constData()); + nMax, current.at(nMax).constData()); } return rc; } @@ -246,7 +246,7 @@ bool ReTest::assertEquals(const QList& expected, * @return true: equal */ bool ReTest::assertEquals(const QByteArray& expected, const QByteArray& current, - const char* file, int lineNo) { + const char* file, int lineNo) { return assertEquals(expected.data(), current.data(), file, lineNo); } @@ -262,7 +262,7 @@ bool ReTest::assertEquals(const QByteArray& expected, const QByteArray& current, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const QByteArray& current, - const char* file, int lineNo) { + const char* file, int lineNo) { return assertEquals(expected, current.constData(), file, lineNo); } @@ -278,9 +278,9 @@ bool ReTest::assertEquals(const char* expected, const QByteArray& current, * @return true: equal */ bool ReTest::assertEquals(const QDate& expected, const QDate& current, - const char* file, int lineNo) { + const char* file, int lineNo) { return assertEquals(expected.toString("yyyy.MM.dd"), - current.toString("yyyy.MM.dd"), file, lineNo); + current.toString("yyyy.MM.dd"), file, lineNo); } /** @@ -295,9 +295,9 @@ bool ReTest::assertEquals(const QDate& expected, const QDate& current, * @return true: equal */ bool ReTest::assertEquals(const QDateTime& expected, const QDateTime& current, - const char* file, int lineNo) { + const char* file, int lineNo) { return assertEquals(expected.toString("yyyy.MM.dd hh:mm:ss"), - current.toString("yyyy.MM.dd hh:mm:ss"), file, lineNo); + current.toString("yyyy.MM.dd hh:mm:ss"), file, lineNo); } /** @@ -312,9 +312,9 @@ bool ReTest::assertEquals(const QDateTime& expected, const QDateTime& current, * @return true: equal */ bool ReTest::assertEquals(const QTime& expected, const QTime& current, - const char* file, int lineNo) { + const char* file, int lineNo) { return assertEquals(expected.toString("hh:mm:ss"), - current.toString("hh:mm:ss"), file, lineNo); + current.toString("hh:mm:ss"), file, lineNo); } /** @@ -392,19 +392,19 @@ bool ReTest::assertNotNull(const void* ptr, const char* file, int lineNo) { * false: otherwise */ bool ReTest::assertEqualFiles(const char* expected, const char* current, - const char* file, int lineNo) { + const char* file, int lineNo) { bool rc = false; QByteArray expectedContent = ReStringUtils::read(expected, true); QByteArray currentContent = ReStringUtils::read(current, true); if (expectedContent.isEmpty()) { char buffer[512]; qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", - expected); + expected); error(buffer); } else if (currentContent.isEmpty()) { char buffer[512]; qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", - current); + current); error(buffer); } else { QList < QByteArray > expLines = expectedContent.split('\n'); @@ -414,33 +414,48 @@ bool ReTest::assertEqualFiles(const char* expected, const char* current, return rc; } +/** + * @brief Writes an error. + * + * @param format message to show. With placeholders like std::printf() + * @param ... the values for the placeholders in format + * @return false (for chaining) + */ +bool ReTest::error(const char* format, ...) { + m_errors++; + va_list ap; + va_start(ap, format); + m_logger.log(LOG_ERROR, 0, format, ap); + va_end(ap); + return false; +} + /** * @brief Writes an info. * * @param message message to show - * @return true (for chaining) + * @return true (for expressions) */ bool ReTest::log(const char* message) { m_logger.log(LOG_INFO, 0, message); return true; } - /** - * @brief Writes an error. + * @brief Writes a message with arguments. * * @param format message to show. With placeholders like std::printf() * @param ... the values for the placeholders in format - * @return false (for chaining) + * @return true (for expressions) */ -bool ReTest::error(const char* format, ...) { - m_errors++; +bool ReTest::logv(const char* format, ...) { va_list ap; va_start(ap, format); - m_logger.log(LOG_ERROR, 0, format, ap); + m_logger.log(LOG_INFO, 0, format, ap); va_end(ap); - return false; + return true; } + /** * @brief Tests whether the m_memoryLogger has a message containing a given pattern. * @@ -475,7 +490,7 @@ bool ReTest::logContains(const char* pattern) { * @return the name of an existing directory */ QByteArray ReTest::getTempDir(const char* node, const char* parent, - bool withSeparator) { + bool withSeparator) { QByteArray temp("c:\\temp"); struct stat info; const char* ptr; @@ -514,7 +529,7 @@ QByteArray ReTest::getTempDir(const char* node, const char* parent, * @return the full name of a temporary file */ QByteArray ReTest::getTempFile(const char* node, const char* parent, - bool deleteIfExists) { + bool deleteIfExists) { QByteArray dir = getTempDir(parent); QByteArray rc = dir; if (!rc.endsWith(m_separator)) diff --git a/base/ReTest.hpp b/base/ReTest.hpp index d9ccd06..009ec26 100644 --- a/base/ReTest.hpp +++ b/base/ReTest.hpp @@ -26,39 +26,40 @@ protected: public: bool assertEquals(int expected, int current, const char* file, int lineNo); bool assertEquals(int64_t expected, int64_t current, const char* file, - int lineNo); + int lineNo); bool assertEquals(qreal expected, qreal current, const char* file, - int lineNo); + int lineNo); bool assertEquals(const char* expected, const ReString& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const ReString& expected, const ReString& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const char* expected, const char* current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const QByteArray& expected, const QByteArray& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const char* expected, const QByteArray& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const QDate& expected, const QDate& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const QDateTime& expected, const QDateTime& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const QTime& expected, const QTime& current, - const char* file, int lineNo); + const char* file, int lineNo); bool assertEquals(const QList& expected, - const QList& current, const char* file, int lineNo); + const QList& current, const char* file, int lineNo); bool assertTrue(bool condition, const char* file, int lineNo); bool assertFalse(bool condition, const char* file, int lineNo); bool assertNull(const void* ptr, const char* file, int lineNo); bool assertNotNull(const void* ptr, const char* file, int lineNo); bool assertEqualFiles(const char* expected, const char* current, - const char* file, int lineNo); - bool log(const char* message); + const char* file, int lineNo); bool error(const char* message, ...); + bool log(const char* message); + bool logv(const char* format...); QByteArray getTempDir(const char* node, const char* parent = NULL, - bool withSeparator = true); + bool withSeparator = true); QByteArray getTempFile(const char* node, const char* parent = NULL, - bool deleteIfExists = true); + bool deleteIfExists = true); bool logContains(const char* pattern); virtual void run(void) = 0; diff --git a/base/rebase.hpp b/base/rebase.hpp index 0f265c3..ca87e1e 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -74,6 +74,42 @@ typedef QString ReString; #define OS_2nd_SEPARATOR_STR "/" #endif +typedef union { +public: + inline void fromBytes(const uint8_t* source){ +#if ! defined __BIG_ENDIAN__ + m_int = *(int64_t*) source; +#else + m_bytes[0] = source[7]; + m_bytes[1] = source[6]; + m_bytes[2] = source[5]; + m_bytes[3] = source[4]; + m_bytes[4] = source[3]; + m_bytes[5] = source[2]; + m_bytes[6] = source[1]; + m_bytes[7] = source[0]; +#endif + } + inline void toBytes(uint8_t* target){ +#if ! defined __BIG_ENDIAN__ + *(int64_t*) target = m_int; +#else + target[0] = m_bytes[7]; + target[1] = m_bytes[6]; + target[2] = m_bytes[5]; + target[3] = m_bytes[4]; + target[4] = m_bytes[3]; + target[5] = m_bytes[2]; + target[6] = m_bytes[1]; + target[7] = m_bytes[0]; +#endif + } +public: + int64_t m_int; + uint8_t m_bytes[sizeof(int64_t)]; +} int64_converter_t; + + #define UNUSED_VAR(var) (void) var inline int max(int a, int b) { diff --git a/cunit/allTests.cpp b/cunit/allTests.cpp index 661c4da..192e6a2 100644 --- a/cunit/allTests.cpp +++ b/cunit/allTests.cpp @@ -94,8 +94,8 @@ static void testOs() { testReFileSystem(); } void allTests() { - testOs(); testBase(); + testOs(); testGui(); if (s_allTest) { testBase(); diff --git a/cunit/cuReRandomizer.cpp b/cunit/cuReRandomizer.cpp index 17ccd8d..baf7718 100644 --- a/cunit/cuReRandomizer.cpp +++ b/cunit/cuReRandomizer.cpp @@ -159,41 +159,6 @@ public: write1m(rand4); } - void testCharTables() { - for (int ix = 0; ix < ReNameScrambler::m_countNodeChars; ix++) { - char cc = ReNameScrambler::m_nodeChars[ix]; - int index = ReNameScrambler::m_indexOfNodeChar[(int) cc]; - checkEqu(ix, index); - } - for (unsigned char cc = 0; cc < 128; cc++) { - int index = ReNameScrambler::m_indexOfNodeChar[cc]; - if (index >= 0) { - unsigned char cc2 = ReNameScrambler::m_nodeChars[index]; - checkEqu(cc, cc2); - } - } - log("ready"); - } - void checkName(const char* name, ReNameScrambler& scrambler){ - QByteArray src(name); - QByteArray trg; - QByteArray trg2; - trg = src; - scrambler.encodeName(trg); - trg2 = trg; - scrambler.decodeName(trg2); - checkEqu(src, trg2); - } - - void testNamesEncoding(){ - QByteArray dir = ReFileUtils::tempDir("fs"); - ReKISSRandomizer nameRandom; - ReNameScrambler scrambler(nameRandom, &m_logger); - checkName("a.b", scrambler); - checkName("Ä.txt", scrambler); - checkName("Ää", scrambler); - checkName(".git", scrambler); - } void checkContent(const char* content, ReByteScrambler& scrambler){ QByteArray src(content); QByteArray trg; @@ -204,11 +169,11 @@ public: rand.nearTrueRandom(); QByteArray info; rand.nextString(10, 20, info); - scrambler.initHeader(metaInfoLength, markerLength, info); - scrambler.encodeContent(src, trg); + scrambler.initHeader(metaInfoLength, markerLength, 0, info); + scrambler.contentRandom(true).codec(trg, src); QByteArray info2; - scrambler.initFromHeader(metaInfoLength, markerLength, NULL, info2); - scrambler.decodeContent(trg, trg2); + scrambler.initFromHeader(metaInfoLength, markerLength, 0, NULL, info2); + scrambler.contentRandom(true).codec(trg2, trg); checkEqu(src, trg2); checkT(info.startsWith(info2)); } @@ -233,6 +198,16 @@ public: } checkContent(src, scrambler); } + src = "12345678abcdefghijklmn"; + QByteArray trg; + scrambler.contentRandom(true).codec(src, trg, 8); + checkEqu("12345678", trg.mid(0, 8)); + src = "1234XY78abcdefghijklmn"; + QByteArray trg2; + scrambler.contentRandom(true).codec(src, trg2, 8); + checkEqu("1234XY78", trg2.mid(0, 8)); + checkEqu(trg.mid(8), trg2.mid(8)); + } void testShuffle(){ ReKISSRandomizer random; @@ -418,8 +393,44 @@ public: void special(){ log("ready"); } + void checkCodec(ReRandomizer& random, const QByteArray src, int offset){ + QByteArray trg, trg2; + random.reset(); + random.codec(trg, src, offset); + random.reset(); + random.codec(trg2, trg, offset); + checkEqu(trg2, src); + } + + void testCodec(){ + ReKISSRandomizer random; + QByteArray src("12345678"); + checkCodec(random, src, 0); + QByteArray trg, trg2; + + ReKISSRandomizer random2; + int sumLength = 0; + for (int ii = 0; ii < 1000; ii++){ + random2.nextData(8, 80, src); + sumLength += src.length(); + int offset = 8 * random2.nextInt(src.length() / 8); + checkCodec(random, src, offset); + } + logv("sum length: %d", sumLength); + src.fill(0, 1024*1024); + clock_t start = clock(); + int mbytes = 100; + for (int ii = 0; ii < mbytes; ii++){ + random.codec(src); + } + double duration = double (clock() - start) / CLOCKS_PER_SEC; + logv("codec: %d MiByte %.3f sec %.1f MiBytes/sec", mbytes, duration, + mbytes / duration); + + } virtual void run(void) { + testCodec(); special(); testReHmHash64(); hashPerformance(); @@ -427,9 +438,7 @@ public: testRealRandom(); testShuffle(); special(); - testContentEncoding(); - testNamesEncoding(); - testCharTables(); + //testContentEncoding(); testModifySeed(); testTextToSeed(); testWrite1m(); diff --git a/os/ReCryptFileSystem.cpp b/os/ReCryptFileSystem.cpp index 06f4a94..5e4e44a 100644 --- a/os/ReCryptFileSystem.cpp +++ b/os/ReCryptFileSystem.cpp @@ -450,7 +450,7 @@ bool ReCryptDirectory::readMetaFile() fnMetaFile.toUtf8().constData(), nRead, META_DIR_HEADER_LENGTH); } else { QByteArray info; - rc = initFromHeader(META_INFO_LENGTH, MARKER_LENGTH, &header, info); + rc = initFromHeader(META_INFO_LENGTH, MARKER_LENGTH, 0, &header, info); if (rc){ const MetaInfo_t* meta = reinterpret_cast(info.constData()); if (meta->m_countFiles > 0){ @@ -462,7 +462,7 @@ bool ReCryptDirectory::readMetaFile() sumLength += nRead; if (nRead < m_blockSize) m_fileBuffer.resize(nRead); - decodeContent(m_fileBuffer, m_fileBuffer); + m_contentRandom.codec(m_fileBuffer); m_entryBuffer.append(m_fileBuffer); splitBlock(sumLength < meta->m_size, m_entryBuffer); @@ -499,7 +499,7 @@ bool ReCryptDirectory::writeMetaFile() int length = it->m_node.toUtf8().length(); meta2->m_size += length + (length < 256 ? 0 : 1); } - initHeader(META_INFO_LENGTH, MARKER_LENGTH, meta); + initHeader(META_INFO_LENGTH, MARKER_LENGTH, 0, meta); QByteArray node; for (it = m_list.cbegin(); it != m_list.cend(); ++it){ node = it->m_node.toUtf8(); @@ -541,7 +541,7 @@ bool ReCryptDirectory::writeMetaFile() m_fileBuffer.resize(newLength); } int offset = ixList <= 1 ? META_DIR_HEADER_LENGTH : 0; - encodeContent(m_fileBuffer, m_fileBuffer, offset); + m_contentRandom.codec(m_fileBuffer, m_fileBuffer, offset); int nWritten = fwrite(m_fileBuffer.constData(), 1, m_fileBuffer.length(), fp); if (nWritten != m_fileBuffer.length()){ @@ -748,7 +748,7 @@ ReFileSystem::ErrorCode ReCryptFile::write(const QByteArray& data) } m_dataSize += data.length(); if (rc == ReFileSystem::EC_SUCCESS){ - m_directory.encodeContent(data, target); + m_directory.contentRandom(false).codec(target, data); m_sumOfEncrypted.updateBlock(target); } return rc; -- 2.39.5