LOC_UPDATE_1, // 22204
};
-const char ReNameScrambler::ESC = '%';
-
const int64_t ReRandomizer::m_primes64[] = {
7919787109669756829L, // 6de8 bc6a 5895 5f9d
8190338840038832831L, // 71a9edc7de997abf
};
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.
return buffer.constData();
}
+/**
+ * Convert a clear text into scrambled data and vice versa.
+ *
+ * <ul><li>The algorithm is symetric: the same method can be used for encoding and
+ * decoding.</li>
+ * <li>the result is the same for little and big endian architectures.</li>
+ * <li>Large data blocks can be de/encoded in parts if the parts have the length
+ * N*8 (multiples of 8 bytes).</li>
+ * </ul>
+ *
+ * @param target OUT: the target buffer
+ * @param source the source to scramble. May be identical <code>target</code>
+ * @param length the length of <code>source</code> 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.
*
m_contentSeed(),
m_buffer(),
m_header(),
- m_logger(logger)
+ m_logger(logger),
+ m_salt(0)
{
m_contentRandom.saveSeed(m_contentSeed);
m_buffer.reserve(256);
}
/**
- * Constructor.
+ * Returns the pseudo random generator used for data encryption.
*
- * @param nameRandom a pseudo random generator
- * @param logger the logger
+ * @param doReset <code>true</code>: 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<br>
- * Can be identical to <code>source</code> (in place replacement)
- * @param offset decoding start at this content
- * @return <code>true</code>: successful<br>
- * <code>false</code>: 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<int64_t*>(target.data());
- int count = (source.length() - offset) / sizeof(int64_t);
- const int64_t* src = reinterpret_cast<const int64_t*>(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<char*>(trg);
- char lastTail = (char) last;
- const char* srcTail = reinterpret_cast<const char*>(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 <code>source</code> (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<int64_t*>(target.data());
- int count = source.length() / sizeof(int64_t);
- const int64_t* src = reinterpret_cast<const int64_t*>(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<char*>(trg);
- char lastTail = (char) last;
- const char* srcTail = reinterpret_cast<const char*>(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;
}
/**
*
* @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 <code>true</code>: 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;
header->length(), headerLength);
rc = false;
} else {
- int64_t random = * reinterpret_cast<const int64_t*>(header->constData());
+ m_salt = * reinterpret_cast<const int64_t*>(header->constData());
m_contentRandom.reset();
- m_contentRandom.modifySeed(random);
+ m_contentRandom.modifySeed(m_salt);
QByteArray marker;
marker.append(reinterpret_cast<const char*>(header->constData()+ sizeof(int64_t)),
markerLength);
/**
* Initializes the scrambler header.
*
- *
* Format of the header:
* <pre>random (8 byte)
* marker (m_markerLength byte)
*
* @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<int64_t*>(m_header.data()) = random;
+ * reinterpret_cast<int64_t*>(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<char*>(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<char*>(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:
- * <ul><li>Invert the name without extension (first char becomes the last),
- * add the extension</li>
- * <li>Replace the "unconvertable" chars (< 127) into "%xx" ('%' with 2 hexdigits)</li>
- * <li>exchange the char with a value generated by the pseudo random generator</li>
- * </ul>
- * @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<char*>(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());
}
-
-
-
int64_t m_sumLength;
QByteArray m_rest;
};
-
/**
* This implements an abstract base class for random generators.
*/
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();
/**
* 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;
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_ */
* @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);
* @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;
}
* @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;
}
* @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;
}
* @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;
}
* @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;
}
* @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')) {
*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;
* @return true: equal
*/
bool ReTest::assertEquals(const QList<QByteArray>& expected,
- const QList<QByteArray>& current, const char* file, int lineNo) {
+ const QList<QByteArray>& current, const char* file, int lineNo) {
int nMax = expected.size();
bool rc = true;
if (current.size() < nMax)
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;
}
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;
}
* @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);
}
* @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);
}
* @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);
}
/**
* @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);
}
/**
* @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);
}
/**
* 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');
return rc;
}
+/**
+ * @brief Writes an error.
+ *
+ * @param format message to show. With placeholders like <code>std::printf()</code>
+ * @param ... the values for the placeholders in <code>format</code>
+ * @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 <code>std::printf()</code>
* @param ... the values for the placeholders in <code>format</code>
- * @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.
*
* @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;
* @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))
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<QByteArray>& expected,
- const QList<QByteArray>& current, const char* file, int lineNo);
+ const QList<QByteArray>& 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;
#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) {
testReFileSystem();
}
void allTests() {
- testOs();
testBase();
+ testOs();
testGui();
if (s_allTest) {
testBase();
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;
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));
}
}
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;
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();
testRealRandom();
testShuffle();
special();
- testContentEncoding();
- testNamesEncoding();
- testCharTables();
+ //testContentEncoding();
testModifySeed();
testTextToSeed();
testWrite1m();
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<const MetaInfo_t*>(info.constData());
if (meta->m_countFiles > 0){
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);
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();
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()){
}
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;