--- /dev/null
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+
+
--- /dev/null
+/*
+ * Prime.cpp
+ *
+ * Created on: Oct 8, 2015
+ * Author: kawi
+ */
+#include "math.h"
+#include "stdlib.h"
+#include "math.h"
+#include "stdio.h"
+#include "unistd.h"
+#include "time.h"
+#include "assert.h"
+#include "base/rebase.hpp"
+#include "Prime.hpp"
+
+Prime::Prime(int64_t from, int count) :
+ m_from(from),
+ m_count(count),
+ m_primes(NULL),
+ m_sizePrimes(0),
+ m_countPrimes(0),
+ m_maxStoredPrimes(0){
+ m_maxStoredPrimes = int (sqrt((double) m_from / 3 / log(sqrt(m_from)))) + 100;
+ m_sizePrimes = m_maxStoredPrimes + 10;
+ fprintf(stderr, "Storing %d primes\n", m_sizePrimes);
+ m_primes = new int64_t[m_sizePrimes];
+ m_primes[0] = 2;
+ m_countPrimes = 1;
+}
+
+Prime::~Prime() {
+}
+void toFile(const char* prefix, int64_t* primes, int count){
+ QByteArray fn = QByteArray(prefix) + "."
+ + QDateTime::currentDateTime().toLocalTime()
+ .toString("yyyy.MM.dd_hh_mm_ss").toUtf8() + ".txt";
+ FILE* fp = fopen(fn.constData(), "w");
+ if (fp != NULL){
+ fprintf(stderr, "Result in %s\n", fn.constData());
+ for (int ix = 0; ix < count; ix++){
+ fprintf(fp, "%lldL, // %llx\n",
+ (long long) primes[ix], (long long) primes[ix]);
+ }
+ fclose(fp);
+ }
+
+}
+
+void Prime::calculate() {
+ int64_t x = lastPrime() * lastPrime();
+ int64_t* primes = new int64_t[m_count];
+
+ assert(x % 2 == 1);
+ int nPrinted = 0;
+ while (nPrinted < m_count){
+ while (x > 0){
+ x -= 2;
+ bool isPrime = true;
+ for (int ix = 0; ix < m_countPrimes; ix++){
+ int64_t fac = m_primes[ix];
+ if (x % fac == 0){
+ isPrime = false;
+ break;
+ }
+ }
+ if (isPrime){
+ printf("%lld, // %llx\n", (long long) x, (long long) x);
+ fflush(stdout);
+ primes[nPrinted++] = x;
+ x -= m_from / m_count / 5;
+ if (x % 2 == 0)
+ x--;
+ break;
+ }
+ }
+ }
+ toFile("primes.sorted", primes, m_count);
+ ReKISSRandomizer random;
+ random.nearTrueRandom();
+ random.shuffle(primes, m_count, sizeof primes[0]);
+ toFile("primes.shuffled", primes, m_count);
+}
+
+void Prime::storePrimes() {
+ clock_t start = clock();
+ int counter2 = 0;
+ for (int64_t x = 3; true; x += 2){
+ if (x % (10*1000*1000) == 1){
+ fprintf(stderr, "%ld Mio: %8.3f\n", x / (1000*1000),
+ (clock() - start) / double(CLOCKS_PER_SEC));
+ if (counter2++ % 5 == 0)
+ dump();
+ fflush(stderr);
+ }
+ bool isPrime = true;
+ for (int ix = 0; ix < m_countPrimes; ix++){
+ int64_t fac = m_primes[ix];
+ if (x % fac == 0){
+ isPrime = false;
+ break;
+ } else if (fac * fac > x)
+ break;
+ }
+ if (isPrime) {
+ m_primes[m_countPrimes++] = x;
+ if (m_countPrimes >= m_maxStoredPrimes || x * x > m_from)
+ break;
+ }
+ }
+ dump();
+}
+
+void Prime::dump() {
+ int64_t last = lastPrime();
+ fprintf(stderr, "count primes: %d size primes: %d last prime: %ld lp*lp: %ld\n",
+ m_countPrimes, m_sizePrimes, last, last * last);
+}
+
+void Prime::run(int argc, char* argv[]){
+ int64_t from = 0x82L * 0x10000 * 0x10000 * 10000; //* 0x10000;
+ int count = 150;
+ if (argc > 1){
+ int64_t lValue;
+ if (sscanf(argv[1], "0x%lx", &lValue) == 1){
+ } else if (sscanf(argv[1], "%ld", &lValue) != 1)
+ printf("wrong argument 1: %s", argv[1]);
+ else
+ from = lValue;
+
+ if (argc > 2){
+ int nValue;
+ if (sscanf(argv[2], "%d", &nValue) != 1)
+ printf("wrong argument 2: %s", argv[2]);
+ else
+ count = nValue;
+ }
+ }
+
+ fprintf(stderr, "from: %ld/%lx count: %d\n", from, from, count);
+ clock_t start = clock();
+ Prime prime(from, count);
+ prime.storePrimes();
+ fprintf (stderr, "storePrime: %f sec\n",
+ double (clock() - start) / CLOCKS_PER_SEC);
+ prime.dump();
+ prime.calculate();
+ double duration = double (clock() - start) / CLOCKS_PER_SEC;
+ fprintf (stderr, "duration: %f sec\n", duration);
+}
+
--- /dev/null
+/*
+ * Prime.hpp
+ *
+ * Created on: Oct 8, 2015
+ * Author: kawi
+ */
+
+#ifndef PRIME_HPP_
+#define PRIME_HPP_
+
+//typedef long long int int64_t;
+class Prime {
+public:
+ Prime(int64_t from, int count);
+ virtual ~Prime();
+public:
+ void storePrimes();
+ void calculate();
+ void dump();
+ int64_t lastPrime() const {
+ return m_primes[m_countPrimes - 1];
+ }
+public:
+ static void run(int argc, char* argv[]);
+private:
+ int64_t m_from;
+ int m_count;
+ int64_t* m_primes;
+ int m_sizePrimes;
+ int m_countPrimes;
+ int m_maxStoredPrimes;
+};
+
+#endif /* PRIME_HPP_ */
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#include <QCoreApplication>
+#include "Prime.hpp"
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+ Prime::run(argc, argv);
+ exit(0);
+ return a.exec();
+}
+
--- /dev/null
+QT += core network gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = reprime
+
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+INCLUDEPATH = ../..
+
+SOURCES += main.cpp \
+ ../../base/ReLogger.cpp \
+ ../../base/ReRandomizer.cpp \
+ ../../base/ReStringUtils.cpp \
+ ../../base/ReException.cpp \
+ Prime.cpp
+
+
const char ReNameScrambler::ESC = '%';
-const int ReRandomizer::m_primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
- 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
- 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
- 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
- 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373,
- 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
- 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
- 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653,
- 659, 661, 673, 677, 683, 691 };
+const int64_t ReRandomizer::m_primes[] = {
+ 4794328877860651L, // 11086aadb3872b
+ 4958110297415603L, // 119d600308dfb3
+ 4623102848326049L, // 106cb00308d9a1
+ 4891108807597633L, // 1160700308de41
+ 4578435188447437L, // 1044100308d8cd
+ 5546234485817489L, // 13b445585e4091
+ 5389897676242243L, // 132615585e3d43
+ 4786884267880873L, // 1101a5585e31a9
+ 5241005476646707L, // 129eaaadb38f33
+ 4734771998022511L, // 10d2400308db6f
+ 5278228526545621L, // 12c085585e3ad5
+ 4652881288245079L, // 1087c5585e2f57
+ 5181448596808493L, // 1268800308e32d
+ 4920887247516739L, // 117b85585e3443
+ 5360119236323197L, // 130b000308e77d
+ 5471788386019861L, // 1370900308ea15
+ 4645436678265319L, // 1081000308d9e7
+ 4481655258710579L, // fec0aadb38233
+ 5523900655878179L, // 139ff5585e4023
+ 5203782426747811L, // 127cd00308e3a3
+ 5375008456282711L, // 13188aadb39257
+ 5226116256687127L, // 1291200308e417
+ 5419676116161323L, // 13412aadb3932b
+ 5218671646707367L, // 128a5aadb38ea7
+ 5136780936929903L, // 123fe00308e26f
+ 4556101358508169L, // 102fc00308d889
+ 5263339306586077L, // 12b2faadb38fdd
+ 4518878308609331L, // 100de5585e2d33
+ 4533767528568833L, // 101b700308d801
+ 4764550437941633L, // 10ed55585e3181
+ 5509011435918673L, // 13926aadb39551
+ 5166559376848937L, // 125af5585e3829
+ 4489099868690317L, // ff2d00308d78d
+ 4727327388042733L, // 10cb7aadb385ed
+ 5330340796404157L, // 12efeaadb391bd
+ 4801773487840397L, // 110f300308dc8d
+ 5397342286222069L, // 132cdaadb392f5
+ 5308006966464857L, // 12db9aadb39159
+ 5084668667071573L, // 12107aadb38c55
+ 4816662707799941L, // 111cbaadb38785
+ 4704993558103493L, // 10b72aadb385c5
+ 5114447106990601L, // 122b900308e209
+ 4712438168083259L, // 10bdf00308db3b
+ 5479232995999613L, // 137755585e3f7d
+ 4660325898224963L, // 108e8aadb38543
+ 5040001007192867L, // 11e7daadb38b23
+ 4972999517375089L, // 11aaeaadb38a71
+ 4853885757698843L, // 113e95585e331b
+ 5315451576444613L, // 12e2600308e6c5
+ 5412231506181583L, // 133a65585e3dcf
+ 5144225546909639L, // 1246a5585e37c7
+ 4548656748528367L, // 1028faadb382ef
+ 4615658238346273L, // 1065eaadb38421
+ 5583457535716339L, // 13d6200308ebf3
+ 4474210648730791L, // fe545585e2ca7
+ 4838996537739323L, // 11310aadb3883b
+ 4600769018386699L, // 1058600308d90b
+ 4742216608002253L, // 10d905585e30cd
+ 4570990578467701L, // 103d4aadb38375
+ 5032556397213109L, // 11e115585e35b5
+ 5025111787233371L, // 11da500308e05b
+ 5568568315756819L, // 13c895585e4113
+ 5174003986828717L, // 1261baadb38dad
+ 4675215118184491L, // 109c15585e302b
+ 5494122215959133L, // 1384e00308ea5d
+ 4980444127354847L, // 11b1b00308dfdf
+ 4697548948123739L, // 10b065585e305b
+ 4779439657901123L, // 10fae00308dc43
+ 5129336326950151L, // 12391aadb38d07
+ 5464343776040087L, // 1369caadb39497
+ 5248450086626447L, // 12a5700308e48f
+ 4905998027557141L, // 116dfaadb38915
+ 5047445617172633L, // 11eea00308e099
+ 5345230016363663L, // 12fd75585e3c8f
+ 5442009946100803L, // 13557aadb39443
+ 4630547458305841L, // 107375585e2f31
+ 5501566825938893L, // 138ba5585e3fcd
+ 5077224057091819L, // 1209b5585e36eb
+ 4913442637536913L, // 1174c00308de91
+ 4935776467476299L, // 1189100308df4b
+ 4541212138548581L, // 102235585e2d65
+ 5404786896201841L, // 1333a00308e871
+ 5159114766869153L, // 1254300308e2a1
+ 5010222567273893L, // 11ccc5585e35a5
+ 5531345265857969L, // 13a6baadb395b1
+ 4757105827961849L, // 10e6900308dbf9
+ 4563545968487959L, // 103685585e2e17
+ 4719882778062997L, // 10c4b5585e3095
+ 4928331857496557L, // 11824aadb389ed
+ 5322896186424389L, // 12e925585e3c45
+ 5538789875837723L, // 13ad800308eb1b
+ 4690104338143981L, // 10a9a00308daed
+ 4943221077456049L, // 118fd5585e34b1
+ 4987888737334627L, // 11b875585e3563
+ 5300562356485079L, // 12d4d5585e3bd7
+ 5367563846302937L, // 1311c5585e3cd9
+ 5293117746505229L, // 12ce100308e60d
+ 5255894696606263L, // 12ac35585e3a37
+ 5211227036727601L, // 128395585e3931
+ 5285673136525447L, // 12c74aadb39087
+ 4526322918589091L, // 1014aaadb382a3
+ 4593324408406963L, // 10519aadb383b3
+ 5449454556080573L, // 135c400308e9bd
+ 4995333347314369L, // 11bf3aadb38ac1
+ 5107002497010847L, // 1224caadb38c9f
+ 5382453066262463L, // 131f500308e7bf
+ 5553679095797237L, // 13bb0aadb395f5
+ 4898553417577403L, // 116735585e33bb
+ 4682659728164237L, // 10a2daadb3858d
+ 4771995047921369L, // 10f41aadb386d9
+ 4585879798427209L, // 104ad5585e2e49
+ 5069779447111979L, // 1202f00308e12b
+ 4861330367678597L, // 11455aadb38885
+ 4965554907395353L, // 11a425585e3519
+ 5188893206788243L, // 126f45585e3893
+ 4831551927759449L, // 112a45585e3259
+ 5337785406383909L, // 12f6b00308e725
+ 5092113277051363L, // 1217400308e1e3
+ 5456899166060341L, // 136305585e3f35
+ 5427120726141077L, // 1347f00308e895
+ 5270783916565829L, // 12b9c00308e545
+ 5561123705777023L, // 13c1d00308eb7f
+ 4749661217982049L, // 10dfcaadb38661
+ 5121891716970409L, // 123255585e37a9
+ 5486677605979391L, // 137e1aadb394ff
+ };
const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes
/ sizeof(int);
const int ReNameScrambler::m_indexOfNodeChar[] = { -1, -1, -1, -1, -1, -1, -1,
maxValue = rc;
}
seed_t seed = nextSeed64();
+ if (minValue >= 0)
+ seed = abs(seed);
if (minValue == maxValue)
rc = minValue;
else {
*
* The operation will be done in place:
*
- * @param array In/Out: The array to shuffle.
- * @param length The length of the array.
- * @param elemSize The size of one element of the array.
+ * @param array IN/OUT: the array to shuffle
+ * @param length the length of the array
+ * @param elemSize the size of one element of the array
+ * @param exchanges count of exchanges: two randomly selected entries will be
+ * exchanged. If <= 0 a default value will be taken: 1.5*length
*/
-void ReRandomizer::shuffle(void* array, size_t length, size_t elemSize) {
+void ReRandomizer::shuffle(void* array, size_t length, size_t elemSize,
+ int exchanges) {
int ii;
char* cptr;
int* iptr;
- int count = length * 3 / 2;
-
+ int64_t* i64ptr;
+ int count = exchanges <= 0 ? length * 3 / 2 : exchanges;
+ int maxIx = length - 1;
switch (elemSize) {
case 1:
cptr = (char*) array;
for (ii = 0; ii < count; ii++) {
- int ix1 = length - nextInt(1, length);
- int ix2 = length - nextInt(1, length);
+ int ix1 =nextInt(maxIx);
+ int ix2 =nextInt(maxIx);
char x = cptr[ix1];
cptr[ix1] = cptr[ix2];
cptr[ix2] = x;
case sizeof(int):
iptr = (int*) array;
for (ii = 0; ii < count; ii++) {
- int ix1 = length - nextInt(1, length);
- int ix2 = length - nextInt(1, length);
+ int ix1 =nextInt(maxIx);
+ int ix2 =nextInt(maxIx);
int x = iptr[ix1];
iptr[ix1] = iptr[ix2];
iptr[ix2] = x;
}
break;
+ case sizeof(int64_t):
+ i64ptr = (int64_t*) array;
+ for (ii = 0; ii < count; ii++) {
+ int ix1 = nextInt(maxIx);
+ int ix2 = nextInt(maxIx);
+ if (i64ptr[ix1] <= 0 || i64ptr[ix2] <= 0)
+ ix1 += 0;
+ int64_t x = i64ptr[ix1];
+ i64ptr[ix1] = i64ptr[ix2];
+ i64ptr[ix2] = x;
+ }
+ break;
default: {
char buffer[0x10000];
assert(elemSize < sizeof buffer);
iptr = (int*) array;
for (ii = 0; ii < count; ii++) {
- int ix1 = length - nextInt(1, length);
- int ix2 = length - nextInt(1, length);
+ int ix1 =nextInt(maxIx);
+ int ix2 =nextInt(maxIx);
char* p1 = ((char*) array) + ix1 * elemSize;
char* p2 = ((char*) array) + ix2 * elemSize;
memcpy(buffer, p1, elemSize);
*/
ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed64() {
m_currentSeed = (m_currentSeed + 1) % m_countSeeds;
- seed_t rc = m_seeds[m_currentSeed] * m_factor + m_increment;
+ int ixFactor = int((m_seeds[m_currentSeed] >> 7) % (m_countPrimes - 1));
+ seed_t rc = m_seeds[m_currentSeed] * m_primes[ixFactor]
+ + (m_primes[ixFactor + 1] >> 1);
m_seeds[m_currentSeed] = rc;
rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffLL);
++m_counter;
* @param contentRandom a pseudo random generator
* @param logger the logger
*/
-ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom,
- int reservedLength, int markerLength, ReLogger* logger) :
+ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger) :
m_contentRandom(contentRandom),
m_realRandom(),
m_contentSeed(),
m_buffer(),
m_header(),
- m_reservedLength(reservedLength),
- m_markerLength(max(0, min(sizeof(int64_t), markerLength))),
- m_headerLength(0),
m_logger(logger)
{
m_contentRandom.saveSeed(m_contentSeed);
m_buffer.reserve(256);
m_realRandom.nearTrueRandom();
- m_headerLength = sizeof (int64_t) + markerLength + m_reservedLength;
- m_header.resize(m_headerLength);
}
/**
/**
* Initializes the scrambler from a header.
*
- * @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
+ * @param metaInfoLength the length of the "reserved area"
+ * @param markerLength length of a mark to ensure header's integrity
+ * @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(const QByteArray* header, QByteArray& info)
+bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength,
+ const QByteArray* header, QByteArray& info)
{
TRACE("initFromHeader():\n");
bool rc = true;
if (header == NULL)
header = &m_header;
- if (header->length() < m_headerLength ){
+ int headerLength = sizeof(int64_t) + markerLength + metaInfoLength;
+ if (header->length() < headerLength ){
m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_1, "header length too small: %d/%d",
- header->length(), m_headerLength);
+ header->length(), headerLength);
rc = false;
} else {
int64_t random = * reinterpret_cast<const int64_t*>(header->constData());
m_contentRandom.modifySeed(random);
QByteArray marker;
marker.append(reinterpret_cast<const char*>(header->constData()+ sizeof(int64_t)),
- m_markerLength);
+ markerLength);
QByteArray marker2;
- m_contentRandom.nextString(m_markerLength, m_markerLength, marker2);
- if (marker != marker2){
- m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_2, "invalid marker: %s / %s",
- ReStringUtils::hexDump(marker, m_markerLength, m_markerLength).constData(),
- ReStringUtils::hexDump(marker2, m_markerLength, m_markerLength).constData());
- rc = false;
+ if (markerLength > 0){
+ m_contentRandom.nextString(markerLength, markerLength, marker2);
+ if (marker != marker2){
+ m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_2, "invalid marker: %s / %s",
+ ReStringUtils::hexDump(marker, markerLength, markerLength).constData(),
+ ReStringUtils::hexDump(marker2, markerLength, markerLength).constData());
+ rc = false;
+ }
}
char last = 0x47;
- const char* src = reinterpret_cast<const char*>(header->data() + sizeof (int64_t) + m_markerLength);
+ const char* src = reinterpret_cast<const char*>(header->data()
+ + sizeof (int64_t) + markerLength);
int length = *src++;
TRACE1("info: Length: %d\n", length);
info.resize(0);
/**
* Initializes the scrambler header.
*
+ *
* Format of the header:
* <pre>random (8 byte)
* marker (m_markerLength byte)
- * reserved (m_reservedLength byte)
+ * reserved (reservedLength byte)
* </pre>
*
- * @param info the content of the "reserved area"
+ * @param metaInfoLength the length of the "reserved area"
+ * @param markerLength length of a mark to ensure header's integrity
+ * @param info the content of the "reserved area". If too few space
+ * the content will be cut
*/
-void ReByteScrambler::initHeader(const QByteArray& info)
+void ReByteScrambler::initHeader(int metaInfoLength, int markerLength,
+ const QByteArray& info)
{
TRACE("initHeader():\n");
int64_t random = m_realRandom.nextSeed64();
m_contentRandom.reset();
m_contentRandom.modifySeed(random);
- m_header.fill(' ', m_headerLength);
+ int headerLength = sizeof(int64_t) + markerLength + metaInfoLength;
+ m_header.fill(' ', headerLength);
* reinterpret_cast<int64_t*>(m_header.data()) = random;
- if (m_markerLength > 0){
+ if (markerLength > 0){
m_buffer.resize(0);
- m_contentRandom.nextString(m_markerLength, m_markerLength, m_buffer);
- memcpy(m_header.data() + sizeof(int64_t), m_buffer, m_markerLength);
+ 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) + m_markerLength);
- int infoLength = min(info.length(), m_reservedLength - 1);
- TRACE2("info: length: %d reserved: %d\n", infoLength, m_reservedLength);
+ 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 < m_reservedLength; ix++){
+ for (int ix = 0; ix < infoLength && ix < metaInfoLength; ix++){
last = *trg++ = m_contentRandom.nextChar() ^ info.at(ix) ^ last;
}
TRACE_IT(("random: %016lx marker: %s\n", random,
int nextInt(int maxValue = INT_MAX, int minValue = 0);
int64_t nextInt64(int64_t maxValue = LLONG_MAX, int64_t minValue = 0);
const char* nextString(int minLength, int maxLength, QByteArray& buffer);
- void shuffle(void* array, size_t length, size_t elemSize);
+ void shuffle(void* array, size_t length, size_t elemSize,
+ int exchanges = -1);
public:
virtual void dump() {
}
int m_counter;
public:
// the first 125 prime numbers
- static const int m_primes[];
+ static const int64_t m_primes[];
static const int m_countPrimes;
};
*/
class ReByteScrambler{
public:
- ReByteScrambler(ReRandomizer& contentRandom,
- int reservedLength, int markerLength, ReLogger* logger);
+ ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger);
public:
bool decodeContent(const QByteArray& source, QByteArray& target);
void encodeContent(const QByteArray& source, QByteArray& target);
- void initHeader(const QByteArray& info = ReStringUtils::m_empty);
- bool initFromHeader(const QByteArray* header, QByteArray& info);
+ void initHeader(int metaInfoLength, int markerLength,
+ const QByteArray& info = ReStringUtils::m_empty);
+ bool initFromHeader(int metaInfoLength, int markerLength,
+ const QByteArray* header, QByteArray& info);
protected:
ReRandomizer& m_contentRandom;
ReKISSRandomizer m_realRandom;
QByteArray m_contentSeed;
QByteArray m_buffer;
QByteArray m_header;
- int m_reservedLength;
- int m_markerLength;
- int m_headerLength;
ReLogger* m_logger;
};
QByteArray src(content);
QByteArray trg;
QByteArray trg2;
+ int markerLength = 4;
+ int metaInfoLength = 8;
ReKISSRandomizer rand;
rand.nearTrueRandom();
QByteArray info;
rand.nextString(10, 20, info);
- scrambler.initHeader(info);
+ scrambler.initHeader(metaInfoLength, markerLength, info);
scrambler.encodeContent(src, trg);
QByteArray info2;
- scrambler.initFromHeader(NULL, info2);
+ scrambler.initFromHeader(metaInfoLength, markerLength, NULL, info2);
scrambler.decodeContent(trg, trg2);
checkEqu(src, trg2);
checkT(info.startsWith(info2));
}
void testContentEncoding(){
ReKISSRandomizer dataRandom;
- ReByteScrambler scrambler(dataRandom, 8, 4, &m_logger);
+ ReByteScrambler scrambler(dataRandom, &m_logger);
checkContent("12345678abc", scrambler);
checkContent("8765432112345678ab", scrambler);
checkContent("8765432112345678", scrambler);
cuReStateStorage.cpp \
cuReSettings.cpp \
cuReMatcher.cpp \
- allTests.cpp
+ allTests.cpp \
+ ../os/ReCryptFileSystem.cpp
HEADERS += \
../base/ReFile.hpp \
../base/rebase.hpp \
../gui/ReEdit.hpp \
../math/ReMatrix.hpp \
- ../math/remath.hpp
+ ../math/remath.hpp \
+ ../os/ReCryptFileSystem.hpp
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#include "base/rebase.hpp"
+#include "os/reos.hpp"
+
+enum {
+ LOC_ADD_ENTRY_1 = LOC_FIRST_OF(LOC_CRYPTFILESYSTEM), // 12301
+ LOC_REMOVE_ENTRY_1, // 12302
+ LOC_READ_META_FILE_1, // 12303
+ LOC_READ_META_FILE_2, // 12304
+ LOC_READ_META_FILE_3, // 12305
+ LOC_WRITE_META_1, // 12306
+ LOC_WRITE_META_2, // 12307
+};
+
+const int ReCryptFileSystem::NODE_LENGHT = 44;
+const int ReCryptFileSystem::MARKER_LENGHT = 4;
+const int ReCryptFileSystem::CHECKSUM_LENGHT = 16;
+const int ReCryptFileSystem::HEADER_LENGTH = sizeof(int64_t)
+ + ReCryptFileSystem::NODE_LENGHT
+ + ReCryptFileSystem::MARKER_LENGHT;
+const QString ReCryptFileSystem::NODE_META_DEVICE = ".0";
+const QString ReCryptFileSystem::NODE_META_DIR = ".1";
+const int ReCryptDirectory::MARKER_LENGTH = 4;
+const int ReCryptDirectory::META_INFO_LENGTH = sizeof (ReCryptDirectory::MetaInfo_t);
+const int ReCryptDirectory::META_DIR_HEADER_LENGTH = sizeof(int64_t)
+ + ReCryptDirectory::MARKER_LENGTH + ReCryptDirectory::META_INFO_LENGTH;
+// space for the struct and the node:
+const int ReCryptDirectory::MAX_ENTRY_SIZE = sizeof(ReCryptDirectory::FileEntry_t)
+ + 512;
+
+/**
+ * Constructor.
+ *
+ * @param hostFileSystem the filesystem which does the storage (with
+ * encrypted names and content
+ * @param nameRandom a pseudo random generator for names
+ * @param contentRandom a pseudo random generator for content
+ */
+ReCryptFileSystem::ReCryptFileSystem(ReFileSystem& hostFileSystem,
+ ReRandomizer& contentRandom, ReLogger* logger) :
+ ReFileSystem("cryptfs", logger),
+ ReCryptDirectory(contentRandom, this, logger),
+ m_host(hostFileSystem)
+{
+}
+
+/**
+ * Destructor.
+ */
+ReCryptFileSystem::~ReCryptFileSystem() {
+}
+
+/** Frees resources like open files.
+ */
+void ReCryptFileSystem::close()
+{
+}
+
+/**
+ * Fills a list with the items of the current directory.
+ *
+ * @param matcher the matching processor
+ * @return the count of the found entries (<code>list.size()</code>)
+ */
+int ReCryptFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher,
+ ReFileMetaDataList& list) {
+ return 0;
+}
+
+/**
+ * Creates a directory.
+ *
+ * @param node the name without path (in the current directory)
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::makeDir(const QString& node) {
+ return EC_SUCCESS;
+}
+
+/**
+ * Reads a part of a file into a buffer.
+ *
+ * @param source the file to read (inside the current directory)
+ * @param offset first position to read
+ * @param size number of bytes to read
+ * @param buffer OUT: content of the file
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::read(const ReFileMetaData& source,
+ int64_t offset, int size, QByteArray& buffer) {
+ return EC_SUCCESS;
+}
+
+/** Removes a file or directory.
+ * @param node the properties ot the node (in the current directory)
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::remove(const ReFileMetaData& node)
+{
+ return EC_SUCCESS;
+}
+
+/**
+ * Sets the current directory.
+ *
+ * @param path relative or absolute path. If absolute it must be part of the
+ * base path
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::setDirectory(const QString& path)
+{
+ return EC_SUCCESS;
+}
+
+/**
+ * Sets the properties of a file in the current directory.
+ *
+ * @param source the properties to copy
+ * @param target the properties of the file to change
+ * @param force <code>true</code>: try to change rights to enable
+ * other changes<br>
+ * <code>false</code>: current rights will be respected
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::setProperties(const ReFileMetaData& source,
+ ReFileMetaData& target, bool force)
+{
+ return EC_SUCCESS;
+}
+
+/**
+ * Writes a buffer to a file.
+ *
+ * @param node the file to write (without path, inside the current directory)
+ * @param offset first position to write
+ * @param buffer content to write
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::write(const QString& target,
+ int64_t offset, const QByteArray& buffer) {
+ return EC_SUCCESS;
+}
+
+/**
+ * Constructor
+ *
+ * @param parent the parent filesystem
+ * @param logger the logger
+ */
+ReCryptDirectory::ReCryptDirectory(ReRandomizer& contentRandom,
+ ReCryptFileSystem* parent, ReLogger* logger) :
+ ReByteScrambler(contentRandom, logger),
+ m_list(),
+ m_parent(parent),
+ m_changed(false),
+ m_logger(logger),
+ m_currentNode(),
+ m_fileBuffer(),
+ m_entryBuffer(),
+ m_blockSize(1024 * 1024)
+{
+ m_fileBuffer.reserve(m_blockSize);
+ m_entryBuffer.reserve(m_blockSize + MAX_ENTRY_SIZE + 10);
+}
+
+/**
+ * Destructor.
+ */
+ReCryptDirectory::~ReCryptDirectory()
+{
+ if (m_changed)
+ writeMetaFile();
+}
+
+/**
+ * Adds an file entry to the directory.
+ *
+ * @param entry the meta data of the file to add
+ * @return <code>true</code>: success
+ */
+bool ReCryptDirectory::addEntry(ReFileMetaData& entry)
+{
+ bool rc = true;
+ if (find(entry.m_node)){
+ rc = ! m_logger->logv(LOG_ERROR, LOC_ADD_ENTRY_1, "file exists yet: %s",
+ entry.m_node.constData());
+ } else {
+ m_list.append(entry);
+ m_changed = true;
+ }
+ return rc;
+}
+
+/**
+ * Makes a node name from an id.
+ *
+ * @param id a unique number of the file
+ * @return a unique node name derived from the id
+ */
+QString ReCryptDirectory::buildHostedNode(int id) const{
+ QByteArray rc;
+ static const int BASE = 'Z' - 'A' + 1;
+ while(id > 0){
+ rc.insert(0, 'a' + id % BASE);
+ id /= BASE;
+ }
+ return QString(rc);
+}
+
+/**
+ * Makes an id from an node name in the hosted filesystem.
+ *
+ * @param hostedNode the node to convert
+ * @return -1: invalid node name<br>
+ * otherwise: the id of the node
+ */
+int ReCryptDirectory::buildId(const QString& hostedNode) const{
+ int id = 0;
+ static const int BASE = 'Z' - 'A' + 1;
+ for (int ix = 0; id >= 0 && ix < hostedNode.length(); ix++){
+ int digit = hostedNode.at(ix).unicode() - QChar('a').unicode();
+ if (digit < 0 || digit >= BASE)
+ id = -1;
+ else
+ id = id*BASE + digit;
+ }
+ return id;
+}
+
+/**
+ * Search an file entry by name.
+ *
+ * @param node the filename without path
+ * @return NULL: not found<br>
+ * otherwise: the found file
+ *
+ */
+const ReFileMetaData* ReCryptDirectory::find(const QString& node) const
+{
+ const ReFileMetaData* rc = NULL;
+ ReFileMetaDataList::const_iterator it;
+ for (it = m_list.cbegin(); it != m_list.cend(); ++it){
+ if (it->m_node == node){
+ rc = &*it;
+ }
+ }
+ return rc;
+}
+
+/**
+ * Removes an entry given by the name.
+ *
+ * @param node the filename without path
+ * @return
+ */
+bool ReCryptDirectory::removeEntry(const QString& node)
+{
+ bool rc = true;
+ const ReFileMetaData* entry = find(node);
+ if (entry == NULL)
+ rc = ! m_logger->logv(LOG_ERROR, LOC_REMOVE_ENTRY_1, "cannot remove file %s: not found",
+ node.toUtf8().constData());
+ else {
+ ReFileMetaData& entry2 = *(ReFileMetaData*) entry;
+ //@ToDo:
+ //m_list.removeOne(entry2);
+ assert(false);
+ ReFileSystem& host = m_parent->host();
+ ReFileMetaData hostedFile;
+ QString hostedNode = buildHostedNode(entry->m_id);
+ if (host.first(hostedNode, hostedFile))
+ host.remove(hostedFile);
+ m_changed = true;
+ }
+ return rc;
+}
+
+/**
+ * Reads the file containing the metadata of the files.
+ *
+ * @return <code>true</code>: success
+ */
+bool ReCryptDirectory::readMetaFile()
+{
+ bool rc = true;
+ m_list.clear();
+ QString fnMetaFile = m_parent->directory() + ReCryptFileSystem::NODE_META_DIR;
+ FILE* fp = fopen(fnMetaFile.toUtf8().constData(), "rb");
+ if (fp != NULL){
+ QByteArray header;
+ header.resize(META_DIR_HEADER_LENGTH);
+ int nRead = fread(header.data(), 1, META_DIR_HEADER_LENGTH, fp);
+ if (nRead != META_DIR_HEADER_LENGTH){
+ rc = ! m_logger->logv(LOG_ERROR, LOC_READ_META_FILE_1,
+ "header of %s too small: %d/%d",
+ fnMetaFile.toUtf8().constData(), nRead, META_DIR_HEADER_LENGTH);
+ } else {
+ QByteArray info;
+ rc = initFromHeader(META_INFO_LENGTH, MARKER_LENGTH, &header, info);
+ if (rc){
+ const MetaInfo_t* meta = reinterpret_cast<const MetaInfo_t*>(info.constData());
+ if (meta->m_countFiles > 0){
+ m_fileBuffer.resize(m_blockSize);
+ m_entryBuffer.resize(0);
+ int sumLength = 0;
+ while ( (nRead = fread(m_fileBuffer.data(),
+ 1, m_blockSize, fp)) > 0){
+ sumLength += nRead;
+ if (nRead < m_blockSize)
+ m_fileBuffer.resize(nRead);
+ decodeContent(m_fileBuffer, m_fileBuffer);
+ m_entryBuffer.append(m_fileBuffer);
+ splitBlock(sumLength < meta->m_size,
+ m_entryBuffer);
+ }
+ if (sumLength != meta->m_size){
+ m_logger->logv(LOG_ERROR, LOC_READ_META_FILE_2,
+ "file %s too small: %d/%d",
+ fnMetaFile.toUtf8().constData(),
+ sumLength, meta->m_size);
+ }
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/**
+ * Writes the metadata of the directory into a file.
+ *
+ * @return <code>true</code>: success
+ */
+bool ReCryptDirectory::writeMetaFile()
+{
+ bool rc = true;
+ QByteArray header;
+ QByteArray meta;
+ meta.resize(sizeof(MetaInfo_t));
+ MetaInfo_t* meta2 = reinterpret_cast<MetaInfo_t*>(meta.data());
+ meta2->m_countFiles = m_list.length();
+ meta2->m_size = meta2->m_countFiles * sizeof(FileEntry_t);
+ ReFileMetaDataList::const_iterator it;
+ for (it = m_list.cbegin(); it != m_list.cend(); ++it){
+ int length = it->m_node.toUtf8().length();
+ meta2->m_size += length + (length < 256 ? 0 : 1);
+ }
+ initHeader(META_INFO_LENGTH, MARKER_LENGTH, meta);
+ QByteArray node;
+ for (it = m_list.cbegin(); it != m_list.cend(); ++it){
+ node = it->m_node.toUtf8();
+ int length = node.length();
+ meta2->m_size += length + (length < 256 ? 0 : 1);
+ }
+ QString fnMetaFile = m_parent->directory() + ReCryptFileSystem::NODE_META_DIR;
+ FILE* fp = fopen(fnMetaFile.toUtf8().constData(), "rb");
+ if (fp == NULL){
+ m_logger->logv(LOG_ERROR, LOC_WRITE_META_1, "cannot write (%d): %s",
+ errno, fnMetaFile);
+ } else {
+ m_fileBuffer.append(header);
+ int ixList = 0;
+ while (ixList++ < m_list.length()){
+ const ReFileMetaData& file = m_list.at(ixList++);
+ FileEntry_t trg;
+ trg.m_created = file.m_created.toMSecsSinceEpoch();
+ trg.m_modified = file.m_modified.toMSecsSinceEpoch();
+ trg.m_owner = file.m_owner;
+ trg.m_group = file.m_group;
+ trg.m_size = file.m_size;
+ trg.m_mode = file.m_mode;
+ trg.m_id = file.m_id;
+ node = file.m_node.toUtf8();
+ int length = node.length();
+ trg.m_nodeLength = length < 256 ? length : 0;
+ m_fileBuffer.append(reinterpret_cast<const char*>(&trg), sizeof trg);
+ m_fileBuffer.append(node);
+ if (length >= 256)
+ m_fileBuffer.append('\0');
+ if (m_fileBuffer.length() >= m_blockSize || ixList >= m_list.length()){
+ m_entryBuffer.resize(0);
+ if (m_fileBuffer.length() > m_blockSize){
+ m_entryBuffer = m_fileBuffer.mid(m_blockSize);
+ m_fileBuffer.resize(m_blockSize);
+ }
+ encodeContent(m_fileBuffer, m_fileBuffer);
+ int nWritten = fwrite(m_fileBuffer.constData(), 1,
+ m_fileBuffer.length(), fp);
+ if (nWritten != m_fileBuffer.length()){
+ rc = ! m_logger->logv(LOG_ERROR, LOC_WRITE_META_2,
+ "write error (%d): %s [%d/%d]", errno,
+ nWritten, m_fileBuffer.length());
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/**
+ * Splits a block with many metadata entries into single entries.
+ *
+ * @param isLast <code>true</code>the given block is the last in the file
+ * @param block the data to split.<br>
+ * Format: FileEntry_t_1 node1 File_entry2 node2 ...<br>
+ * Precondition: the block starts with a FileEntry_t<br>
+ * Postcondition: the block is empty or starts with the
+ * first FileEntry_t which is not processed. All processed
+ * entries are deleted from the buffer. block.length() < MAX_ENTRY_SIZE
+ */
+void ReCryptDirectory::splitBlock(bool isLast, QByteArray& block){
+ const FileEntry_t* src = reinterpret_cast<const FileEntry_t*>
+ (block.constData());
+ ReFileMetaData file;
+ int position = 0;
+ const char* srcPtr = reinterpret_cast<const char*>(block.constData());
+ const char* endPtr = srcPtr + block.length() - (isLast ? 0 : MAX_ENTRY_SIZE);
+ while (srcPtr < endPtr){
+ const FileEntry_t* src = reinterpret_cast<const FileEntry_t*>(srcPtr);
+ file.m_created.setMSecsSinceEpoch(src->m_created);
+ file.m_modified.setMSecsSinceEpoch(src->m_modified);
+ file.m_owner = src->m_owner;
+ file.m_group = src->m_group;
+ file.m_size = src->m_size;
+ file.m_mode = src->m_mode;
+ file.m_id = src->m_id;
+ srcPtr += sizeof(FileEntry_t);
+ int nodeLength = src->m_nodeLength != 0 ? src->m_nodeLength : strlen(srcPtr);
+ QByteArray node(srcPtr, nodeLength);
+ file.m_node = node;
+ m_list.append(file);
+ srcPtr += nodeLength + (src->m_nodeLength != 0 ? 0 : 1);
+ }
+ block.remove(0, srcPtr - block.constData());
+ printf("List: %d Rest: %d\n", m_list.length(), block.length());
+}
+/**
+ * Gets the filename of an entry in the hosted filesystem.
+ *
+ * @param entry the name was built for this file
+ * @return the full name of the hosted (encrypted) file
+ */
+const QString& ReCryptDirectory::hostedFilename(const ReFileMetaData& entry)
+{
+ QString node = buildHostedNode(entry.m_id);
+ m_currentNode = ReFileUtils::pathAppend(m_parent->directory(), node);
+ return m_currentNode;
+}
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#ifndef RECRYPTFILESYSTEM_HPP
+#define RECRYPTFILESYSTEM_HPP
+
+class ReCryptFileSystem;
+
+class ReCryptDirectory : protected ReByteScrambler{
+public:
+ typedef struct {
+ int64_t m_size;
+ //@ millisec from epoch
+ int64_t m_modified;
+ //@ millisec from epoch
+ int64_t m_created;
+ int32_t m_id;
+ int16_t m_owner;
+ int16_t m_group;
+ mode_t m_mode;
+ // 0: strlen(node) > 255
+ uint8_t m_nodeLength;
+ } FileEntry_t;
+ typedef struct {
+ int32_t m_countFiles;
+ int32_t m_size;
+ } MetaInfo_t;
+public:
+ ReCryptDirectory(ReRandomizer& contentRandom, ReCryptFileSystem* parent,
+ ReLogger* logger);
+ ~ReCryptDirectory();
+public:
+ bool addEntry(ReFileMetaData& entry);
+ const ReFileMetaData* find(const QString& node) const;
+ bool removeEntry(const QString& entry);
+ bool readMetaFile();
+ bool writeMetaFile();
+protected:
+ int buildId(const QString& hostedNode) const;
+ QString buildHostedNode(int id) const;
+ const QString& hostedFilename(const ReFileMetaData& entry);
+ void splitBlock(bool isLast, QByteArray& block);
+public:
+ static const int MARKER_LENGTH;
+ static const int META_INFO_LENGTH;
+ static const int META_DIR_HEADER_LENGTH;
+ static const int MAX_ENTRY_SIZE;
+protected:
+ ReFileMetaDataList m_list;
+ ReCryptFileSystem* m_parent;
+ bool m_changed;
+ ReLogger* m_logger;
+ QString m_currentNode;
+ QByteArray m_fileBuffer;
+ QByteArray m_entryBuffer;
+ int m_blockSize;
+};
+
+/**
+ * A filesystem with encrypted filenames and file content.
+ *
+ * The storage is done with a 'host filesystem'.
+ * The filenames used in the interface (parameters) are clear text.
+ * The filenames of the base filesystem are encrypted.
+ * If a file content is copied / moved to the base filesystem the content
+ * will be encrypted. In the other direction the file content will be decrypted.
+ */
+class ReCryptFileSystem: public ReFileSystem,
+ protected ReCryptDirectory
+{
+public:
+ static const int NODE_LENGHT;
+ static const int HEADER_LENGTH;
+ static const int CHECKSUM_LENGHT;
+ static const int MARKER_LENGHT;
+ static const QString NODE_META_DIR;
+ static const QString NODE_META_DEVICE;
+public:
+ ReCryptFileSystem(ReFileSystem& hostFileSystem,
+ ReRandomizer& contentRandom, ReLogger* logger);
+ ~ReCryptFileSystem();
+public:
+ virtual void close();
+ virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
+ ReFileMetaDataList& list);
+ virtual ErrorCode makeDir(const QString& node);
+ virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
+ int size, QByteArray& buffer);
+ virtual ErrorCode remove(const ReFileMetaData& node);
+ virtual ErrorCode setDirectory(const QString& path);
+ virtual ErrorCode setProperties(const ReFileMetaData& source, ReFileMetaData& target, bool force);
+ virtual ErrorCode write(const QString& target, int64_t offset,
+ const QByteArray& buffer);
+public:
+ /** Returns the filesystem hosting the encrypted files.
+ * @return the hosting filesystem
+ */
+ ReFileSystem& host() const {
+ return m_host;
+ }
+
+protected:
+ ReFileSystem& m_host;
+};
+
+#endif // RECRYPTFILESYSTEM_HPP
LOC_SET_PROPERTIES_5, // 12017
};
-const int ReCryptFileSystem::NODE_LENGHT = 44;
-const int ReCryptFileSystem::MARKER_LENGHT = 4;
-const int ReCryptFileSystem::CHECKSUM_LENGHT = 16;
-const int ReCryptFileSystem::HEADER_LENGTH = sizeof(int64_t)
- + ReCryptFileSystem::NODE_LENGHT
- + ReCryptFileSystem::MARKER_LENGHT;
-
-#ifdef WITH_TRACE
-static bool s_trace = true;
-#endif
-
/**
* Constructor.
*
* EC_NOT_ACCESSIBLE parent not readable
*/
ReFileSystem::ErrorCode ReLocalFileSystem::setDirectory(const QString& path) {
- ErrorCode rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND;
+ ErrorCode rc;
+ if (ReFileUtils::isAbsolutPath(path))
+ rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND;
+ else
+ rc = m_dir.setCurrent(ReFileUtils::pathAppend(
+ m_dir.absolutePath(), path))
+ ? EC_SUCCESS : EC_PATH_NOT_FOUND;
m_directory = m_dir.absolutePath();
ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR);
return rc;
* @param size the filesize (0 for directories)
*/
ReFileMetaData::ReFileMetaData(const QString& node, const QDateTime& modified,
- const QDateTime& created, int owner, int group, mode_t mode, int64_t size) :
+ const QDateTime& created, int owner, int group, mode_t mode, int64_t size,
+ int32_t id) :
m_node(node),
m_modified(modified),
m_created(created),
+ m_size(size),
m_owner(owner),
m_group(group),
- m_mode(mode),
- m_size(size) {
+ m_id(id),
+ m_mode(mode)
+{
}
m_node(source.m_node),
m_modified(source.m_modified),
m_created(source.m_created),
+ m_size(source.m_size),
m_owner(source.m_owner),
m_group(source.m_group),
- m_mode(source.m_mode),
- m_size(source.m_size) {
+ m_id(source.m_id),
+ m_mode(source.m_mode)
+{
}
m_group = source.m_group;
m_mode = source.m_mode;
m_size = source.m_size;
+ m_id = source.m_id;
return *this;
}
-/**
- * Constructor.
- *
- * @param hostFileSystem the filesystem which does the storage (with
- * encrypted names and content
- * @param nameRandom a pseudo random generator for names
- * @param contentRandom a pseudo random generator for content
- */
-ReCryptFileSystem::ReCryptFileSystem(ReFileSystem& hostFileSystem,
- ReRandomizer& nameRandom, ReRandomizer& contentRandom, ReLogger* logger) :
- ReFileSystem("cryptfs", logger),
- ReByteScrambler(contentRandom, NODE_LENGHT, sizeof(int32_t), logger),
- m_host(hostFileSystem) {
-}
-
-/**
- * Destructor.
- */
-ReCryptFileSystem::~ReCryptFileSystem() {
-}
-
-/** Frees resources like open files.
- */
-void ReCryptFileSystem::close()
-{
-}
-
-/**
- * Fills a list with the items of the current directory.
- *
- * @param matcher the matching processor
- * @return the count of the found entries (<code>list.size()</code>)
- */
-int ReCryptFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list) {
- return 0;
-}
-
-/**
- * Creates a directory.
- *
- * @param node the name without path (in the current directory)
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::makeDir(const QString& node) {
- return EC_SUCCESS;
-}
-
-/**
- * Reads a part of a file into a buffer.
- *
- * @param source the file to read (inside the current directory)
- * @param offset first position to read
- * @param size number of bytes to read
- * @param buffer OUT: content of the file
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::read(const ReFileMetaData& source,
- int64_t offset, int size, QByteArray& buffer) {
- return EC_SUCCESS;
-}
-
-/** Removes a file or directory.
- * @param node the properties ot the node (in the current directory)
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::remove(const ReFileMetaData& node)
-{
- return EC_SUCCESS;
-}
-
-/**
- * Sets the current directory.
- *
- * @param path relative or absolute path. If absolute it must be part of the
- * base path
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::setDirectory(const QString& path)
-{
- return EC_SUCCESS;
-}
-
-/**
- * Sets the properties of a file in the current directory.
- *
- * @param source the properties to copy
- * @param target the properties of the file to change
- * @param force <code>true</code>: try to change rights to enable
- * other changes<br>
- * <code>false</code>: current rights will be respected
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::setProperties(const ReFileMetaData& source,
- ReFileMetaData& target, bool force)
-{
- return EC_SUCCESS;
-}
-
-/**
- * Writes a buffer to a file.
- *
- * @param node the file to write (without path, inside the current directory)
- * @param offset first position to write
- * @param buffer content to write
- * @return EC_SUCCESS or error code
- */
-ReFileSystem::ErrorCode ReCryptFileSystem::write(const QString& target,
- int64_t offset, const QByteArray& buffer) {
- return EC_SUCCESS;
-}
-
ReFileMetaData();
ReFileMetaData(const QString& node, const QDateTime& modified,
const QDateTime& created, int owner = -1, int group = -1,
- mode_t mode = (mode_t) - 1, int64_t size = 0);
+ mode_t mode = (mode_t) - 1, int64_t size = 0, int32_t id = 0);
virtual ~ReFileMetaData();
ReFileMetaData(const ReFileMetaData& source);
ReFileMetaData& operator =(const ReFileMetaData& source);
QString m_node;
QDateTime m_modified;
QDateTime m_created;
+ int64_t m_size;
int16_t m_owner;
int16_t m_group;
+ // unique inside the directory:
+ int32_t m_id;
mode_t m_mode;
- int64_t m_size;
};
typedef QList<ReFileMetaData> ReFileMetaDataList;
FILE* m_writeFile;
};
-/**
- * A filesystem with encrypted filenames and file content.
- *
- * The storage is done with a 'host filesystem'.
- * The filenames used in the interface (parameters) are clear text.
- * The filenames of the base filesystem are encrypted.
- * If a file content is copied / moved to the base filesystem the content
- * will be encrypted. In the other direction the file content will be decrypted.
- */
-class ReCryptFileSystem: public ReFileSystem, protected ReByteScrambler {
-public:
- static const int NODE_LENGHT;
- static const int HEADER_LENGTH;
- static const int CHECKSUM_LENGHT;
- static const int MARKER_LENGHT;
-public:
- ReCryptFileSystem(ReFileSystem& hostFileSystem, ReRandomizer& nameRandom,
- ReRandomizer& contentRandom, ReLogger* logger);
- ~ReCryptFileSystem();
-public:
-public:
- virtual void close();
- virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list);
- virtual ErrorCode makeDir(const QString& node);
- virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
- int size, QByteArray& buffer);
- virtual ErrorCode remove(const ReFileMetaData& node);
- virtual ErrorCode setDirectory(const QString& path);
- virtual ErrorCode setProperties(const ReFileMetaData& source, ReFileMetaData& target, bool force);
- virtual ErrorCode write(const QString& target, int64_t offset,
- const QByteArray& buffer);
-protected:
- ReFileSystem& m_host;
-};
#endif /* OS_REFILESYSTEM_HPP_ */
#endif
}
#include "os/ReFileSystem.hpp"
+#include "os/ReCryptFileSystem.hpp"
#endif /* OS_REOS_HPP_ */
LOC_STATESTORAGE, // 120
LOC_FILESYSTEM,
LOC_RANDOMIZER,
+ LOC_CRYPTFILESYSTEM,
};
#define LOC_FIRST_OF(moduleNo) (moduleNo*100+1)
class RplModules {