메타데이터 비교

같은 파일인데 info hash는 왜 달라질까요 | 토렌트씨

파일 내용이 같아도 토렌트의 이름이나 조각 크기를 바꾸면 v1 info hash가 달라질 수 있습니다. 600 KiB 표본을 직접 만들어 다섯 조건을 비교하고, 같은 해시와 다른 해시가 각각 무엇을 뜻하는지 살펴봅니다.

파일의 해시와 info hash는 무엇이 다른가요?

파일 해시는 내용 바이트를, v1 info hash는 이름과 분할 정보까지 포함한 info 사전을 요약합니다. 따라서 같은 파일 내용을 두 방식으로 포장하면 내용 해시는 같아도 info hash는 달라질 수 있습니다. 자료 목록에서 중복 여부를 확인할 때 두 값을 구별해야 하는 이유입니다.

BitTorrent v1의 info hash는 파일 본문 전체를 바로 SHA-1에 넣은 값이 아닙니다. 파일명·길이·조각 크기·조각별 해시 등을 담은 info 사전을 bencode로 직렬화한 뒤 SHA-1으로 계산합니다. 이 구조 때문에 파일 내용이 같아도 info 안의 다른 값이 바뀌면 결과가 달라질 수 있습니다.

정의와 단일 파일 구조: BEP 3 — metainfo files와 info_hash.

파일 내용의 비교

표본의 614,400바이트 → SHA-256
이번 실험에서 내용이 같은지 확인하는 기준으로 사용했습니다.

v1 토렌트의 비교

이름·길이·분할 정보가 든 info → bencode → SHA-1
프로토콜의 토렌트 식별값을 계산했습니다.

서로 다른 대상을 해시했으므로 두 값이 바뀌는 조건도 같을 필요가 없습니다. 이를 추상적인 설명으로 끝내지 않고 한 조건씩 바꿔 확인했습니다.

600 KiB 표본을 어떻게 만들었나요?

2026-10-28, Windows의 Python 3.12.14에서 표준 라이브러리만 사용했습니다. bytes(range(256)) * 2400으로 0~255 바이트를 반복해 614,400바이트를 만들었습니다. 단일 파일 이름은 sample.bin, 기준 조각 크기는 262,144바이트로 정했습니다.

  • 각 조각을 SHA-1으로 계산한 20바이트 값을 순서대로 붙였습니다.
  • length, name, piece length, pieces를 info 사전에 넣었습니다.
  • 사전 키는 바이트 순서로 정렬하고, 정수에는 선행 0을 붙이지 않고 bencode로 인코딩했습니다.
  • info 바깥 주석의 영향을 보기 위해 별도의 comment 값을 함께 감싼 메타데이터도 계산했습니다.

인코딩 규칙과 조각 해시: BEP 3 — bencoding 및 pieces. 표본 생성식과 실제 바이트 길이는 원자료 JSON에 있습니다.

이것은 로컬 메타데이터 계산입니다. 배포용 토렌트를 등록하거나 트래커·피어에 접속하지 않았습니다. 영상 파일, 실제 게시물, 다운로드 속도는 실험 대상이 아닙니다.

어떤 조건에서 파일은 같고 식별값은 달라졌나요?

info.name 변경과 조각 크기 변경에서 내용 SHA-256은 같고 info hash만 달라졌습니다. 기준을 포함한 다섯 조건의 결과는 아래와 같습니다. ‘같음’과 ‘달라짐’은 첫 행과의 비교이며, 표에는 해시 앞 12자리, 원자료에는 전체 값을 남겼습니다.

단일 파일 v1 메타데이터 · 각 행은 기준 표본에서 한 조건만 변경
조건내용 SHA-256v1 info hash
기준 표본같음기준값3eb4c823ece8…
바깥 주석만 변경같음같음3eb4c823ece8…
info.name만 변경같음달라짐f84fb6c26cd7…
조각 크기만 변경같음달라짐e468b4f7d494…
내용 1바이트 변경달라짐달라짐63a76e0a7e3f…

결과 원본: 5개 조건의 입력·전체 해시·조각별 해시.

1. 주석만 바꾸면 어느 해시가 달라지나요?

바깥 주석만 바꾼 경우에는 메타데이터 전체의 SHA-256만 달라지고 info hash는 유지됐습니다. 주석은 info 사전 밖에 있으므로 info 바이트를 해시하는 계산에 포함되지 않았습니다.

  • 변경한 입력: comment의 baseline → revised note.
  • 유지된 입력: 파일 내용과 info 사전의 모든 필드.
  • 판단: 같은 info hash라도 이를 감싼 메타데이터 전체가 같다는 뜻은 아닙니다.

2. 이름만 바꿔도 달라지는 이유는 무엇인가요?

info.name은 해시 입력에 포함되므로 이름 변경만으로도 info hash가 달라졌습니다. 이 비교에서 파일 내용의 SHA-256은 유지됐고, 바이트 내용이나 조각 길이를 수정하지 않았습니다.

  • 변경한 입력: info.name의 sample.bin → renamed.bin.
  • 유지된 입력: 614,400바이트의 내용과 262,144바이트 조각 크기.
  • 판단: 게시판 글 제목이나 마그넷의 표시 이름을 바꾼 실험과는 다릅니다.

3. 내용 한 바이트를 바꾸면 어디까지 달라지나요?

내용 한 바이트를 바꾸자 내용 SHA-256, 첫 조각의 SHA-1, info hash가 모두 달라졌습니다. 이름과 파일 길이는 그대로였으므로 목록에 보이는 이름과 크기만으로는 이 차이를 구분할 수 없었습니다.

  • 변경한 위치: 0부터 센 42번 바이트, 값 42 → 43.
  • 달라진 조각: 변경 위치가 속한 첫 번째 조각.
  • 유지된 조각: 두 번째와 세 번째 조각의 SHA-1.

조각 크기를 바꾸면 무엇이 달라지나요?

같은 614,400바이트를 256 KiB와 512 KiB로 나눠 봤습니다. 마지막 조각은 남은 길이만큼 사용되므로, 각각 3조각과 2조각이 됐습니다.

256 KiB: 262,144 + 262,144 + 90,112

3개의 SHA-1 → pieces 필드 60바이트

512 KiB: 524,288 + 90,112

2개의 SHA-1 → pieces 필드 40바이트

파일 본문을 건드리지 않았는데도 piece length와 pieces가 모두 달라졌습니다. 두 값이 info에 들어 있으므로 info hash도 달라졌습니다. 다른 info hash를 봤다는 사실만으로 영상의 장면이나 화질이 다르다고 결론 낼 수 없는 이유가 여기에 있습니다.

고정 길이 조각과 마지막 조각의 규칙: BEP 3 — piece length 및 pieces. 이번 조각 길이는 실제 계산 기록의 piece_sizes에 있습니다.

표본은 256바이트 패턴이 반복되므로 같은 길이의 앞쪽 조각들은 해시도 같습니다. 이는 표본 설계의 결과이며 일반 영상 파일의 조각이 모두 같다는 뜻이 아닙니다. 또한 조각 수가 줄었다는 사실만으로 다운로드가 빨라졌다고 말할 수 없습니다. 전송은 측정하지 않았습니다.

마그넷의 표시 이름도 info hash에 들어가나요?

마그넷의 dn은 표시 이름이며, 그 값을 바꾸는 것 자체가 info 사전을 수정하지는 않습니다. BEP 9에서 v1 토렌트를 식별하는 값은 xt=urn:btih: 뒤의 info hash입니다. dn과 info.name은 이름처럼 보이지만 역할이 다른 필드입니다.

마그넷 필드 정의: BEP 9 — magnet URI format. 이 글은 실행 가능한 다운로드 링크 대신 필드 이름만 설명합니다.

이 점은 앞의 이름 변경 실험과도 구분해야 합니다. 실험에서 바꾼 것은 info.name이었고, 마그넷의 dn만 고치는 것은 info 사전을 수정하는 일이 아닙니다. 화면 제목, 마그넷의 표시 이름, info 안의 이름을 모두 ‘파일명’이라고 부르면 서로 다른 결과를 혼동하기 쉽습니다.

v2는 범위 밖입니다. BEP 52의 v2는 SHA-256 기반 구조를 사용합니다. 여기의 SHA-1 계산과 40자리 v1 해시를 모든 토렌트에 공통인 규칙으로 적용하지 않습니다. BEP 52 — BitTorrent v2

토렌트씨 목록에서는 어떤 순서로 비교하나요?

이름의 종류, 비교 대상, 아직 확인하지 않은 범위를 순서대로 기록합니다. 같은 작품을 찾는 일과 같은 바이트의 파일을 찾는 일은 다르므로, 토렌트씨 목록에서 얻은 정보가 어느 질문에 답하는지 먼저 정합니다.

  1. 어떤 이름을 보고 있는지: 게시물 제목인지, 마그넷 표시 이름인지, 메타데이터의 이름인지 구분합니다.
  2. 무엇의 동일성을 묻는지: 같은 작품, 같은 파일 바이트, 같은 v1 info hash는 별개의 질문입니다. 작품명만 같은 자료를 동일 파일로 단정하지 않습니다.
  3. 확인할 수 없는 부분은 무엇인지: 목록만 읽었다면 실제 파일 내용은 아직 확인하지 않은 것입니다. info hash가 있다는 사실도 배포 권한이나 파일 안전성을 증명하지 않습니다.

이번 비교의 결론은 “해시 하나면 모든 것을 알 수 있다”가 아닙니다. 서로 다른 info hash가 나오는 이유를 파일 내용의 차이 하나로 좁히지 말자는 것입니다. 이름과 조각 크기만 달리해도 다른 결과가 나왔기 때문에, 중복 자료를 판단할 때 비교 대상을 먼저 정해야 합니다.

이 실험은 한 종류의 결정적 표본과 v1 단일 파일 사전으로 범위를 제한했습니다. 여러 파일을 묶은 토렌트, v2·하이브리드, 실제 클라이언트의 표시 방식과 전송 성능은 검증하지 않았습니다.

직접 확인할 수 있는 자료

JSON의 info_bencoded_hex를 바이트로 되돌려 SHA-1을 계산하면 공개한 info hash와 대조할 수 있습니다.

import hashlib, json
with open("infohash-comparison.json", encoding="utf-8") as source:
    data = json.load(source)
for case in data["cases"]:
    encoded = bytes.fromhex(case["info_bencoded_hex"])
    actual = hashlib.sha1(encoded).hexdigest()
    assert actual == case["infohash_v1"]
    print(case["id"], actual)
블로그 목록으로 돌아가기 →