Compare commits
11 commits
Wywołanie_
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
109d10c3ca | ||
|
|
336e12d8c0 | ||
|
|
bfc6c1811d | ||
|
|
f9ea960cf0 | ||
|
|
8896624acc | ||
|
|
aea66dbfd9 | ||
|
|
6b0fbed103 | ||
|
|
e69bfd0e3d | ||
|
|
c2bdcfe2b9 | ||
|
|
608e382095 | ||
|
|
c733778e2e |
14 changed files with 158 additions and 421 deletions
137
ChunkManager.cpp
137
ChunkManager.cpp
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -23,9 +23,6 @@ CompressionManager::CompressionManager()
|
|||
:cctx(ZSTD_createCCtx())
|
||||
,dctx(ZSTD_createDCtx())
|
||||
{
|
||||
// Tu ustawienia pod kompresjê
|
||||
const int level = COMPRESSION_LEVEL;
|
||||
|
||||
// Ustawienia frameless
|
||||
size_t rc = 0;
|
||||
|
||||
|
|
@ -42,7 +39,7 @@ CompressionManager::CompressionManager()
|
|||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0);
|
||||
|
||||
// Ustawia poziom kompresji
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level);
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd::compression_level);
|
||||
|
||||
if (ZSTD_isError(rc)) {
|
||||
std::cerr << "ZSTD_CCtx_setParameter error" << std::endl;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@
|
|||
#error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless"
|
||||
#endif
|
||||
|
||||
#define COMPRESSION_LEVEL 3
|
||||
namespace zstd
|
||||
{
|
||||
inline constexpr short compression_level = 3;
|
||||
}
|
||||
|
||||
class CompressionManager
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@
|
|||
#include "CreateCargo.h"
|
||||
|
||||
CreateCargo::CreateCargo()
|
||||
: signature(SIGNATURE)
|
||||
, extension(EXTENSION)
|
||||
, version(VERSION)
|
||||
: signature(fl::sigpak)
|
||||
, extension(fl::extpak)
|
||||
, methodFlags(0)
|
||||
, xxhState(XXH64_createState())
|
||||
, offset(0)
|
||||
|
|
@ -90,7 +89,7 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag)
|
|||
}
|
||||
|
||||
// Zapisywanie klucza szyfrującego
|
||||
if (flag == FILE_FLAG_ENCRYPT || flag == FILE_FLAG_ZIPENC || encList.size() > 0)
|
||||
if (flag == flag::enc || flag == flag::ezd || encList.size() > 0)
|
||||
{
|
||||
eman.saveKey(catalogPath, hppKey);
|
||||
}
|
||||
|
|
@ -133,11 +132,11 @@ bool CreateCargo::GetFileList(const std::string& path)
|
|||
{
|
||||
if (FindOnTheList(zipList, fileRef) || CheckFileExtension(fileRef, zipList))
|
||||
{
|
||||
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ZIPENC : FILE_FLAG_COMPRESS;
|
||||
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::ezd : flag::zip;
|
||||
}
|
||||
else
|
||||
{
|
||||
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ENCRYPT : FILE_FLAG_RAW;
|
||||
pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::enc : flag::raw;
|
||||
}
|
||||
pc.path = PathToUnixLike(tmpPath);
|
||||
std::cout << pc.path << " - " << pc.parameter << std::endl;
|
||||
|
|
@ -185,42 +184,13 @@ CargoHead CreateCargo::CreateCargoHead(const uint32_t& filesLen, const uint64_t&
|
|||
{
|
||||
CargoHead ch;
|
||||
|
||||
ch.signature = signature;
|
||||
ch.signature = fl::sigpak;
|
||||
ch.table = table;
|
||||
ch.files = filesLen;
|
||||
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -249,28 +219,27 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
size_t size = f.tellg();
|
||||
f.seekg(0, std::ios::beg);
|
||||
|
||||
if (size > MAX_FILE_SIZE)
|
||||
if (size > ds::maxFileSize)
|
||||
{
|
||||
std::cerr << path << " is too large. It exceeds " << MAX_FILE_SIZE / 1024 / 1024 / 1024 << "GB!" << std::endl;
|
||||
std::cerr << path << " is too large. It exceeds " << ds::maxFileSize / 1024 / 1024 / 1024 << "GB!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
XXH64_reset(xxhState, 0);
|
||||
|
||||
//Wczytanie pliku do pamięci
|
||||
std::vector<char> buffer(CHUNK_STREAM_256MB);
|
||||
std::vector<char> buffer(ds::chunk_stream);
|
||||
|
||||
uint64_t sizeFile = 0;
|
||||
|
||||
const uint32_t chunkBlockSize = CHUNK_BLOCK_SIZE;
|
||||
const uint32_t chunkBlockSize = ds::block_size;
|
||||
const uint32_t quantity = (size + chunkBlockSize) / chunkBlockSize;
|
||||
const uint32_t lastChunkSize = size - (chunkBlockSize * (quantity - 1));
|
||||
|
||||
// Jeśli jest ustawiona flaga inna niż RAW
|
||||
// Dodaj do kontenera konfigurację chunków
|
||||
if (file.parameter != FILE_FLAG_RAW)
|
||||
if (file.parameter != flag::raw)
|
||||
{
|
||||
std::cout << "CHUNK PARAM" << std::endl;
|
||||
cargo.write(reinterpret_cast<const char*>(&quantity), sizeof(quantity));
|
||||
cargo.write(reinterpret_cast<const char*>(&chunkBlockSize), sizeof(chunkBlockSize));
|
||||
cargo.write(reinterpret_cast<const char*>(&lastChunkSize), sizeof(lastChunkSize));
|
||||
|
|
@ -278,7 +247,7 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
}
|
||||
|
||||
// Strumieniowanie danych
|
||||
while (f.read(buffer.data(), CHUNK_STREAM_256MB) || f.gcount() > 0)
|
||||
while (f.read(buffer.data(), ds::chunk_stream) || f.gcount() > 0)
|
||||
{
|
||||
const int bufferSize = f.gcount();
|
||||
buffer.resize(bufferSize);
|
||||
|
|
@ -286,7 +255,7 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
// Aktualizacja XXH64
|
||||
XXH64_update(xxhState, buffer.data(), buffer.size());
|
||||
|
||||
if (file.parameter == FILE_FLAG_RAW)
|
||||
if (file.parameter == flag::raw)
|
||||
{
|
||||
// Zapisywanie strumienia do kontenera
|
||||
cargo.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
|
||||
|
|
@ -308,17 +277,16 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
std::vector<char> outChunk;
|
||||
|
||||
// Przetwórz chunki i przetwórz
|
||||
if ((file.parameter & FILE_FLAG_COMPRESS) == FILE_FLAG_COMPRESS)
|
||||
if ((file.parameter & flag::zip) == flag::zip)
|
||||
{
|
||||
// Zaszyfruj i skompresuj lub tylko skompresuj
|
||||
outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ?
|
||||
outChunk = (file.parameter & flag::enc) == flag::enc ?
|
||||
eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Zaszyfruj lub skopiuj
|
||||
outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ?
|
||||
eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
|
||||
outChunk = eman.encrypt(chunk);
|
||||
}
|
||||
|
||||
const uint32_t outSize = outChunk.size();
|
||||
|
|
@ -329,19 +297,11 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
cargo.write(reinterpret_cast<const char*>(outChunk.data()), outChunk.size());
|
||||
sizeFile += outSize;
|
||||
}
|
||||
std::cout << "SIZE: " << sizeFile << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
ft.nameFile = path;
|
||||
ft.nameLen = path.length();
|
||||
|
|
@ -350,8 +310,6 @@ std::vector<FilesTable> CreateCargo::ComputingHeadFiles()
|
|||
ft.flag = file.parameter;
|
||||
ft.crc = XXH64_digest(xxhState);
|
||||
|
||||
//cargo.write(reinterpret_cast<const char*>(pakBuffer.data()), pakBuffer.size());
|
||||
|
||||
filesTable.push_back(ft);
|
||||
offset += sizeFile;
|
||||
}
|
||||
|
|
@ -373,24 +331,25 @@ void CreateCargo::GetFilters(const std::string& filterFile)
|
|||
file.close();
|
||||
|
||||
// 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
|
||||
if (jslist.contains(KEY_ENCRYPT))
|
||||
if (jslist.contains(key::enc))
|
||||
{
|
||||
encList = jslist[KEY_ENCRYPT].get<std::vector<std::string>>();
|
||||
encList = jslist[key::enc].get<std::vector<std::string>>();
|
||||
}
|
||||
|
||||
// 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>>();
|
||||
}
|
||||
|
||||
hppKey = jslist.value("keyhpp", false);
|
||||
// Flaga tworzenia klucza jako plik nag³ówka c++
|
||||
hppKey = jslist.value(key::hpp, false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "DataStruct.h"
|
||||
#include "ChunkManager.h"
|
||||
#include "EncryptionManager.h"
|
||||
#include "CompressionManager.h"
|
||||
|
||||
|
|
@ -45,6 +44,17 @@
|
|||
|
||||
#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
|
||||
{
|
||||
std::string path;
|
||||
|
|
@ -62,7 +72,6 @@ public:
|
|||
private:
|
||||
const std::string signature;
|
||||
const std::string extension;
|
||||
const signed char version;
|
||||
|
||||
uint8_t methodFlags;
|
||||
|
||||
|
|
@ -113,9 +122,6 @@ private:
|
|||
// Wczytanie filtrów wyj¹tków
|
||||
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
|
||||
bool CheckFileExtension(const std::string&, const std::vector<std::string>&);
|
||||
|
||||
|
|
|
|||
59
DataStruct.h
59
DataStruct.h
|
|
@ -22,39 +22,46 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#define EXTENSION "pak"
|
||||
#define SIGNATURE "XPAK"
|
||||
namespace ui
|
||||
{
|
||||
inline constexpr std::string_view title = "exPak";
|
||||
inline constexpr std::string_view ver = "0.5";
|
||||
}
|
||||
|
||||
#define SIGNATURE_KEY_FILE "XKEY"
|
||||
// Pliki
|
||||
namespace fl
|
||||
{
|
||||
inline constexpr std::string_view sigpak = "XPAK";
|
||||
inline constexpr std::string_view sigkey = "XKEY";
|
||||
|
||||
#define VERSION 0x03
|
||||
inline constexpr std::string_view extpak = "pak";
|
||||
inline constexpr std::string_view extkey = "key";
|
||||
}
|
||||
|
||||
// WielkoϾ pojedynczego bloku strumienia
|
||||
#define CHUNK_STREAM_512KB 524288 // 512KB
|
||||
#define CHUNK_STREAM_16MB 16777216 // 16MB
|
||||
#define CHUNK_STREAM_256MB 268435456 // 256MB
|
||||
// Size
|
||||
namespace ds
|
||||
{
|
||||
// Chunki streamowania
|
||||
inline constexpr uint32_t chunk_stream = 268435456; // 256MB
|
||||
|
||||
// Rozmiar pojedynczego bloku
|
||||
#define CHUNK_BLOCK_SIZE 131072 // 128KB
|
||||
// Blok chunków
|
||||
inline constexpr uint32_t block_size = 131072; // 128KB
|
||||
|
||||
#define FILE_FLAG_RAW 0x00
|
||||
#define FILE_FLAG_COMPRESS 0x0F
|
||||
#define FILE_FLAG_ENCRYPT 0xF0
|
||||
#define FILE_FLAG_ZIPENC 0xFF
|
||||
// Maksymalny rozmiar pliku do spakowania
|
||||
inline constexpr uint64_t maxFileSize = 8589934592; // 8GB
|
||||
}
|
||||
|
||||
#define FILE_FLAG_FILTERING 0xAB
|
||||
// Flagi
|
||||
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
|
||||
|
||||
|
||||
//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
|
||||
// Flaga do aktywacji filtra zdefiniowanego w json
|
||||
inline constexpr uint8_t filter = 0xAB;
|
||||
}
|
||||
|
||||
struct CargoHead
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,9 +67,6 @@ void EncryptionManager::generateKeys()
|
|||
|
||||
void EncryptionManager::saveKey(const std::string& path, bool hpp)
|
||||
{
|
||||
const std::string sig = SIGNATURE_KEY_FILE;
|
||||
const int8_t ver = VERSION;
|
||||
|
||||
// Wygeneruj time stamp
|
||||
std::time_t now = std::time(nullptr);
|
||||
const int time = static_cast<int>(now);
|
||||
|
|
@ -78,14 +75,13 @@ void EncryptionManager::saveKey(const std::string& path, bool hpp)
|
|||
std::vector<char> keyVec(reinterpret_cast<const char*>(key.data()),
|
||||
reinterpret_cast<const char*>(key.data()) + key.size());
|
||||
|
||||
const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION);
|
||||
const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), 0);
|
||||
|
||||
// Zapisz ten œmietnik do pliku KEY
|
||||
std::ofstream file(path + ".key", std::ios::binary);
|
||||
if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; }
|
||||
|
||||
file.write(sig.data(), sig.length());
|
||||
file.write(reinterpret_cast<const char*>(&ver), sizeof(ver));
|
||||
file.write(fl::sigkey.data(), fl::sigkey.length());
|
||||
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*>(&crcKey), sizeof(crcKey));
|
||||
|
|
@ -102,7 +98,7 @@ void EncryptionManager::saveCppHeadFile(const std::string& path)
|
|||
|
||||
std::ofstream file(path + ".hpp");
|
||||
|
||||
file << "// Plik wygenerowany przez " << PROGRAM_TITLE << " " << PROGRAM_VERSION << std::endl;
|
||||
file << "// Plik wygenerowany przez " << ui::title << " " << ui::ver << std::endl;
|
||||
file << std::endl;
|
||||
file << std::endl;
|
||||
file << "#pragma once" << std::endl;
|
||||
|
|
@ -137,18 +133,15 @@ std::string EncryptionManager::toHex(const unsigned char* data, size_t len)
|
|||
void EncryptionManager::loadKey(const std::string& path)
|
||||
{
|
||||
std::ifstream file(path + ".key", std::ios::binary);
|
||||
|
||||
const std::string signature = SIGNATURE_KEY_FILE;
|
||||
std::vector<char> sig(signature.size());
|
||||
std::vector<char> sig(fl::sigkey.size());
|
||||
int8_t ver;
|
||||
int time;
|
||||
|
||||
// Wczytaj
|
||||
file.read(sig.data(), sig.size());
|
||||
file.read(reinterpret_cast<char*>(&ver), sizeof(ver));
|
||||
|
||||
// SprawdŸ czy plik klucza jest poprawny
|
||||
if (std::string(sig.begin(), sig.end()) != signature || ver != VERSION)
|
||||
if (std::string(sig.begin(), sig.end()) != fl::sigkey)
|
||||
{
|
||||
throw std::runtime_error("Invalid key file!");
|
||||
}
|
||||
|
|
@ -161,7 +154,7 @@ void EncryptionManager::loadKey(const std::string& path)
|
|||
file.read(reinterpret_cast<char*>(&crcKey), sizeof(crcKey));
|
||||
|
||||
// SprawdŸ integralnoœæ klucza
|
||||
if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey)
|
||||
if (XXH64(keyVec.data(), keyVec.size(), 0) != crcKey)
|
||||
{
|
||||
throw std::runtime_error("Key integrity error!");
|
||||
}
|
||||
|
|
|
|||
125
ExtractCargo.cpp
125
ExtractCargo.cpp
|
|
@ -22,11 +22,11 @@
|
|||
ExtractCargo::ExtractCargo()
|
||||
:filesLen(0)
|
||||
, tablePosition(0)
|
||||
, version(VERSION)
|
||||
, signature(SIGNATURE)
|
||||
, xxhState(XXH64_createState())
|
||||
, signature(fl::sigpak)
|
||||
{
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
XXH64_reset(xxhState, 0);
|
||||
}
|
||||
|
||||
ExtractCargo::~ExtractCargo()
|
||||
|
|
@ -110,51 +110,6 @@ bool ExtractCargo::CheckCargoFile()
|
|||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -175,9 +130,6 @@ void ExtractCargo::LoadFilesTable()
|
|||
cargoFile.read(reinterpret_cast<char*>(&fhTmp.crc), sizeof(fhTmp.crc));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -191,25 +143,76 @@ void ExtractCargo::ExtractingFilesFromCargo()
|
|||
{
|
||||
std::filesystem::path dir = cargoFileName.stem() / fh.nameFile;
|
||||
CreateDirections(dir);
|
||||
|
||||
std::cout << dir.string() << std::endl;
|
||||
|
||||
std::ofstream file(dir, std::ios::binary);
|
||||
|
||||
std::cout << fh.size << std::endl;
|
||||
cargoFile.seekg(fh.offset);
|
||||
std::vector<char> buffor(fh.size);
|
||||
|
||||
cargoFile.read(buffor.data(), fh.size);
|
||||
XXH64_reset(xxhState, 0);
|
||||
|
||||
std::vector<char> rawBuffor;
|
||||
computingBytes(buffor, rawBuffor, fh.flag);
|
||||
|
||||
if (!HashValid(rawBuffor, fh.crc))
|
||||
// Strumieñ wyci¹gaj¹cy
|
||||
if (fh.flag == flag::raw)
|
||||
{
|
||||
std::cerr << fh.nameFile << " Error: Corrupted data integration CRC" << std::endl;
|
||||
for (uint64_t sc = 0; sc < fh.size; sc += ds::chunk_stream)
|
||||
{
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
file.write(reinterpret_cast<const char*>(rawBuffor.data()), rawBuffor.size());
|
||||
XXH64_update(xxhState, rawBuffer.data(), rawBuffer.size());
|
||||
file.write(reinterpret_cast<const char*>(rawBuffer.data()), chunkSize);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@
|
|||
#include <sstream>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <xxhash.h>
|
||||
|
||||
#include "DataStruct.h"
|
||||
#include "ChunkManager.h"
|
||||
#include "EncryptionManager.h"
|
||||
#include "CompressionManager.h"
|
||||
|
||||
class ExtractCargo {
|
||||
public:
|
||||
|
|
@ -47,8 +48,8 @@ private:
|
|||
|
||||
uint32_t filesLen;
|
||||
uint64_t tablePosition;
|
||||
XXH64_state_t* xxhState;
|
||||
|
||||
const int8_t version;
|
||||
const std::string signature;
|
||||
|
||||
std::vector<FilesTable> filesHeads;
|
||||
|
|
@ -57,7 +58,7 @@ private:
|
|||
std::ifstream cargoFile;
|
||||
|
||||
EncryptionManager eman;
|
||||
|
||||
CompressionManager cman;
|
||||
|
||||
// Sprawdzenie poprawnoœci archiwum
|
||||
bool CheckCargoFile();
|
||||
|
|
@ -68,13 +69,7 @@ private:
|
|||
// Pobieranie nag³ówków plików
|
||||
void LoadFilesTable();
|
||||
|
||||
// Sprawdzanie sumy kontrolnej
|
||||
bool HashValid(const std::vector<char>&, const uint64_t&);
|
||||
|
||||
// Utwórz katalog
|
||||
void CreateDirections(std::filesystem::path);
|
||||
|
||||
// Magiczna funkcja do dekompresji i deszyfracji danych
|
||||
void computingBytes(const std::vector<char>&, std::vector<char>&, const uint8_t&);
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ bool ViewCargo::ViewFiles(const std::string& path)
|
|||
uint64_t tabPos = 0;
|
||||
uint32_t tabSize = 0;
|
||||
|
||||
const std::string signature = SIGNATURE;
|
||||
std::vector<char> magic(signature.length());
|
||||
std::vector<char> magic(fl::sigpak.length());
|
||||
int8_t cargoVer = 0;
|
||||
|
||||
std::ifstream cargo(path, std::ios::binary);
|
||||
|
|
@ -82,7 +81,7 @@ bool ViewCargo::ViewFiles(const std::string& path)
|
|||
cargo.read(reinterpret_cast<char*>(&tabSize), sizeof(tabSize));
|
||||
|
||||
//SprawdŸ czy kontener ma poprawn¹ sygnature
|
||||
if (std::string(magic.begin(), magic.end()) != signature)
|
||||
if (std::string(magic.begin(), magic.end()) != fl::sigpak)
|
||||
{
|
||||
std::cerr << "Error: Corrupted Cargo" << std::endl;
|
||||
cargo.close();
|
||||
|
|
@ -129,15 +128,15 @@ void ViewCargo::ShowFile(const std::string& file, const uint8_t& flag)
|
|||
// Ustawianie checkboxów
|
||||
switch (flag)
|
||||
{
|
||||
case FILE_FLAG_COMPRESS:
|
||||
case flag::zip:
|
||||
compresedCheck = "[x]";
|
||||
break;
|
||||
|
||||
case FILE_FLAG_ENCRYPT:
|
||||
case flag::enc:
|
||||
encryptedCheck = "[x]";
|
||||
break;
|
||||
|
||||
case FILE_FLAG_ZIPENC:
|
||||
case flag::ezd:
|
||||
compresedCheck = "[x]";
|
||||
encryptedCheck = "[x]";
|
||||
break;
|
||||
|
|
|
|||
20
voidcmd.cpp
20
voidcmd.cpp
|
|
@ -80,26 +80,16 @@ static bool EmptyPath(std::string path)
|
|||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string path = "";
|
||||
|
||||
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;
|
||||
std::cout << ui::title << std::endl << "ver. " << ui::ver << std::endl;
|
||||
std::cout << "Author: Yanczi" << std::endl;
|
||||
std::cout << "License: GNU LGPL v3" << "\n" << std::endl;
|
||||
|
||||
CreateCargo cargo;
|
||||
ExtractCargo extract;
|
||||
ViewCargo viewCargo;
|
||||
|
||||
std::string path = "";
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ChunkManager.cpp" />
|
||||
<ClCompile Include="CompressionManager.cpp" />
|
||||
<ClCompile Include="CreateCargo.cpp" />
|
||||
<ClCompile Include="EncryptionManager.cpp" />
|
||||
|
|
@ -141,7 +140,6 @@
|
|||
<ClCompile Include="voidcmd.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ChunkManager.h" />
|
||||
<ClInclude Include="CompressionManager.h" />
|
||||
<ClInclude Include="CreateCargo.h" />
|
||||
<ClInclude Include="DataStruct.h" />
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@
|
|||
<ClCompile Include="ViewCargo.cpp">
|
||||
<Filter>Pliki źródłowe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ChunkManager.cpp">
|
||||
<Filter>Pliki źródłowe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EncryptionManager.cpp">
|
||||
<Filter>Pliki źródłowe</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -50,9 +47,6 @@
|
|||
<ClInclude Include="DataStruct.h">
|
||||
<Filter>Pliki nagłówkowe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ChunkManager.h">
|
||||
<Filter>Pliki nagłówkowe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EncryptionManager.h">
|
||||
<Filter>Pliki nagłówkowe</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue