C.W.K.
Stream
Lesson 02 of 04 · published

Content-Addressed Id

~13 min · content-addressed, chunk-id, hashing, provenance

Level 0불 꺼진 심지
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"chunk 한테 이름을 주지 마. chunk 의 내용이 스스로 이름 짓게 둬."

공식

Lantern chunk id 는 배정되지 않아 — 계산돼. 문서 자체의 content 해시, 조각의 시작·끝 문자 offset, 그걸 만든 chunking profile 의 id 를 잡아. 이어 붙이고, 결과를 해시하고, 앞 32 개 16진 문자를 남겨. 그 문자열이 chunk id 야. 모든 입력이 내용 자체에 대한 사실이라, 출력이 DB 가 삽입 시점에 붙인 라벨이 아니라 내용의 지문이야.

모든 재료가 거기 있는 이유

공식의 각 부분이 자리를 벌어:

  • doc_sha256어느 문서인가, 파일명이 아니라 내용으로 식별돼. 바이트 동일한 두 파일은 여기서 같은 문서고, 이름 바뀐 파일도 여전히 같은 문서고, 편집된 파일은 다른 문서야.
  • char_startchar_end — 그 문서의 어느 조각인가, 디코드된 텍스트로의 문자 offset 으로. 정확한 범위를 고정해.
  • profile_id어느 chunking 규칙 아래인가. 다른 profile 로 잘린 같은 범위는 다른 chunk 고, 다른 id 를 받아야 해.

공식의 어떤 것도 chunk 가 언제 삽입됐는지 어디 테이블에 앉는지 안 말해. 그 누락이 핵심 전부야: 위치와 시간의 흔적을 다 지우면, 남는 건 내용이 바뀔 때만 바뀔 수 있어.

공짜로 얻는 것

content-addressing 이 추가 장부 없이 속성 셋을 한 번에 건네:

  • 안정성: 같은 profile 아래 같은 텍스트를 다시 수집하면 id 가 바이트 동일해 — 재구축을 넘어, 기계를 넘어.
  • 중복 제거: 동일 내용은 같은 id 로 계산돼, 여럿 대신 자연히 하나로 접혀.
  • 검증 가능성: 내용이 주어지면, 누구나 id 를 재계산해 맞는지 확인할 수 있어 — id 는 배정될 뿐 아니라 확인 가능해.

이게 Git 이 commit 과 blob 을 이름 짓고, 컨테이너 시스템이 이미지 layer 를 이름 짓는 데 쓰는 바로 그 트릭이야: 주소가 내용의 해시야.

해시를 자르는 건 의도적이고 안전한 거래야. 완전한 SHA-256 은 16진 64 자고, Lantern 은 32 자를 남겨. 그래도 128 비트 주소 공간이야 — 진짜 코퍼스에서 다른 두 chunk 가 충돌하는 게 천문학적으로 불가능할 만큼 충분히 넘쳐. 이론적 충돌 여유 조금을 더 짧고 다루기 쉬운 id 와 맞바꿔. 왜 자르는지 알고, 이 규모에서 안전하단 걸 알아.

id 는 온전한 provenance 와 함께 여행해

chunk id 는 절대 혼자 안 다녀. 모든 결과가 provenance 번들 전체를 지녀: 코퍼스, 문서 경로, 문서 해시, 문자 offset, chunk 해시, profile. id 는 내구성 있는 손잡이고, 번들은 조각을 처음부터 다시 찾고, 다시 검증하고, 다시 파생하는 데 필요한 전부야. 함께면 결과가 몇 년 뒤, 네가 처음 검색을 돌렸을 땐 존재하지도 않던 기계에서, 완전한 확신으로 가리킬 수 있는 게 돼.

Code

chunk id 는 지문, 배정이 아니라 계산돼·python
import hashlib

def chunk_id(doc_sha256: str, char_start: int, char_end: int, profile_id: str) -> str:
    # Every input is a property of the CONTENT, never of insertion time or place.
    payload = f"{doc_sha256}:{char_start}:{char_end}:{profile_id}"
    return hashlib.sha256(payload.encode("utf-8")).hexdigest()[:32]

# Same content + same profile -> same id, forever, everywhere:
a = chunk_id("d41d8c...", 4120, 4229, "md-para-v1")
b = chunk_id("d41d8c...", 4120, 4229, "md-para-v1")
assert a == b            # deterministic

# Change the chunking rules -> a genuinely different chunk -> a different id:
c = chunk_id("d41d8c...", 4120, 4229, "md-para-v2")
assert c != a            # profile is part of identity

External links

Exercise

네 세계의 뭔가에 대한 content-addressed id 를 설계해 — 사진, 노트, 레코드. 그걸 유일하게 그것이게 하는 속성들을 나열해(언제 저장했는지나 어느 행에 내려앉았는지 말고). 공식을 써: 어느 필드의 해시? 그다음 머릿속에서 테스트해 — 그 항목을 다른 기계로 복사하면, 네 공식이 같은 id 를 낼까? 아니라면, 제거해야 할 위치나 시간 필드를 넣은 거야.
Hint
실패 모드는 '혹시 몰라' 타임스탬프, 파일명, auto id 를 슬쩍 넣는 거야. 그중 하나하나가 이식성을 깨. content-addressed id 는 내용만으로 계산 가능해야 하고, 그래야 독립된 두 기계가 같은 답에 닿아.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.