Bencode

**Bencode**('비인코드'처럼 발음)는 P2P 파일 공유 시스템인 비트토렌트에서 느슨하게 구조화된 데이터를 저장하고 전송하는 데 사용되는 인코딩 방식이다.

다음과 같은 네 가지 유형의 값을 지원한다.
* 바이트 문자열
* 정수
* 리스트 (배열)
* 사전 (연관 배열)

Bencode는 토렌트 파일에서 가장 흔히 사용되며, 비트토렌트 사양의 일부이다. 이러한 메타데이터 파일은 단순히 bencode로 인코딩된 사전이다.

Bencode는 간단하며 (숫자가 10진수 텍스트로 인코딩되기 때문에) 엔디언의 영향을 받지 않아 비트토렌트와 같은 크로스 플랫폼 애플리케이션에 중요하다. 또한 애플리케이션이 예상치 못한 사전 키를 무시하는 한 상당히 유연하여 호환성 문제 없이 새로운 키를 추가할 수 있다.

## 인코딩 알고리즘

Bencode는 ASCII 문자를 구분 기호와 숫자로 사용하여 데이터 구조를 간단하고 압축된 형식으로 인코딩한다.

* **정수**는 `i<base10 integer>e`로 인코딩된다.
** 정수는 10진수로 인코딩되며 음수일 수 있다 (선행 하이픈-마이너스로 표시).
** 정수가 0인 경우를 제외하고 선행 0은 허용되지 않는다.
** 예시:
*** 0은 `i0e`로 인코딩된다.
*** 숫자 42는 `i42e`로 인코딩된다.
*** 음수 42는 `i-42e`로 인코딩된다.

* **바이트 문자열**은 `<length>:<contents>`로 인코딩된다.
** 길이는 문자열의 바이트 수이며, 10진수로 인코딩된다.
** 콜론(`:`)은 길이와 내용을 구분한다.
** 내용은 길이에 의해 지정된 정확한 바이트 수이다.
** 내용은 바이트 시퀀스이다 (텍스트 문자열이 아님).
** 예시:
*** 빈 문자열은 `0:`으로 인코딩된다.
*** 문자열 "bencode"는 `7:bencode`로 인코딩된다.

* **리스트**는 `l<elements>e`로 인코딩된다.
** `l`로 시작하여 `e`로 끝난다.
** 요소는 구분 기호 없이 연결된 bencode 값이다.
** 예시:
*** 빈 리스트는 `le`로 인코딩된다.
*** 문자열 "bencode"와 정수 -20을 포함하는 리스트는 `l7:bencodei-20ee`로 인코딩된다.

* **사전**은 `d<pairs>e`로 인코딩된다.
** `d`로 시작하여 `e`로 끝난다.
** 키-값 쌍을 포함한다.
** 키는 바이트 문자열이며 사전순으로 나타나야 한다.
** 각 키 뒤에는 그 값이 바로 오며, 값은 어떤 bencode 유형이든 될 수 있다.
** 예시:
*** 빈 사전은 `de`로 인코딩된다.
*** 키 "wiki" → "bencode" 및 "meaning" → 42를 가진 사전은 `d7:meaningi42e4:wiki7:bencodee`로 인코딩된다.

리스트와 사전 내에 저장되는 값의 유형에는 제한이 없다. 다른 리스트와 사전을 포함할 수 있어 임의로 복잡한 데이터 구조를 만들 수 있다.

Bencode는 텍스트 저장을 위한 특정 문자 인코딩이 아닌 바이트 문자열 유형만 정의한다. Bencode를 사용하는 다운스트림 애플리케이션 및 데이터 형식 사양은 텍스트를 bencode 바이트 문자열로 인코딩하는 데 선호하는 인코딩을 자유롭게 지정할 수 있다.

### Bencode의 오류 유형

형식이 잘못된 bencode가 가질 수 있는 오류 목록은 다음과 같다.

# 널 루트 값.
# 단일하지 않은 루트 항목.
# 잘못된 유형 발견 ('i', 'l', 'd' 또는 '0'-'9'가 아닌 문자).
# 'i', 'l', 'd' 유형에 대한 'e' 종결자 누락.
# **정수 오류:**
## 숫자가 아닌 문자 포함.
## 선행 0이 있음.
## 음수 0.
# **바이트 문자열 오류:**
## 음수 길이.
## 길이에 ':'이 뒤따르지 않음.
## 문자열을 완료하기 전에 예상치 못한 EOF.
## 길이가 바이트 단위가 아닌 코드포인트(문자) 단위로 지정됨.
# **사전 오류:**
## 키가 문자열이 아님.
## 중복 키.
## 키가 정렬되지 않음.
## 키가 사전순이 아닌 특정 문자 인코딩의 코드포인트 순서로 잘못 정렬됨.
## 키에 대한 값 누락.

## 기능
Bencode는 몇 가지 고유한 속성을 가진 매우 특수화된 이진 코딩 방식이다.

* 각 가능한 (복잡한) 값에 대해 단 하나의 유효한 bencode만 존재한다. 즉, 값과 해당 인코딩 사이에 전단사 함수가 존재한다. 이는 애플리케이션이 bencode 값을 인코딩된 형태로 비교할 수 있게 하여 값을 디코딩할 필요를 없애는 장점이 있다.
* Bencode는 JSON 및 YAML과 같은 데이터 언어와 유사한 목적을 수행하며, 복잡하지만 느슨하게 구조화된 데이터를 플랫폼 독립적인 방식으로 저장할 수 있게 한다. 이는 복잡한 데이터를 위한 선형 메모리 저장을 가능하게 한다.

## 단점

Bencode는 사람이 읽을 수 있는 인코딩 형식으로 간주되지 않는다. BE 코드 그룹은 수동으로 디코딩할 수 있지만, bencode 값에는 종종 이진 데이터가 포함되어 있어 손으로 디코딩하면 오류가 발생하기 쉽다. bencode 파일에는 이진 데이터가 포함되어 있으므로 텍스트 편집기에서 bencode 파일을 편집하는 것은 안전하지 않으며, 헥사 편집기 또는 특수 bencode 편집기 도구를 사용해야 한다.

Bencode는 리스트 또는 사전 구조의 크기에 대한 메타데이터를 저장하지 않으므로 특정 필드에 도달하려면 모든 선행 요소를 순차적으로 읽어야 한다. 따라서 bencode는 필드에 대한 임의 접근이 필요한 대규모 데이터 구조에는 적합하지 않을 수 있다.

## 같이 보기
* 정규 S-표현식
* 비트토렌트

## 각주

## 외부 링크
* Bencoding 사양
* File_Bittorrent2 - 또 다른 PHP Bencode/decode 구현
* Python으로 구현된 오리지널 BitTorrent 독립형 패키지
* Torrent File Editor BEncode 파일을 위한 크로스 플랫폼 GUI 편집기
* bencode-tools - bencode 데이터를 조작하기 위한 C 라이브러리 및 Python의 bencode 메시지용 XML 스키마와 유사한 유효성 검사기
* Bento - Elixir용 Bencode 라이브러리
* Beecoder - java.io.* 스트림 API를 사용하여 Java에서 "B-encode" 데이터 형식을 디/인코딩하는 파일 스트림 파서
* Java의 Bencode 파싱
* Scala의 Bencode 라이브러리
* C의 Bencode 파싱
* CPAN에 수많은 Perl 구현이 있다

분류:비트토렌트
분류:데이터 직렬화 포맷