Compare commits

..

No commits in common. "master" and "Wywołanie_i/o" have entirely different histories.

14 changed files with 420 additions and 157 deletions

137
ChunkManager.cpp Normal file
View file

@ -0,0 +1,137 @@
/*
* This file is part of VoidArchiveTool.
*
* Copyright (C) 2025 Yanczi
*
* Void Archive Toolis free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ChunkManager.h"
ChunkManager::ChunkManager(EncryptionManager& em)
:eman(em)
{ }
ChunkManager::~ChunkManager()
{ }
//-----------------------------------------------------------------------------
// Kompresja blokowa
//
// Dzielenie vectora na chunki dok³adnie po 128KB
// Kompresowanie chunków bez nag³ówka
//-----------------------------------------------------------------------------
std::vector<char> ChunkManager::chunked(const std::vector<char>& raw, const bool& compress, const bool& encrypt)
{
//std::vector<BlockSize> blockSizes;
// Maksymalny rozmiar chunka
const size_t maxBlockSize = BLOCK_SIZE;
const size_t rawSize = raw.size();
uint32_t blockLen = 0;
uint32_t lastChunkRawSize;
std::vector<char> compressedBlocks;
for (size_t offset = 0; offset < rawSize; offset += maxBlockSize)
{
// Rozmiar chunka
const size_t chunkSize = std::min(maxBlockSize, rawSize - offset);
auto begin = raw.begin() + offset;
auto end = begin + chunkSize;
// Skopiuj fragment danych do chunka
std::vector<char> chunk(begin, end);
std::vector<char> outChunk;
// Przetwórz chunki i przetwórz
if (compress)
{
// Zaszyfruj i skompresuj lub tylko skompresuj
outChunk = encrypt ? eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
}
else
{
// Zaszyfruj lub skopiuj
outChunk = encrypt ? eman.encrypt(chunk) : std::move(chunk);
}
uint32_t chs = static_cast<uint32_t>(chunk.size());
uint32_t zch = static_cast<uint32_t>(outChunk.size());
//addIntToVector<uint32_t>(compressedBlocks, chs);
lastChunkRawSize = chs;
addIntToVector<uint32_t>(compressedBlocks, zch);
compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end());
blockLen++;
}
std::vector<char> zip;
// Wstaw liczbê o iloœci bloków do vectora;
// Przekonpwertuj usigned int32 na ci¹g znkaów
// uint16_t blockLen = blockSizes .size();
addIntToVector<uint32_t>(zip, blockLen);
addIntToVector<uint32_t>(zip, maxBlockSize);
addIntToVector<uint32_t>(zip, lastChunkRawSize);
// Dodaj skompresowane dane
zip.insert(zip.end(), compressedBlocks.begin(), compressedBlocks.end());
return zip;
}
//////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Dekompresja blokowa
//-----------------------------------------------------------------------------
std::vector<char> ChunkManager::dechunked(const std::vector<char>& zip, const bool& compress, const bool& encrypt)
{
size_t offset = 0;
const uint32_t chunkLen = getIntFromVector<uint32_t>(zip, offset);
const uint32_t chunkBeforeSize = getIntFromVector<uint32_t>(zip, offset);
const uint32_t chunkLastSize = getIntFromVector<uint32_t>(zip, offset);
std::cout << "Q: " << chunkLen << std::endl;
std::cout << "C: " << chunkBeforeSize << std::endl;
std::cout << "L: " << chunkBeforeSize << std::endl;
std::vector<char> chunksString;
// Dekompresja bloków
for (size_t i = 0; i < chunkLen; ++i)
{
// Pobierz rozmiar chunków przed i po skompresowaniem
uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize;
uint32_t chunkZipSize = getIntFromVector<uint32_t>(zip, offset);
// Pobierz blok chunka
std::vector<char> inChunk(chunkZipSize);
std::memcpy(inChunk.data(), zip.data() + offset, chunkZipSize);
offset += chunkZipSize;
// Jeœli flaga encrypt jest aktywna najpierw zdeszyfruj blok
std::vector<char> zipChunk = encrypt ? eman.decrypt(inChunk) : std::move(inChunk);
// Zdeklarój pusty chunk
std::vector<char> chunk = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk);
// Scal chunki
chunksString.insert(chunksString.end(), chunk.begin(), chunk.end());
}
return chunksString;
}

70
ChunkManager.h Normal file
View file

@ -0,0 +1,70 @@
/*
* This file is part of VoidArchiveTool.
*
* Copyright (C) 2025 Yanczi
*
* Void Archive Toolis free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <algorithm>
#include <iostream>
#include "EncryptionManager.h"
#include "CompressionManager.h"
#define BLOCK_SIZE 131072 // 128KB
class ChunkManager
{
public:
ChunkManager(EncryptionManager& em);
~ChunkManager();
// Podzia³ na chunki
std::vector<char> chunked(const std::vector<char>&, const bool&, const bool&);
// Zcalanie chunków
std::vector<char> dechunked(const std::vector<char>&, const bool&, const bool&);
private:
EncryptionManager eman;
CompressionManager cman;
// Przekonwertuj zmienn¹ na ci¹g na vector
template <typename T>
void addIntToVector(std::vector<char>& vec, const T& val)
{
size_t tmpSize = vec.size();
vec.resize(tmpSize + sizeof(val));
std::memcpy(vec.data() + tmpSize, &val, sizeof(val));
}
// Pobierz zmienn¹ z vectora
template <typename T>
T getIntFromVector(const std::vector<char>& vec, size_t& offset)
{
T tmp{};
std::memcpy(&tmp, vec.data() + offset, sizeof(tmp));
offset += sizeof(tmp);
return tmp;
}
};

View file

@ -23,6 +23,9 @@ CompressionManager::CompressionManager()
:cctx(ZSTD_createCCtx()) :cctx(ZSTD_createCCtx())
,dctx(ZSTD_createDCtx()) ,dctx(ZSTD_createDCtx())
{ {
// Tu ustawienia pod kompresjê
const int level = COMPRESSION_LEVEL;
// Ustawienia frameless // Ustawienia frameless
size_t rc = 0; size_t rc = 0;
@ -39,7 +42,7 @@ CompressionManager::CompressionManager()
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0);
// Ustawia poziom kompresji // Ustawia poziom kompresji
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd::compression_level); rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level);
if (ZSTD_isError(rc)) { if (ZSTD_isError(rc)) {
std::cerr << "ZSTD_CCtx_setParameter error" << std::endl; std::cerr << "ZSTD_CCtx_setParameter error" << std::endl;

View file

@ -30,10 +30,7 @@
#error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless" #error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless"
#endif #endif
namespace zstd #define COMPRESSION_LEVEL 3
{
inline constexpr short compression_level = 3;
}
class CompressionManager class CompressionManager
{ {

View file

@ -20,8 +20,9 @@
#include "CreateCargo.h" #include "CreateCargo.h"
CreateCargo::CreateCargo() CreateCargo::CreateCargo()
: signature(fl::sigpak) : signature(SIGNATURE)
, extension(fl::extpak) , extension(EXTENSION)
, version(VERSION)
, methodFlags(0) , methodFlags(0)
, xxhState(XXH64_createState()) , xxhState(XXH64_createState())
, offset(0) , offset(0)
@ -89,7 +90,7 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag)
} }
// Zapisywanie klucza szyfrującego // Zapisywanie klucza szyfrującego
if (flag == flag::enc || flag == flag::ezd || encList.size() > 0) if (flag == FILE_FLAG_ENCRYPT || flag == FILE_FLAG_ZIPENC || encList.size() > 0)
{ {
eman.saveKey(catalogPath, hppKey); eman.saveKey(catalogPath, hppKey);
} }
@ -132,11 +133,11 @@ bool CreateCargo::GetFileList(const std::string& path)
{ {
if (FindOnTheList(zipList, fileRef) || CheckFileExtension(fileRef, zipList)) if (FindOnTheList(zipList, fileRef) || CheckFileExtension(fileRef, zipList))
{ {
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::ezd : flag::zip; pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ZIPENC : FILE_FLAG_COMPRESS;
} }
else else
{ {
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::enc : flag::raw; pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ENCRYPT : FILE_FLAG_RAW;
} }
pc.path = PathToUnixLike(tmpPath); pc.path = PathToUnixLike(tmpPath);
std::cout << pc.path << " - " << pc.parameter << std::endl; std::cout << pc.path << " - " << pc.parameter << std::endl;
@ -184,13 +185,42 @@ CargoHead CreateCargo::CreateCargoHead(const uint32_t& filesLen, const uint64_t&
{ {
CargoHead ch; CargoHead ch;
ch.signature = fl::sigpak; ch.signature = signature;
ch.table = table; ch.table = table;
ch.files = filesLen; ch.files = filesLen;
return ch; return ch;
} }
//-----------------------------------------------------------------------------
// Sprawdza czy plik znajduje siê na liœcie
//-----------------------------------------------------------------------------
void CreateCargo::computingBytes(const uint8_t& flag, std::vector<char>& input, std::vector<char>& output)
{
//Flaga aktywna sprawdza czy plik jest na liœcie. Jeœli jest to zwraca surowedane
//Przeciwnie kompresuje dane
ChunkManager cm(eman);
switch (flag)
{
case FILE_FLAG_COMPRESS:
output = cm.chunked(input, true, false);
break;
case FILE_FLAG_ENCRYPT:
output = cm.chunked(input, false, true);
break;
case FILE_FLAG_ZIPENC:
output = cm.chunked(input, true, true);
break;
default:
output = std::move(input);
break;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Przygotowanie nagłówków i plików // Przygotowanie nagłówków i plików
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -219,27 +249,28 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
size_t size = f.tellg(); size_t size = f.tellg();
f.seekg(0, std::ios::beg); f.seekg(0, std::ios::beg);
if (size > ds::maxFileSize) if (size > MAX_FILE_SIZE)
{ {
std::cerr << path << " is too large. It exceeds " << ds::maxFileSize / 1024 / 1024 / 1024 << "GB!" << std::endl; std::cerr << path << " is too large. It exceeds " << MAX_FILE_SIZE / 1024 / 1024 / 1024 << "GB!" << std::endl;
} }
else else
{ {
XXH64_reset(xxhState, 0); XXH64_reset(xxhState, 0);
//Wczytanie pliku do pamięci //Wczytanie pliku do pamięci
std::vector<char> buffer(ds::chunk_stream); std::vector<char> buffer(CHUNK_STREAM_256MB);
uint64_t sizeFile = 0; uint64_t sizeFile = 0;
const uint32_t chunkBlockSize = ds::block_size; const uint32_t chunkBlockSize = CHUNK_BLOCK_SIZE;
const uint32_t quantity = (size + chunkBlockSize) / chunkBlockSize; const uint32_t quantity = (size + chunkBlockSize) / chunkBlockSize;
const uint32_t lastChunkSize = size - (chunkBlockSize * (quantity - 1)); const uint32_t lastChunkSize = size - (chunkBlockSize * (quantity - 1));
// Jeśli jest ustawiona flaga inna niż RAW // Jeśli jest ustawiona flaga inna niż RAW
// Dodaj do kontenera konfigurację chunków // Dodaj do kontenera konfigurację chunków
if (file.parameter != flag::raw) if (file.parameter != FILE_FLAG_RAW)
{ {
std::cout << "CHUNK PARAM" << std::endl;
cargo.write(reinterpret_cast<const char*>(&quantity), sizeof(quantity)); cargo.write(reinterpret_cast<const char*>(&quantity), sizeof(quantity));
cargo.write(reinterpret_cast<const char*>(&chunkBlockSize), sizeof(chunkBlockSize)); cargo.write(reinterpret_cast<const char*>(&chunkBlockSize), sizeof(chunkBlockSize));
cargo.write(reinterpret_cast<const char*>(&lastChunkSize), sizeof(lastChunkSize)); cargo.write(reinterpret_cast<const char*>(&lastChunkSize), sizeof(lastChunkSize));
@ -247,7 +278,7 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
} }
// Strumieniowanie danych // Strumieniowanie danych
while (f.read(buffer.data(), ds::chunk_stream) || f.gcount() > 0) while (f.read(buffer.data(), CHUNK_STREAM_256MB) || f.gcount() > 0)
{ {
const int bufferSize = f.gcount(); const int bufferSize = f.gcount();
buffer.resize(bufferSize); buffer.resize(bufferSize);
@ -255,7 +286,7 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
// Aktualizacja XXH64 // Aktualizacja XXH64
XXH64_update(xxhState, buffer.data(), buffer.size()); XXH64_update(xxhState, buffer.data(), buffer.size());
if (file.parameter == flag::raw) if (file.parameter == FILE_FLAG_RAW)
{ {
// Zapisywanie strumienia do kontenera // Zapisywanie strumienia do kontenera
cargo.write(reinterpret_cast<const char*>(buffer.data()), buffer.size()); cargo.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
@ -277,16 +308,17 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
std::vector<char> outChunk; std::vector<char> outChunk;
// Przetwórz chunki i przetwórz // Przetwórz chunki i przetwórz
if ((file.parameter & flag::zip) == flag::zip) if ((file.parameter & FILE_FLAG_COMPRESS) == FILE_FLAG_COMPRESS)
{ {
// Zaszyfruj i skompresuj lub tylko skompresuj // Zaszyfruj i skompresuj lub tylko skompresuj
outChunk = (file.parameter & flag::enc) == flag::enc ? outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ?
eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
} }
else else
{ {
// Zaszyfruj lub skopiuj // Zaszyfruj lub skopiuj
outChunk = eman.encrypt(chunk); outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ?
eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
} }
const uint32_t outSize = outChunk.size(); const uint32_t outSize = outChunk.size();
@ -297,11 +329,19 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
cargo.write(reinterpret_cast<const char*>(outChunk.data()), outChunk.size()); cargo.write(reinterpret_cast<const char*>(outChunk.data()), outChunk.size());
sizeFile += outSize; sizeFile += outSize;
} }
std::cout << "SIZE: " << sizeFile << std::endl;
} }
} }
f.close(); f.close();
//Tworzenie hashu CRC
//const uint64_t crc = XXH64(buffer.data(), buffer.size(), 0);
//Kompresjia
//std::vector<char> pakBuffer;
//computingBytes(file.parameter, buffer, pakBuffer);
FilesTable ft; FilesTable ft;
ft.nameFile = path; ft.nameFile = path;
ft.nameLen = path.length(); ft.nameLen = path.length();
@ -310,6 +350,8 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
ft.flag = file.parameter; ft.flag = file.parameter;
ft.crc = XXH64_digest(xxhState); ft.crc = XXH64_digest(xxhState);
//cargo.write(reinterpret_cast<const char*>(pakBuffer.data()), pakBuffer.size());
filesTable.push_back(ft); filesTable.push_back(ft);
offset += sizeFile; offset += sizeFile;
} }
@ -331,25 +373,24 @@ void CreateCargo::GetFilters(const std::string& filterFile)
file.close(); file.close();
// Lista plików do skompresowania // Lista plików do skompresowania
if (jslist.contains(key::zip)) if (jslist.contains(KEY_ZIP))
{ {
zipList = jslist[key::zip].get<std::vector<std::string>>(); zipList = jslist[KEY_ZIP].get<std::vector<std::string>>();
} }
// Lista plików do zaszyfrowania // Lista plików do zaszyfrowania
if (jslist.contains(key::enc)) if (jslist.contains(KEY_ENCRYPT))
{ {
encList = jslist[key::enc].get<std::vector<std::string>>(); encList = jslist[KEY_ENCRYPT].get<std::vector<std::string>>();
} }
// Lista plików do pominięcia // Lista plików do pominięcia
if (jslist.contains(key::ignore)) if (jslist.contains(KEY_IGNORE))
{ {
ignoreList = jslist[key::ignore].get<std::vector<std::string>>(); ignoreList = jslist[KEY_IGNORE].get<std::vector<std::string>>();
} }
// Flaga tworzenia klucza jako plik nag³ówka c++ hppKey = jslist.value("keyhpp", false);
hppKey = jslist.value(key::hpp, false);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -33,6 +33,7 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "DataStruct.h" #include "DataStruct.h"
#include "ChunkManager.h"
#include "EncryptionManager.h" #include "EncryptionManager.h"
#include "CompressionManager.h" #include "CompressionManager.h"
@ -44,17 +45,6 @@
#define ALL_FILE ".*" // Wszystkie pliki #define ALL_FILE ".*" // Wszystkie pliki
namespace key
{
inline constexpr std::string_view zip = "compress";
inline constexpr std::string_view raw = "raw";
inline constexpr std::string_view enc = "encrypt";
inline constexpr std::string_view ignore = "ignore";
inline constexpr std::string_view all = ".*";
inline constexpr std::string_view hpp = "keyhpp";
}
struct PathConf struct PathConf
{ {
std::string path; std::string path;
@ -72,6 +62,7 @@ public:
private: private:
const std::string signature; const std::string signature;
const std::string extension; const std::string extension;
const signed char version;
uint8_t methodFlags; uint8_t methodFlags;
@ -122,6 +113,9 @@ private:
// Wczytanie filtrów wyj¹tków // Wczytanie filtrów wyj¹tków
void GetFilters(const std::string&); void GetFilters(const std::string&);
// Sprawdza czy plik znajduje siê na liœcie
void computingBytes(const uint8_t&, std::vector<char>&, std::vector<char>&);
// Sprawdzanie rozsze¿eñ plików // Sprawdzanie rozsze¿eñ plików
bool CheckFileExtension(const std::string&, const std::vector<std::string>&); bool CheckFileExtension(const std::string&, const std::vector<std::string>&);

View file

@ -22,46 +22,39 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
namespace ui #define EXTENSION "pak"
{ #define SIGNATURE "XPAK"
inline constexpr std::string_view title = "exPak";
inline constexpr std::string_view ver = "0.5";
}
// Pliki #define SIGNATURE_KEY_FILE "XKEY"
namespace fl
{
inline constexpr std::string_view sigpak = "XPAK";
inline constexpr std::string_view sigkey = "XKEY";
inline constexpr std::string_view extpak = "pak"; #define VERSION 0x03
inline constexpr std::string_view extkey = "key";
}
// Size // WielkoϾ pojedynczego bloku strumienia
namespace ds #define CHUNK_STREAM_512KB 524288 // 512KB
{ #define CHUNK_STREAM_16MB 16777216 // 16MB
// Chunki streamowania #define CHUNK_STREAM_256MB 268435456 // 256MB
inline constexpr uint32_t chunk_stream = 268435456; // 256MB
// Blok chunków // Rozmiar pojedynczego bloku
inline constexpr uint32_t block_size = 131072; // 128KB #define CHUNK_BLOCK_SIZE 131072 // 128KB
// Maksymalny rozmiar pliku do spakowania #define FILE_FLAG_RAW 0x00
inline constexpr uint64_t maxFileSize = 8589934592; // 8GB #define FILE_FLAG_COMPRESS 0x0F
} #define FILE_FLAG_ENCRYPT 0xF0
#define FILE_FLAG_ZIPENC 0xFF
// Flagi #define FILE_FLAG_FILTERING 0xAB
namespace flag
{
inline constexpr uint8_t raw = 0x00; // Surowy plik
inline constexpr uint8_t zip = 0x0F; // Kompresja
inline constexpr uint8_t enc = 0xF0; // Szyfrowanie
inline constexpr uint8_t ezd = 0xFF; // Kompresja z szyfrowaniem
// Flaga do aktywacji filtra zdefiniowanego w json
inline constexpr uint8_t filter = 0xAB; //Prgoram title
} #define PROGRAM_TITLE "eXtendet PAK"
#define PROGRAM_VERSION "v0.5"
#define PROGRAM_AUTHOR "Yanczi"
#define PROGRAM_COMPILING "19 December 2025"
#define PROGRAM_LICENSE "GNU LGPL v3"
//Limity
#define MAX_FILE_SIZE 8589934592 // 8GB
#define MAX_PAK_SIZE 8796093022208 // 8TB
struct CargoHead struct CargoHead
{ {

View file

@ -67,6 +67,9 @@ void EncryptionManager::generateKeys()
void EncryptionManager::saveKey(const std::string& path, bool hpp) void EncryptionManager::saveKey(const std::string& path, bool hpp)
{ {
const std::string sig = SIGNATURE_KEY_FILE;
const int8_t ver = VERSION;
// Wygeneruj time stamp // Wygeneruj time stamp
std::time_t now = std::time(nullptr); std::time_t now = std::time(nullptr);
const int time = static_cast<int>(now); const int time = static_cast<int>(now);
@ -75,13 +78,14 @@ void EncryptionManager::saveKey(const std::string& path, bool hpp)
std::vector<char> keyVec(reinterpret_cast<const char*>(key.data()), std::vector<char> keyVec(reinterpret_cast<const char*>(key.data()),
reinterpret_cast<const char*>(key.data()) + key.size()); reinterpret_cast<const char*>(key.data()) + key.size());
const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), 0); const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION);
// Zapisz ten œmietnik do pliku KEY // Zapisz ten œmietnik do pliku KEY
std::ofstream file(path + ".key", std::ios::binary); std::ofstream file(path + ".key", std::ios::binary);
if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; } if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; }
file.write(fl::sigkey.data(), fl::sigkey.length()); file.write(sig.data(), sig.length());
file.write(reinterpret_cast<const char*>(&ver), sizeof(ver));
file.write(reinterpret_cast<const char*>(&time), sizeof(time)); file.write(reinterpret_cast<const char*>(&time), sizeof(time));
file.write(reinterpret_cast<const char*>(keyVec.data()), keyVec.size()); file.write(reinterpret_cast<const char*>(keyVec.data()), keyVec.size());
file.write(reinterpret_cast<const char*>(&crcKey), sizeof(crcKey)); file.write(reinterpret_cast<const char*>(&crcKey), sizeof(crcKey));
@ -98,7 +102,7 @@ void EncryptionManager::saveCppHeadFile(const std::string& path)
std::ofstream file(path + ".hpp"); std::ofstream file(path + ".hpp");
file << "// Plik wygenerowany przez " << ui::title << " " << ui::ver << std::endl; file << "// Plik wygenerowany przez " << PROGRAM_TITLE << " " << PROGRAM_VERSION << std::endl;
file << std::endl; file << std::endl;
file << std::endl; file << std::endl;
file << "#pragma once" << std::endl; file << "#pragma once" << std::endl;
@ -133,15 +137,18 @@ std::string EncryptionManager::toHex(const unsigned char* data, size_t len)
void EncryptionManager::loadKey(const std::string& path) void EncryptionManager::loadKey(const std::string& path)
{ {
std::ifstream file(path + ".key", std::ios::binary); std::ifstream file(path + ".key", std::ios::binary);
std::vector<char> sig(fl::sigkey.size());
const std::string signature = SIGNATURE_KEY_FILE;
std::vector<char> sig(signature.size());
int8_t ver; int8_t ver;
int time; int time;
// Wczytaj // Wczytaj
file.read(sig.data(), sig.size()); file.read(sig.data(), sig.size());
file.read(reinterpret_cast<char*>(&ver), sizeof(ver));
// SprawdŸ czy plik klucza jest poprawny // SprawdŸ czy plik klucza jest poprawny
if (std::string(sig.begin(), sig.end()) != fl::sigkey) if (std::string(sig.begin(), sig.end()) != signature || ver != VERSION)
{ {
throw std::runtime_error("Invalid key file!"); throw std::runtime_error("Invalid key file!");
} }
@ -154,7 +161,7 @@ void EncryptionManager::loadKey(const std::string& path)
file.read(reinterpret_cast<char*>(&crcKey), sizeof(crcKey)); file.read(reinterpret_cast<char*>(&crcKey), sizeof(crcKey));
// SprawdŸ integralnoœæ klucza // SprawdŸ integralnoœæ klucza
if (XXH64(keyVec.data(), keyVec.size(), 0) != crcKey) if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey)
{ {
throw std::runtime_error("Key integrity error!"); throw std::runtime_error("Key integrity error!");
} }

View file

@ -22,11 +22,11 @@
ExtractCargo::ExtractCargo() ExtractCargo::ExtractCargo()
:filesLen(0) :filesLen(0)
, tablePosition(0) , tablePosition(0)
, xxhState(XXH64_createState()) , version(VERSION)
, signature(fl::sigpak) , signature(SIGNATURE)
{ {
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
XXH64_reset(xxhState, 0);
} }
ExtractCargo::~ExtractCargo() ExtractCargo::~ExtractCargo()
@ -110,6 +110,51 @@ bool ExtractCargo::CheckCargoFile()
return true; return true;
} }
//-----------------------------------------------------------------------------
// Sprawdzanie sumy kontrolnej
//-----------------------------------------------------------------------------
bool ExtractCargo::HashValid(const std::vector<char>& data, const uint64_t& crc)
{
uint64_t actualCrc = XXH64(data.data(), data.size(), 0);
if (actualCrc != crc)
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Magiczna funkcja do dekompresji i deszyfracji danych
//-----------------------------------------------------------------------------
void ExtractCargo::computingBytes(const std::vector<char>& input, std::vector<char>& output, const uint8_t& flag)
{
ChunkManager cm(eman);
std::cout << static_cast<int>(flag) << std::endl;
switch (flag)
{
case FILE_FLAG_COMPRESS:
output = cm.dechunked(input, true, false);
break;
case FILE_FLAG_ENCRYPT:
output = cm.dechunked(input, false, true);
break;
case FILE_FLAG_ZIPENC:
output = cm.dechunked(input, true, true);
std::cout << "DENC" << std::endl;
break;
default:
output = input;
break;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Pobieranie nagłówków plików // Pobieranie nagłówków plików
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -130,6 +175,9 @@ void ExtractCargo::LoadFilesTable()
cargoFile.read(reinterpret_cast<char*>(&fhTmp.crc), sizeof(fhTmp.crc)); cargoFile.read(reinterpret_cast<char*>(&fhTmp.crc), sizeof(fhTmp.crc));
cargoFile.read(reinterpret_cast<char*>(&fhTmp.flag), sizeof(fhTmp.flag)); cargoFile.read(reinterpret_cast<char*>(&fhTmp.flag), sizeof(fhTmp.flag));
std::cout << tablePosition << std::endl;
std::cout << "Size: " << fhTmp.size << std::endl;
filesHeads.push_back(fhTmp); filesHeads.push_back(fhTmp);
} }
} }
@ -143,76 +191,25 @@ void ExtractCargo::ExtractingFilesFromCargo()
{ {
std::filesystem::path dir = cargoFileName.stem() / fh.nameFile; std::filesystem::path dir = cargoFileName.stem() / fh.nameFile;
CreateDirections(dir); CreateDirections(dir);
std::cout << dir.string() << std::endl;
std::ofstream file(dir, std::ios::binary); std::ofstream file(dir, std::ios::binary);
std::cout << fh.size << std::endl;
cargoFile.seekg(fh.offset); cargoFile.seekg(fh.offset);
std::vector<char> buffor(fh.size);
XXH64_reset(xxhState, 0); cargoFile.read(buffor.data(), fh.size);
// Strumieñ wyci¹gaj¹cy std::vector<char> rawBuffor;
if (fh.flag == flag::raw) computingBytes(buffor, rawBuffor, fh.flag);
if (!HashValid(rawBuffor, fh.crc))
{ {
for (uint64_t sc = 0; sc < fh.size; sc += ds::chunk_stream) std::cerr << fh.nameFile << " Error: Corrupted data integration CRC" << std::endl;
{
const uint32_t streamChunk = std::min(ds::chunk_stream, static_cast<uint32_t>(fh.size - sc));
std::vector<char> buffer(streamChunk);
cargoFile.read(buffer.data(), streamChunk);
XXH64_update(xxhState, buffer.data(), buffer.size());
file.write(reinterpret_cast<const char*>(buffer.data()), streamChunk);
}
} }
else
{
uint32_t chunkLen;
uint32_t chunkBeforeSize;
uint32_t chunkLastSize;
cargoFile.read(reinterpret_cast<char*>(&chunkLen), sizeof(chunkLen)); file.write(reinterpret_cast<const char*>(rawBuffor.data()), rawBuffor.size());
cargoFile.read(reinterpret_cast<char*>(&chunkBeforeSize), sizeof(chunkBeforeSize));
cargoFile.read(reinterpret_cast<char*>(&chunkLastSize), sizeof(chunkLastSize));
std::vector<char> chunksString;
// Dekompresja bloków
for (size_t i = 0; i < chunkLen; ++i)
{
// Pobierz rozmiar chunków przed i po skompresowaniem
uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize;
uint32_t chunkZipSize;
cargoFile.read(reinterpret_cast<char*>(&chunkZipSize), sizeof(chunkZipSize));
// Pobierz blok chunka
std::vector<char> buffer(chunkZipSize);
cargoFile.read(buffer.data(), chunkZipSize);
std::vector<char> rawBuffer(chunkSize);
if ((fh.flag & flag::zip) == flag::zip)
{
rawBuffer = (fh.flag & flag::enc) == flag::enc ?
cman.decompress(eman.decrypt(buffer), chunkSize) :
cman.decompress(buffer, chunkSize);
}
else
{
rawBuffer = eman.decrypt(buffer);
}
XXH64_update(xxhState, rawBuffer.data(), rawBuffer.size());
file.write(reinterpret_cast<const char*>(rawBuffer.data()), chunkSize);
}
}
file.close(); file.close();
if (XXH64_digest(xxhState) != fh.crc)
{
std::cerr << dir.string() << " Error: Corrupted data integration CRC" << std::endl;
}
} }
std::cout << "Unpacking complete!" << std::endl; std::cout << "Unpacking complete!" << std::endl;

View file

@ -28,12 +28,11 @@
#include <sstream> #include <sstream>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <utility>
#include <xxhash.h> #include <xxhash.h>
#include "DataStruct.h" #include "DataStruct.h"
#include "ChunkManager.h"
#include "EncryptionManager.h" #include "EncryptionManager.h"
#include "CompressionManager.h"
class ExtractCargo { class ExtractCargo {
public: public:
@ -48,8 +47,8 @@ private:
uint32_t filesLen; uint32_t filesLen;
uint64_t tablePosition; uint64_t tablePosition;
XXH64_state_t* xxhState;
const int8_t version;
const std::string signature; const std::string signature;
std::vector<FilesTable> filesHeads; std::vector<FilesTable> filesHeads;
@ -58,7 +57,7 @@ private:
std::ifstream cargoFile; std::ifstream cargoFile;
EncryptionManager eman; EncryptionManager eman;
CompressionManager cman;
// Sprawdzenie poprawnoœci archiwum // Sprawdzenie poprawnoœci archiwum
bool CheckCargoFile(); bool CheckCargoFile();
@ -69,7 +68,13 @@ private:
// Pobieranie nag³ówków plików // Pobieranie nag³ówków plików
void LoadFilesTable(); void LoadFilesTable();
// Sprawdzanie sumy kontrolnej
bool HashValid(const std::vector<char>&, const uint64_t&);
// Utwórz katalog // Utwórz katalog
void CreateDirections(std::filesystem::path); void CreateDirections(std::filesystem::path);
// Magiczna funkcja do dekompresji i deszyfracji danych
void computingBytes(const std::vector<char>&, std::vector<char>&, const uint8_t&);
}; };

View file

@ -59,7 +59,8 @@ bool ViewCargo::ViewFiles(const std::string& path)
uint64_t tabPos = 0; uint64_t tabPos = 0;
uint32_t tabSize = 0; uint32_t tabSize = 0;
std::vector<char> magic(fl::sigpak.length()); const std::string signature = SIGNATURE;
std::vector<char> magic(signature.length());
int8_t cargoVer = 0; int8_t cargoVer = 0;
std::ifstream cargo(path, std::ios::binary); std::ifstream cargo(path, std::ios::binary);
@ -81,7 +82,7 @@ bool ViewCargo::ViewFiles(const std::string& path)
cargo.read(reinterpret_cast<char*>(&tabSize), sizeof(tabSize)); cargo.read(reinterpret_cast<char*>(&tabSize), sizeof(tabSize));
//SprawdŸ czy kontener ma poprawn¹ sygnature //SprawdŸ czy kontener ma poprawn¹ sygnature
if (std::string(magic.begin(), magic.end()) != fl::sigpak) if (std::string(magic.begin(), magic.end()) != signature)
{ {
std::cerr << "Error: Corrupted Cargo" << std::endl; std::cerr << "Error: Corrupted Cargo" << std::endl;
cargo.close(); cargo.close();
@ -128,15 +129,15 @@ void ViewCargo::ShowFile(const std::string& file, const uint8_t& flag)
// Ustawianie checkboxów // Ustawianie checkboxów
switch (flag) switch (flag)
{ {
case flag::zip: case FILE_FLAG_COMPRESS:
compresedCheck = "[x]"; compresedCheck = "[x]";
break; break;
case flag::enc: case FILE_FLAG_ENCRYPT:
encryptedCheck = "[x]"; encryptedCheck = "[x]";
break; break;
case flag::ezd: case FILE_FLAG_ZIPENC:
compresedCheck = "[x]"; compresedCheck = "[x]";
encryptedCheck = "[x]"; encryptedCheck = "[x]";
break; break;

View file

@ -80,16 +80,26 @@ static bool EmptyPath(std::string path)
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
std::cout << ui::title << std::endl << "ver. " << ui::ver << std::endl; std::string path = "";
std::cout << "Author: Yanczi" << std::endl;
std::cout << "License: GNU LGPL v3" << "\n" << std::endl; std::cout <<
" 8888888b. d8888 888 d8P \n"
" 888 Y88b d88888 888 d8P \n"
" 888 888 d88P888 888 d8P \n"
" .d88b. 888 888 888 d88P d88P 888 888d88K \n"
"d8P Y8b `Y8bd8P' 8888888P\" d88P 888 8888888b \n"
"88888888 X88K 888 d88P 888 888 Y88b \n"
"Y8b. .d8\"\"8b. 888 d8888888888 888 Y88b \n"
" \"Y8888 888 888 888 d88P 888 888 Y88b\n"
<< std::endl;
std::cout << "\n" << PROGRAM_VERSION << " Release " << PROGRAM_COMPILING << std::endl;
std::cout << "Author: " << PROGRAM_AUTHOR << std::endl;
std::cout << "License: " << PROGRAM_LICENSE << "\n" << std::endl;
CreateCargo cargo; CreateCargo cargo;
ExtractCargo extract; ExtractCargo extract;
ViewCargo viewCargo; ViewCargo viewCargo;
std::string path = "";
for (int i = 0; i < argc; ++i) for (int i = 0; i < argc; ++i)
{ {
std::string arg = argv[i]; std::string arg = argv[i];

View file

@ -132,6 +132,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="ChunkManager.cpp" />
<ClCompile Include="CompressionManager.cpp" /> <ClCompile Include="CompressionManager.cpp" />
<ClCompile Include="CreateCargo.cpp" /> <ClCompile Include="CreateCargo.cpp" />
<ClCompile Include="EncryptionManager.cpp" /> <ClCompile Include="EncryptionManager.cpp" />
@ -140,6 +141,7 @@
<ClCompile Include="voidcmd.cpp" /> <ClCompile Include="voidcmd.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ChunkManager.h" />
<ClInclude Include="CompressionManager.h" /> <ClInclude Include="CompressionManager.h" />
<ClInclude Include="CreateCargo.h" /> <ClInclude Include="CreateCargo.h" />
<ClInclude Include="DataStruct.h" /> <ClInclude Include="DataStruct.h" />

View file

@ -27,6 +27,9 @@
<ClCompile Include="ViewCargo.cpp"> <ClCompile Include="ViewCargo.cpp">
<Filter>Pliki źródłowe</Filter> <Filter>Pliki źródłowe</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ChunkManager.cpp">
<Filter>Pliki źródłowe</Filter>
</ClCompile>
<ClCompile Include="EncryptionManager.cpp"> <ClCompile Include="EncryptionManager.cpp">
<Filter>Pliki źródłowe</Filter> <Filter>Pliki źródłowe</Filter>
</ClCompile> </ClCompile>
@ -47,6 +50,9 @@
<ClInclude Include="DataStruct.h"> <ClInclude Include="DataStruct.h">
<Filter>Pliki nagłówkowe</Filter> <Filter>Pliki nagłówkowe</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ChunkManager.h">
<Filter>Pliki nagłówkowe</Filter>
</ClInclude>
<ClInclude Include="EncryptionManager.h"> <ClInclude Include="EncryptionManager.h">
<Filter>Pliki nagłówkowe</Filter> <Filter>Pliki nagłówkowe</Filter>
</ClInclude> </ClInclude>