{"id":16153862,"url":"https://github.com/roginvs/huffman_coding","last_synced_at":"2026-03-18T18:07:12.136Z","repository":{"id":77829659,"uuid":"172559123","full_name":"roginvs/huffman_coding","owner":"roginvs","description":"A playground and demo for Huffman Coding","archived":false,"fork":false,"pushed_at":"2023-02-28T15:23:45.000Z","size":3442,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T23:42:30.626Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roginvs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-25T18:13:46.000Z","updated_at":"2019-06-09T19:09:04.000Z","dependencies_parsed_at":"2024-11-02T01:41:19.403Z","dependency_job_id":"d0539289-1291-47c8-a523-142e08d7da78","html_url":"https://github.com/roginvs/huffman_coding","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/roginvs/huffman_coding","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fhuffman_coding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fhuffman_coding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fhuffman_coding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fhuffman_coding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roginvs","download_url":"https://codeload.github.com/roginvs/huffman_coding/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roginvs%2Fhuffman_coding/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28580245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T18:29:59.827Z","status":"ssl_error","status_checked_at":"2026-01-19T18:29:40.878Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T01:14:46.789Z","updated_at":"2026-01-19T18:32:51.583Z","avatar_url":"https://github.com/roginvs.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Демо алгоритма Хаффмана\n\nЭтот репозиторий состоит из реализаций кодирования и раскодирования по алгоритму Хаффмана. Кодирование и декодирование реализовано на C и так же на Typescript. Имеются консольные версии и web-демо (webassembly).\n\n# Алгоритм работы\n\nСжатие проходит в два прохода по файлу - сначала считается статистика по частоте используемых байтов, затем строится дерево Хаффмана и далее вторым проходом по файлу идёт сжатие.\n\nРаспаковка проходит в один проход - читается заголовок, строится дерево по информации из заголовка и далее сжатый файл читается по битам.\n\n# Формат сжатого файла\n\nПервые 4 байта - заголовок, фиксированные случайно выбранные 4 байта.\n\nДалее 4 байта - размер оригинального файла.\n\nПосле этого идёт поток битов для описания дерева. Дерево записывается простым обходом. Если это внутренний узел, то записать бит 0. Если это лист, то записать бит 1 и далее 8 битов на соответствующий байт. Всего должно получиться 255 внутренних узлов и 256 листов, т.е. `255*1 + 256*(1 + 8) = 2559 битов`. После этого идёт контрольный нулевой бит для того чтобы заголовок закончился на целом байте.\n\nДалее идёт поток битов для самих данных.\n\nПоследний байт дополняется до целого байта нулевыми битами если нужно.\n\n# C-версия\n\nСобирается через gcc на Windows (с mingw) или на Linux:\n\n```\ngcc -Wall -o main main.c\n./main encode \u003cимя входного файла\u003e \u003cимя сжатого выходного файла\u003e\n./main decode \u003cимя сжатого входного файла\u003e \u003cимя выходного файла\u003e\n```\n\nВ `main.c` находится только CLI оболочка, а вся логика реализована в `huffman.c`.\n\nФункция кодирования - это `huffman_encode`, принимает 3 параметра - указатель на буфер с входными данными, длина входного буфера, указатель на переменную куда запишется размер выходного буфера. Внутри функции выделяется память на выходной буфер (его длина как раз идёт в `outlen`), и далее функция возвращает указатель на выделенный блок памяти (либо `NULL` если произошла ошибка).\n\nФункция декодирования - это `huffman_decode`, принимает 2 параметра - указатель на входной буфер и указатель на переменную куда запишется размер выходного буфера. Размер входного буфера определяется в заголовке (точнее, там определяется размер файла до сжатия). Так же аллоцирует память и возвращает указатель на буфер либо `NULL`.\n\n# TypeScript версия для nodejs\n\nЯдро находится в `huffman.ts`, CLI оболочка в `main.ts`. Для запуска нужен nodejs и typescript, можно предварительно собирать в js либо запускать сразу с `ts-node`\n\n```\nts-node -T main.ts encode \u003csome-input-file\u003e \u003csome-output-encoded-file\u003e\nts-node -T main.ts decode \u003csome-input-encoded-file\u003e \u003csome-output-decoded-file\u003e\n```\n\n# Тесты\n\nТесты проверяют сжатие обоими версиями (C и TS), проверяют что файл распаковывается и совпадает с оригинальным. Запускаются тесты в `./test.sh`\n\n# WebAssembly версия\n\nСобирается с emscripten в `buildWeb.sh`, доступна по адресу \u003chttps://roginvs.github.io/huffman_coding/web/\u003e\n\nЯ не использовал webpack/react/etc чтобы не тянуть большие зависимости.\n\nИнтересно что я из C кода экспортировал malloc/free для того, чтобы иметь возможность получать в javascript буферы в аллокаторе из stdlib.\n\nWebassembly реализация работает где-то раза в 4 быстрей чем javascript.\n\n# TODO\n\nПочему-то WebAssembly версия падает на файле `hpmor_ru.html.huffman.huffman` (два раза сжатый `./test/hpmor_ru.html`). При этом C версия пакует нормально и полученный файл так же распаковывается. Возможно где-то неправильно используется `emscripten`.\n\nUpdate: Почему-то Webassembly теперь падает на `hpmor_ru.html.huffman.huffman.huffman`\n\nUpdate2: Теперь почему-то вообще не падает, хотя wasm файл не поменялся.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froginvs%2Fhuffman_coding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froginvs%2Fhuffman_coding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froginvs%2Fhuffman_coding/lists"}