화면과 카메라만으로 파일을 옮기는 브라우저 PoC
브라우저에서 fountain-coded animated QR로 네트워크 없이 파일을 전송하는 프로젝트
TL;DR
Decimen은 브라우저 기반으로 화면과 카메라만으로 파일을 전송하는 PoC로, Luby transform 기반 fountain 코드를 사용해 프레임 손실을 견딥니다. 송신은 animated QR 스트림을 표시하고 수신은 WASM(zxing-cpp) 디코더로 프레임을 해독해 충분한 서로 다른 프레임을 모으면 원본을 복원한 뒤 SHA-256으로 무결성을 확인합니다. standalone HTML 산출물과 호스팅 사이트를 모두 제공해 서버 없이도 배포 가능하지만 모바일에서는 HTTPS로 서빙하거나 호스팅 사이트의 오프라인 모드를 이용해야 카메라 권한을 확보할 수 있습니다.
해결 문제
네트워크가 없거나 네트워크 연결을 신뢰할 수 없는 상황에서 파일을 교환해야 하는 문제를 해결합니다. 화면·카메라라는 일방향 물리 채널에서는 수신측이 재전송을 요구할 수 없는데, fountain 코드를 도입해 프레임 손실을 시간 지연으로만 흡수하고 전송의 정확성을 유지합니다. 이 접근은 앱 설치나 네트워크 설정 권한이 제한된 환경에서 간단히 파일을 옮겨야 할 때 실용적인 대안이 됩니다.
주요 기능
- 화면과 카메라만으로 파일 전송을 구현해 네트워크·페어링·권한 없이 데이터를 옮길 수 있습니다.
- fountain(LT) 코드를 사용해 프레임 손실을 허용하면서 재전송 없이 수신 측에서 원본 파일을 복원합니다.
- WASM(zxing-cpp) 기반 QR 디코더와 설정 가능한 tx fps·bytes/frame·decode worker 수로 다양한 디바이스 조합에 맞춰 튜닝할 수 있습니다.
차별점
- 브라우저 기반이고 standalone HTML 산출물을 제공해 서버 없이도 송신 페이지 또는 수신 페이지를 바로 전달해 사용할 수 있습니다. build:standalone 모드는 디코더 WASM과 워커를 인라인해 파일·USB·이메일로 배포 후 즉시 실행 가능한 단일 파일을 생성합니다. 수신 페이지의 보안 컨텍스트 제한(iOS Safari/Android Chrome의 file:// 카메라 권한 문제)을 문서에 명확히 다루고 있어 실무 적용 시 주의할 점이 분명합니다.
- fountain 코드와 QR 레이어를 함께 설계해 프레임 손실(erasures)과 프레임 내 비트 오류(corruption)를 역할 분담으로 처리합니다. QR의 ECC 레벨을 L로 낮춰 각 프레임의 용량을 최대화하고, 상위의 fountain 계층에서 누락 프레임을 보완하도록 최적화하여 전체 throughput을 끌어올립니다. 이 설계는 고밀도 프레임과 고주사율 송신 환경에서 특히 좋은 손실 대비 성능을 냅니다.
- 실제 브라우저 엔진 차이(V8 vs JavaScriptCore)의 수치 연산 불일치와 플랫폼별 카메라 프레임 레이트 특성을 해결한 실전 노하우를 포함하고 있습니다. deterministic IEEE-754 기반 로그 구현, getUserMedia의 frameRate exact 요구, requestVideoFrameCallback 세대 카운터 같은 하드닝이 빌트인되어 있어 다른 PoC보다 현장 적용 가능성이 높습니다. 또한 데모 모드로 파일 선택을 잠가 공개 시연에서의 보안·프라이버시 우려를 낮추는 옵션을 제공합니다.
지금 주목받는 이유
네트워크 없는 데이터 이동에 대한 관심이 커진 가운데 화면-카메라 채널은 물리적으로 분리된 디바이스 간 데이터 교환을 간편하게 해 줄 수 있습니다. Decimen은 브라우저만으로 구현되고 standalone 배포를 제공해 접근성이 높고, 실사용을 고려한 튜닝 파라미터와 플랫폼별 페널티를 문서로 담아 현장 적용 사례가 만들기 쉬운 편입니다. GitHub에 공개된 PoC와 3.6k 스타가 모여 사용자 실험과 파생 프로젝트를 촉진하는 환경을 조성하고 있습니다.
어떻게 동작하는가
송신 쪽은 파일을 고정 크기 블록으로 나누고 각 프레임에 블록 서브셋의 XOR를 싣는 animated QR 스트림을 지속해서 갱신합니다. 각 프레임에는 세션 id와 시퀀스 번호, 블록·파일 메타데이터를 담는 20바이트 헤더가 포함되어 수신 측이 스트림을 중간에서 잠금하고 어떤 프레임을 모아야 할지 파악하게 합니다. 수신 쪽은 zxing-cpp를 WASM 워커로 실행해 QR를 디코딩하고, 충분한 서로 다른 프레임을 수집하면 Luby transform 기반의 peeling 프로세스로 원본을 복원한 뒤 SHA-256으로 무결성을 검증합니다.
사용 사례
- 온라인 연결이 불가능하거나 보안 정책으로 네트워크 파일 전송이 차단된 현장 장비에서 파일을 전달할 때 유용합니다. 송신 기기에서 브라우저로 파일을 띄워 수신 기기 카메라로 받아 저장하는 방식은 별도 설치·페어링 없이 즉각적인 전달 경로를 마련합니다. 데모·전시·워크숍에서 대역폭이나 네트워크 설정에 신경 쓰지 않고 자료를 배포하는 상황에도 적합합니다.
- 임시 오프라인 배포나 긴급 상황에서 신속히 작은 자원을 교환해야 할 때 실무적으로 활용할 수 있습니다. 단, 전송 내용은 암호화되지 않으므로 민감 데이터 전송에는 적합하지 않습니다. 대신 공개 자료, 이미지, 텍스트 스니펫, 설정 파일 같은 비밀성이 낮은 페이로드에 적합합니다.
시작하기
로컬에서 실행하려면 레포지토리를 클론한 뒤 npm install로 의존성을 설치한 후 npm run dev로 개발 서버를 띄우면 됩니다. 송신 페이지는 /send/에서 파일을 선택해 화면을 최대 밝기로 유지하고, 수신 기기는 /receive/ 페이지에서 카메라 권한을 허용해 화면을 가리면 복호화가 진행됩니다. 배포용으로는 npm run build:standalone으로 생성된 decimen-sender.html과 decimen-receiver.html을 전달해 서버 없이 실행할 수 있으나, 모바일에서 카메라 권한을 보장하려면 HTTPS로 서빙하는 것이 권장됩니다.
요구사항
- 브라우저: getUserMedia와 requestVideoFrameCallback을 지원하는 최신 모바일 브라우저 (데스크톱도 동작하나 수신은 주로 휴대폰 권장)
- 적절한 화면 밝기와 카메라 초점 유지, 근거리에서의 충분한 해상도(높은 bytes/frame 설정 시)
- 빌드 러ntime: Node.js 및 npm (프로젝트 로컬 개발과 빌드용)
벤치마크
| 벤치마크 | 지표 | 값 | 비교 |
|---|---|---|---|
| measured goodput | KB/s | 129.2 KB/s | — |
| parent experiment ceiling | KB/s | 128 KB/s handheld, 186 KB/s propped | — |
이미지 분석

3.6k
Stars
417
Forks
+213
Trending
1
조회수
관련 토론
아직 관련 토론이 없습니다.
댓글
댓글을 작성하려면 로그인이 필요합니다.