# QR Code Transceiver (광학 에어갭 데이터 전송 시스템)

[English](README.md) | [한국어](README.ko.md)

애니메이션 연속 QR 코드("QR 코드 무비")를 사용하여 물리적으로 격리된 에어갭(Air-gap) 환경 간에 텍스트 및 바이너리 파일을 전송하는 초경량, 의존성 없는 브라우저 기반 송수신 시스템입니다.

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python 3.x](https://img.shields.io/badge/Python-3.x-green.svg)](https://www.python.org/)
[![WebRTC / HTTPS](https://img.shields.io/badge/Browser-WebRTC%20%2F%20HTTPS-orange.svg)]()

---

## 📌 개요 (Overview)

**QR Code Transceiver**는 컴퓨터 모니터와 스마트폰 카메라와 같이 물리적으로 격리된("에어갭") 기기 간에 Wi-Fi, 블루투스, 이동통신 또는 물리적 USB 연결 없이도 안전하게 데이터를 전송할 수 있도록 합니다.

### 주요 기능
* 📺 **광학 데이터 전송**: 텍스트나 바이너리 파일을 시각적 QR 코드 애니메이션 스트림으로 전송합니다.
* 📦 **시스토매틱 LT Code 파운틴 엔진**: 페이로드를 $K$개의 소스 블록으로 분할하고 2단계 전송 전략을 사용합니다: 1단계($s=1..K$)에서는 각 소스 블록을 직접 전송하여 손실 없는 환경에서 디코딩 오버헤드 0%로 즉시 복원하며, 2단계($s > K$)에서는 Mulberry32 PRNG 및 Robust Soliton 분포 기반 파운틴 드롭릿을 생성하여 손실된 프레임을 복구합니다.
* 🛡️ **Level M 오류 복원 능력**: Error Correction Level M(15% 리드-솔로몬 오류 복원 내성)을 적용하여 카메라 모션 블러, 렌즈 왜곡 및 광학 반사에 강력한 내성을 제공합니다.
* 🎯 **카메라 최적화 광학 밀도**: 모바일 센서에서 모듈 피셀 시독성을 유지하기 위해 QR 버전을 최대 Version 15($77 \times 77$ 모듈)로 제한하고 Version 10, 12, 15 옵션을 제공합니다.
* 🚀 **오프스크린 프레임 프리렌더링 엔진**: $N = \max(K \times 2, 60)$개의 QR 프레임을 메모리 상의 Data URL 캐시에 미리 생성하여, 고속 재생 시 런타임 캔버스 지연을 완벽히 제거합니다.
* ⚡ **순수 8비트 바이너리 QR 모드**: 기존 Base64 및 JSON 인코딩을 압축된 바이너리 헤더와 8비트 바이트 QR 프레임(`MODE_8BIT_BYTE`)으로 대체하여 약 ~40%의 오버헤드를 절감합니다.
* ⏩ **속도 프리셋**: 셔터 동기화 프리셋 지원: **Standard (5 FPS)**, **🚀 High Speed (7 FPS - Mobile Sweet Spot)**, **⚡ Ultra Speed (10 FPS)**.
* 📷 **고속 카메라 스캐너**: 실시간 QR 코드 테두리 추적 기능과 함께 고프레임 카메라 스캐닝(최대 초당 60회 스캔)을 활용합니다.
* 🧩 **실시간 BP 디코더 및 DOM 캐싱 진행 표시**: 신뢰 전파(BP) 디코딩을 활용하여 실시간으로 소스 블록을 복원하며, DOM 그리드 셀 요소 캐싱으로 최대 스캔 처리량을 유지합니다.
* 📥 **바이너리 파일 자동 재조립**: 원본 데이터 버퍼(`Uint8Array`)를 직접 복원하고 원본 파일명을 유지하여 브라우저 다운로드를 실행합니다.
* 🔒 **로컬 HTTPS 서버 포함**: 브라우저의 미디어 보안 요구사항(`navigator.mediaDevices.getUserMedia`)을 충족하기 위해 Python SSL 서버 및 자체 서명 TLS 증명서를 제공합니다.
* ✨ **Gemini AI 연동**: 광학 전송 전 긴 텍스트 입력값을 요약하는 선택적 Gemini AI 연동 기능을 지원합니다.

---

## 🏗️ 시스템 아키텍처 (System Architecture)

```mermaid
flowchart TD
    subgraph Transmitter ["송신기 (화면 Display)"]
        A[텍스트 / 바이너리 파일 입력] --> B[페이로드를 K개 소스 블록으로 분할]
        B --> C[시스토매틱 LT 파운틴 인코더: 1단계 직송 + 2단계 Soliton 파운틴]
        C --> D[오프스크린 캔버스 프레임 캐시 사전 렌더링]
        D --> E[순수 8비트 바이트 QR 코드 무비 스트림 출력]
    end

    subgraph Receiver ["수신기 (카메라 Camera)"]
        F[카메라 비디오 스트림] --> G[실시간 프레임 스캐너]
        G --> H[바이너리 패킷 헤더 언패킹]
        H --> I[신뢰 전파 BP 파운틴 디코더]
        I --> J[DOM 캐시 그리드 실시간 복원 진행 상황 기록]
        J -->|K개 블록 복원 완료| K[원본 Uint8Array 페이로드 재조립]
        K -->|텍스트| L[텍스트 UI 출력]
        K -->|바이너리 파일| M[파일 다운로드 실행]
    end

    Transmitter -- "광학 에어갭 (화면 -> 카메라)" --> Receiver
```

---

## 🚀 시작하기 (Getting Started)

### 사전 요구사항
* 웹 인터페이스를 제공할 호스트에 **Python 3.x** 설치.
* 수신 기기에서 카메라 권한이 활성화된 최신 웹 브라우저(Chrome, Firefox, Safari, Edge 등).

### 빠른 실행 (Quick Start)

1. **저장소 클론**:
   ```bash
   git clone https://github.com/your-username/qrcode_transceiver.git
   cd qrcode_transceiver
   ```

2. **로컬 HTTPS 서버 실행**:
   ```bash
   python3 server.py 8000
   ```
   *(참고: `python3 server.py 8080`과 같이 옵션 인자로 포트 번호를 지정할 수 있습니다)*

3. **웹 애플리케이션 접속**:
   * **송신기 (Transmitter)**: 송신 기기에서 `https://localhost:8000/transmitter.html` 로 접속합니다.
   * **수신기 (Receiver)**: 수신 기기(예: 동일한 로컬 네트워크에 연결된 모바일 기기 또는 카메라 스캐너)에서 `https://<로컬-IP>:8000/receiver.html` 로 접속합니다.

---

## 📖 사용 가이드 (Usage Guide)

### 데이터 송신 (Transmitter)

1. `transmitter.html` 페이지를 엽니다.
2. **Text Data** 입력란에 텍스트를 입력하거나 **Upload a File**을 통해 바이너리 파일을 업로드합니다.
3. 필요에 따라 QR 코드 설정을 조정합니다:
   * **QR Code Size**: Small (128px), Medium (192px), Large (256px), Extra Large (300px), Huge (400px), Max (450px).
   * **QR Code Version**: Auto (Version 10), Version 10 (57x57), Version 12 (65x65), Version 15 (77x77).
4. **Generate Movie** 버튼을 클릭합니다. 오프스크린 프리렌더링 엔진이 $N = \max(K \times 2, 60)$개의 프레임을 메모리에 준비합니다.
5. 속도 프리셋을 선택하거나 **Speed (FPS)** 슬라이더를 조절합니다:
   * **Standard (5 FPS)**: 기본 설정 / 보급형 카메라 센서 권장 (프레임당 200ms).
   * **🚀 High Speed (7 FPS - Mobile Sweet Spot)**: 모바일 카메라 셔터 속도와 디코딩 안정성의 최적 밸런스 (프레임당 142ms).
   * **⚡ Ultra Speed (10 FPS)**: 고프레임 카메라 센서를 위한 초고속 광학 스트리밍 (프레임당 100ms).
6. *(선택사항)* **✨ Summarize & Generate** 버튼을 눌러 Gemini AI로 텍스트를 요약한 후 QR 코드를 생성할 수 있습니다.

### 데이터 수신 (Receiver)

1. `receiver.html` 페이지를 엽니다.
2. 사용할 카메라(후면 또는 전면)를 선택하고 **Scan Rate** 슬라이더(초당 1~60회)를 조정합니다.
3. **Start Camera** 버튼을 누르고 프롬프트가 뜨면 카메라 접근 권한을 허용합니다.
4. 송신기 화면의 애니메이션 QR 코드를 향해 카메라를 비춥니다.
5. 파운틴 드롭릿이 수신되고 BP 디코더에 의해 블록이 복원됨에 따라 시각적 진행 그리드가 실시간으로 업데이트됩니다.
6. $K$개 블록이 모두 복원되면(100% 완료) 페이로드가 자동으로 재조립되어 화면에 표시되거나 파일로 다운로드됩니다.

---

## ⚡ 처리량 및 성능 벤치마크 (Throughput & Benchmarks)

Error Correction Level M, 카메라 최적화 모듈 밀도(Version 10~15), 순수 8비트 바이트 QR 패킹, 오프스크린 프레임 프리렌더링 및 DOM 셀 캐싱 기법을 통해 물리적 에어갭 환경에서 신뢰성 높은 전송 성능을 달성합니다:

### 모듈 밀도 및 페이로드 용량 (Level M 기준)

| QR 버전 | 마트릭스 크기 | 모듈 너비 (350px 디스플레이) | 최대 원시 패킷 | 블록 크기 $L$ |
|---|---|---|---|---|
| **Version 1** | $21 \times 21$ | 16.6 px | 12 바이트 | 1 바이트 |
| **Version 5** | $37 \times 37$ | 9.4 px | 60 바이트 | 44 바이트 |
| **Version 10** | $57 \times 57$ | 6.1 px | 158 바이트 | 142 바이트 |
| **Version 12** | $65 \times 65$ | 5.3 px | 204 바이트 | 188 바이트 |
| **Version 15** | $77 \times 77$ | 4.5 px | 272 바이트 | 256 바이트 |

### 전송 처리량 벤치마크

| 속도 프리셋 | 프레임레이트 (FPS) | QR 버전 | 프레임당 패킷 용량 | 전송 처리량 범위 | 수신 오버헤드 |
|---|---|---|---|---|---|
| **Standard** | 5 FPS | Version 10 – 15 | 158 – 272 바이트 | **0.8 – 1.36 KB/sec** | 0% (1단계 시스토매틱) |
| **🚀 High Speed** | 7 FPS *(Mobile Sweet Spot)* | Version 10 – 15 | 158 – 272 바이트 | **1.1 – 1.9 KB/sec** | 0% (1단계 시스토매틱) |
| **⚡ Ultra Speed** | 10 FPS | Version 10 – 15 | 158 – 272 바이트 | **1.6 – 2.72 KB/sec** | 0% (1단계 시스토매틱) |

*참고: 1단계 (Seed $1 \dots K$)는 광학 환경이 깨끗할 경우 0% 오버헤드로 완벽 복원됩니다. 2단계 (Seed $> K$)는 프레임 유실, 렌즈 블러, 손떨림이 발생하는 환경에서 무제한 파운틴 복구(~5–10% 오버헤드)를 제공합니다.*

---

## 📡 프로토콜 및 패킷 포맷 (Protocol & Packet Format)

데이터 페이로드는 $L$ 바이트 크기의 $K$개 소스 블록으로 분할됩니다. 각 QR 코드 프레임은 경량 바이너리 헤더와 XOR 인코딩된 블록 페이로드 바이트로 구성된 압축 패킷을 포함합니다.

### 바이너리 헤더 구조 (Binary Header Structure)

| 오프셋 (바이트) | 필드 | 타입 | 설명 |
|---|---|---|---|
| `0..3` | `Seed` | uint32 (Big-Endian) | Mulberry32 PRNG가 차수 분포 및 블록 인덱스를 샘플링하는 데 사용하는 시드 (Seed $1..K$ = 시스토매틱 직송 블록). |
| `4..5` | `K` | uint16 (Big-Endian) | 페이로드의 전체 소스 블록 개수. |
| `6..7` | `L` | uint16 (Big-Endian) | 소스 블록 1개당 바이트 길이. |
| `8` | `Flags` | uint8 | 플래그 비트: `0x01` = 바이너리 파일 여부 (`0` = 텍스트, `1` = 파일), `0x02` = 파일명 헤더 포함 여부, `0x04` = 시스토매틱 프레임 여부 ($s \le K$). |
| `9` | `Filename Length` | uint8 (선택사항) | 파일명 UTF-8 문자열의 바이트 길이 $N$ (`Flags & 0x02` 설정 시 포함). |
| `10..9+N` | `Filename` | String (선택사항) | UTF-8 인코딩된 원본 파일명 (`Flags & 0x02` 설정 시 포함). |
| `HeaderLen..` | `Payload` | Bytes ($L$ 바이트) | 본 파운틴 드롭릿에 대해 샘플링된 소스 블록들의 XOR 연산 합 (시스토매틱 프레임의 경우 해당 블록 데이터 직접 포함). |

---

## 📁 저장소 구조 (Repository Structure)

```
.
├── server.py             # SSL 래퍼가 포함된 간이 Python HTTPS 서버
├── transmitter.html      # HTML/JS 송신기 UI 및 QR 코드 생성기
├── receiver.html         # HTML/JS 수신기 UI 및 실시간 카메라 스캐너
├── lt_engine.js          # LT Code 파운틴 엔진 (PRNG, Soliton 분포, BP 디코더)
├── easy.qrcode.min.js    # 동적 QR 코드 렌더링용 로컬 JS 라이브러리
├── certs/
│   ├── cert.pem          # 자체 서명 TLS 인증서
│   └── key.pem           # TLS 개인키
└── docs/
    └── adr/              # 아키텍처 결정 기록 (ADR)
```

---

## 📑 아키텍처 결정 기록 (ADRs)

본 프로젝트의 주요 기술적 의사결정은 ADR로 문서화되어 있습니다:

* [ADR 0001: 애니메이션 QR 코드 프레임 스트리밍 프로토콜 및 LT 파운틴 엔진](docs/adr/0001-animated-qr-code-frame-streaming.md)
* [ADR 0002: 바이너리 헤더 패킹 및 순수 8비트 바이트 QR 패킷 스키마](docs/adr/0002-chunking-and-json-metadata-packet-schema.md)
* [ADR 0003: 미디어 접근을 위한 HTTPS 요구사항 및 로컬 TLS 인증서](docs/adr/0003-https-requirement-and-local-tls-certificates.md)
* [ADR 0004: 실시간 비순차적 프레임 재조립 및 진행 상황 추적](docs/adr/0004-real-time-out-of-order-frame-assembly.md)

---

## 🔒 보안 및 성능 고려사항 (Security & Performance)

* **에어갭 무결성**: 송신기와 수신기 간에 어떠한 네트워크 소켓이나 데이터 채널도 형성되지 않습니다. 모든 데이터는 물리적 에어갭을 넘어 광학적으로만 전달됩니다.
* **HTTPS 환경**: 최신 웹 브라우저의 카메라 API 접근 정책(`navigator.mediaDevices.getUserMedia`)을 충족하기 위해 `./certs/` 내의 로컬 자체 서명 인증서가 필요합니다.
* **전송 속도 vs 안정성**: QR 밀도를 Version 15($77 \times 77$)로 제한하고 7 FPS를 모바일 최적 속도로 적용하여 셔터 포착 안정성을 대폭 향상했습니다. Error Correction Level M 적용으로 렌즈 블러, 왜곡, 조명 반사 시에도 15%의 복원 능력을 제공하며 초당 1.1~2.7 KB/sec 전송 속도를 달성합니다.

---

## 📄 라이선스 (License)

본 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.
