Skip to content

Runzipper/core

Repository files navigation

open-mission-compressor

실행 방법

npx open-mission-compressor

모드 선택

사용자에게 압축을 할 것인지 압축해제를 할 것인지 입력받습니다.

압축/압축 해제를 선택해주세요.
압축: 1
압축 해제: 2

압축 프로세스

  • 개별 파일마다 LZ77 압축 적용
  • LZ77로 압축된 데이터를 Huffman 코딩으로 재압축
  • 모든 압축된 파일을 메타데이터와 함께 하나의 아카이브로 통합

압축 해제 프로세스

  • 아카이브에서 메타데이터 읽기 (파일 개수, 경로, 데이터 길이)
  • 각 파일별로 Huffman 디코딩 적용
  • Huffman으로 복원된 데이터를 LZ77 압축 해제
  • 디렉토리 구조를 재구성하여 원본 파일 복원

요구사항

공통

  • 파일들을 하나의 파일로 합칠 수 있어야 한다.
  • 하나로 합쳐진 파일을 여러개의 파일들로 다시 나눌 수 있어야 한다.
  • 위 기능에 압축알고리즘을 적용하여, 하나의 파일로 합칠 시 용량을 줄일 수 있어야 한다.

입력

  • 사용자는 여러개의 파일을 선택 할 수 있다.
  • 사용자는 디렉토리를 선택 할 수 있다.
  • 사용자는 아카이빙된 파일을 선택할 수 있다.
  • 파일 탐색기를 통해 부모/자식 디렉토리로 이동할 수 있다.

압축

  • LZ77 알고리즘을 사용하여 파일들을 압축한다.
    • 검색 버퍼 크기: 32KB
    • 전방 버퍼 크기: 258 bytes
    • 반복 패턴을 (offset, length, next_char) 튜플로 인코딩
  • 허프만 압축 알고리즘을 사용하여 파일들을 압축한다.
    • 빈도 기반 가변 길이 코드 할당
    • Huffman 트리 구성을 통한 최적 압축
  • LZ77 → Huffman 순서로 압축하여 최대 압축률 달성

출력

  • 사용자는 여러개의 파일을 하나로 합친 파일의 이름을 정할 수 있다. (자동으로 .compressed 확장자 추가)
  • 사용자는 아카이빙된 파일을 여러개의 파일로 다시 나눌시에 저장될 디렉토리를 정할 수 있다.
  • 압축 해제 시 원본 디렉토리 구조가 유지된다.

프로젝트 구조

src/
├── index.ts                         # 애플리케이션 진입점
├── App.ts                           # 메인 애플리케이션 로직
│
├── controllers/                     # 컨트롤러 계층
│   ├── ModeSelector.ts              # 압축/해제 모드 선택
│   ├── FileSelector.ts              # 파일 선택 전략 인터페이스
│   ├── InteractiveFileSelector.ts   # 대화형 파일 탐색 구현체
│   ├── TextFileSelector.ts          # 직접 경로 입력 구현체
│   ├── CompressController.ts        # 압축 로직 제어
│   └── DecompressController.ts      # 압축 해제 로직 제어
│
├── models/                          # 도메인 모델
│   ├── Mode.ts                      # 모드 타입 (압축/해제)
│   ├── File.ts                      # 파일 시스템 경로 관리
│   ├── LZ77.ts                      # LZ77 압축/해제 알고리즘
│   └── Huffman.ts                   # Huffman 압축/해제 알고리즘
│
├── view/                            # 뷰 계층
│   ├── Input.ts                     # 사용자 입력 처리
│   └── Output.ts                    # 콘솔 출력 처리
│
├── utils/                           # 유틸리티
│   ├── Heap.ts                      # MinHeap/MaxHeap 자료구조
│   ├── Parser.ts                    # 입력값 파싱
│   ├── Validator.ts                 # 유효성 검증
│   └── Retry.ts                     # 에러 재시도 메커니즘
│
├── constants/                       # 상수 관리
│   ├── constant.ts                  # 애플리케이션 상수
│   ├── message.ts                   # 사용자 메시지
│   └── errorMessage.ts              # 에러 메시지
│
└── types/                           # TypeScript 타입 정의
    └── index.d.ts

아키텍처 설계

압축 아키텍처

압축 파이프라인

원본 파일 → LZ77 압축 → Huffman 코딩 → 압축 데이터

아카이브 포맷

[파일 개수: 4 bytes]
[경로1 길이: 4 bytes][경로1: UTF-8][데이터1 길이: 4 bytes][압축 데이터1]
[경로2 길이: 4 bytes][경로2: UTF-8][데이터2 길이: 4 bytes][압축 데이터2]
...
  • 모든 길이 필드: 4바이트 부호 없는 정수 (빅 엔디안)
  • 경로: 기본 디렉토리 상대 경로 (UTF-8 인코딩)

압축 해제 아키텍처

압축 해제 파이프라인

압축 데이터 → Huffman 디코딩 → LZ77 압축 해제 → 원본 파일

압축 해제 프로세스

  1. 아카이브 메타데이터 파싱 (파일 개수, 경로, 길이)
  2. 각 압축 파일 추출
  3. 역순 압축 해제 (Huffman → LZ77)
  4. 디렉토리 구조 재구성
  5. 출력 디렉토리에 파일 작성

압축 알고리즘 상세

LZ77 압축

설정

searchBufferSize = 32KB (32,768 bytes)
lookAheadBufferSize = 258 bytes

압축 형식

(offset, length, next_char) 튜플
- offset: 2 bytes
- length: 2 bytes
- next_char: 1 byte

Huffman 코딩

압축 과정

1. 바이트 빈도수 계산
2. Huffman 트리 구축 (MinHeap 활용)
3. 빈도 기반 가변 길이 코드 테이블 생성
4. 데이터 인코딩  직렬화