CLI-утилита на C++ для объединения нескольких файлов в один архив без сжатия с защитой от одиночных битовых ошибок. Использует код Хэмминга с настраиваемыми параметрами (n, k) — длиной кодового и информационного слов.
- Создание архива из произвольного количества файлов
- Извлечение всех или выбранных файлов из архива
- Просмотр содержимого архива (
list) - Добавление файлов в существующий архив (
append) - Удаление файлов из архива (
delete) - Конкатенация двух архивов в один (
concatenate) - Настраиваемые параметры кода Хэмминга
(cword_len, word_len) - Автоматическая коррекция одиночной битовой ошибки в каждом кодовом слове
- C++17
- STL (
<fstream>,<cstdint>) - CMake
- Без внешних зависимостей
git clone https://github.com/LomanTrue/hamming-archiver.git
cd hamming-archiver
mkdir build && cd build
cmake ..
makeПосле сборки появится исполняемый файл hamarc.
Все команды начинаются с ключевого слова hamarc. Имя архива указывается через -f <name> или --file=<name>.
hamarc -c -f archive.haf file1.txt file2.bin <cword_len> <word_len>Последние два числовых аргумента — параметры кода Хэмминга: длина кодового слова n и длина информационного слова k. Например, для классического кода Хэмминга (7, 4) укажите 7 4.
hamarc -l -f archive.hafИзвлечь все файлы в директорию:
hamarc -x <output_dir> -f archive.hafИзвлечь конкретные файлы:
hamarc -x <output_dir> -f archive.haf file1.txt file2.binhamarc -a -f archive.haf newfile1.txt newfile2.binhamarc -d -f archive.haf file1.txthamarc -A old1.haf old2.haf -f merged.haf <cword_len> <word_len>| Короткий | Длинный | Назначение |
|---|---|---|
-c |
--create |
Создать архив |
-l |
--list |
Показать содержимое |
-x <dir> |
--extract <dir> |
Извлечь файлы в директорию |
-a |
--append |
Добавить файлы |
-d |
--delete |
Удалить файлы |
-A |
--concatenate |
Объединить два архива |
-f <name> |
--file=<name> |
Имя целевого архива |
Проект разделён на CLI-слой и слой работы с архивом:
main.cpp # Парсинг аргументов командной строки и диспетчеризация
archive.h/.cpp # Структуры данных и операции над архивом
Ключевые сущности из archive.h:
struct arch_file {
std::string name; // Имя исходного файла
uint64_t size; // Размер исходных данных
uint64_t begin; // Смещение блока в архиве
};
struct arch_info {
std::vector<arch_file> files; // Таблица файлов
uint64_t size; // Размер заголовка
};
struct archive {
std::string name; // Имя архива
uint32_t cword_len; // Длина кодового слова (n)
uint32_t word_len; // Длина информационного слова (k)
arch_info info; // Метаданные
void WriteArch();
void ReadArch();
void AddFile(std::string file_name);
void DeleteFile(std::string& file_name);
void ExtractFile(std::string& file_name, std::string& file_dir);
void ListOfFiles();
void Concatenate(archive& arch1, archive& arch2);
};┌────────────────────────────────────────┐
│ Header │
│ ├─ Размер метаданных (8 байт) │
│ ├─ cword_len (4 байта) │
│ └─ word_len (4 байта) │
├────────────────────────────────────────┤
│ Таблица файлов │
│ для каждого файла: │
│ ├─ имя (строка) │
│ ├─ size (8 байт) │
│ └─ begin: смещение блока (8 байт) │
├────────────────────────────────────────┤
│ Данные файлов │
│ разбиты на кодовые слова Хэмминга │
│ длины cword_len │
└────────────────────────────────────────┘
Каждые k бит исходных данных кодируются в n бит добавлением n - k проверочных бит. Позиции проверочных бит — степени двойки (1, 2, 4, 8, ...), значения вычисляются как XOR информационных бит в соответствующих позициях.
При чтении вычисляется синдром — XOR проверочных бит. Если синдром равен нулю — данные целы; иначе значение синдрома указывает на номер испорченного бита, который инвертируется.
Это позволяет восстановить одну битовую ошибку в каждом кодовом слове, что соответствует определению кода Хэмминга (n, k).
# Создаём архив из двух файлов с кодом Хэмминга (7, 4)
$ ./hamarc -c -f my.haf hello.txt notes.md 7 4
# Смотрим содержимое
$ ./hamarc -l -f my.haf
hello.txt 126 bytes
notes.md 2048 bytes
# Добавляем ещё один файл
$ ./hamarc -a -f my.haf image.png
# Извлекаем всё в папку out/
$ ./hamarc -x out -f my.haf