OPEN HYPER STEP
← 목록으로 (math)
MATH · 24 / 45
math
CHAPTER 24 / 45
읽기 약 2
FUNCTION

해시 함수: 빠른 검색의 수학


핵심 개념

해시 함수 원리·충돌·체이닝 — HashMap의 O(1) 검색·bcrypt 비밀번호·체크섬 무결성.

본문

해시 함수 = 입력 → 고정 크기 출력

📋 코드 (11줄)
입력 (가변 크기) ──┐
                 ↓
              해시 함수
                 ↓
입력 (고정 크기) ──┘  (예: 256비트)

특징:
1. 결정적 (Deterministic): 같은 입력 → 항상 같은 출력
2. 균등 분포 (Uniform): 비슷한 입력도 다른 출력
3. 단방향 (One-way): 출력 → 입력 역산 불가
4. 빠름: O(1) 또는 O(n)

Python 해시

PYTHON📋 코드 (19줄)
# 내장 hash() — 임의의 정수
print(hash("Hello"))   # 5235312840681...
print(hash(42))        # 42
print(hash((1, 2, 3))) # -2962840714241...
print(hash([1, 2, 3])) # TypeError — list는 mutable이라 hashable 아님


# 같은 입력 → 같은 출력
print(hash("Hello") == hash("Hello"))  # True


# 단, Python의 hash()는 보안용 아님 (단순 분산용)
# 보안 필요 시 hashlib 사용
import hashlib

m = hashlib.sha256()
m.update(b"Hello")
print(m.hexdigest())
# 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

HashMap 동작 원리

PYTHON📋 코드 (34줄)
# 직접 HashMap 구현 — 체이닝 방식

class HashMap:
    def __init__(self, capacity=10):
        self.capacity = capacity
        self.buckets = [[] for _ in range(capacity)]

    def _hash(self, key):
        # 키를 0~capacity-1 정수로 변환
        return hash(key) % self.capacity

    def put(self, key, value):
        bucket = self.buckets[self._hash(key)]
        for i, (k, v) in enumerate(bucket):
            if k == key:
                bucket[i] = (key, value)  # 업데이트
                return
        bucket.append((key, value))  # 신규

    def get(self, key):
        bucket = self.buckets[self._hash(key)]
        for k, v in bucket:
            if k == key:
                return v
        raise KeyError(key)


m = HashMap()
m.put("Alice", 30)
m.put("Bob", 25)
m.put("Charlie", 35)

print(m.get("Alice"))  # 30
print(m.get("Bob"))    # 25

충돌 (Collision)

PYTHON📋 코드 (17줄)
# 두 키가 같은 버킷에 매핑 = 충돌
# 비둘기집 원리: 입력 가능 수 > 버킷 수면 반드시 충돌

# 충돌 시뮬레이션
m = HashMap(capacity=3)
m.put("Alice", 30)
m.put("Bob", 25)
m.put("Charlie", 35)
m.put("Dave", 40)
m.put("Eve", 45)

# 버킷 분포 확인
for i, bucket in enumerate(m.buckets):
    print(f"버킷 {i}: {bucket}")
# 버킷 0: [('Bob', 25), ('Eve', 45)]      ← 충돌 (체이닝)
# 버킷 1: [('Alice', 30)]
# 버킷 2: [('Charlie', 35), ('Dave', 40)] ← 충돌

충돌 해결 방법

📋 코드 (10줄)
1. 체이닝 (Separate Chaining)
   각 버킷에 연결 리스트 → Python dict의 기본 구조

2. 개방 주소법 (Open Addressing)
   - Linear Probing: 다음 빈 칸 탐색
   - Quadratic Probing: i² 만큼 점프
   - Double Hashing: 두 번째 해시 함수

3. 로빈 후드 해싱 (Robin Hood Hashing)
   가까운 것은 가까이, 멀리 떨어진 것에 양보

실전 — bcrypt 비밀번호 해싱

PYTHON📋 코드 (24줄)
# pip install bcrypt
import bcrypt

# 회원가입 시
password = b"my_secret_password"
salt = bcrypt.gensalt(rounds=12)  # 솔트 생성
hashed = bcrypt.hashpw(password, salt)
print(hashed)
# b'$2b$12$wIvK0iTXrh7L...'


# 로그인 시
def verify_password(input_pw, stored_hash):
    return bcrypt.checkpw(input_pw.encode(), stored_hash)


print(verify_password("my_secret_password", hashed))  # True
print(verify_password("wrong_pw", hashed))            # False


# bcrypt가 안전한 이유:
# 1. 솔트 — 같은 비밀번호도 매번 다른 해시
# 2. 의도적으로 느림 (rounds=12 → 약 0.3초) — 무차별 공격 방어
# 3. SHA-256보다 적합 (SHA는 빠름이 단점)

실전 — 체크섬으로 데이터 무결성 검증

PYTHON📋 코드 (19줄)
# 파일 다운로드 후 변조 여부 확인
import hashlib

def file_sha256(path):
    h = hashlib.sha256()
    with open(path, 'rb') as f:
        while chunk := f.read(8192):
            h.update(chunk)
    return h.hexdigest()


# 다운로드 사이트 제공: a3f1...8c92
expected = "a3f1c5d8b2e9..."
actual = file_sha256("downloaded_file.zip")

if actual == expected:
    print("✅ 무결성 검증 통과")
else:
    print("❌ 파일이 변조됨")

O(1) 검색의 비밀

PYTHON📋 코드 (14줄)
# 리스트 검색: O(n)
nums = list(range(1_000_000))
999_999 in nums  # 약 10ms

# set/dict 검색: O(1) 평균
nums_set = set(nums)
999_999 in nums_set  # 약 0.001ms

# 비밀: 해시 함수가 즉시 버킷 위치 계산
# → 충돌 없으면 O(1), 충돌 있어도 평균 O(1)


# Worst case는 O(n) — 모든 키가 한 버킷에 몰리면
# Python dict는 무작위화 + open addressing으로 방어

다음 챕터

CH.25 "이산수학 종합" — 모듈 3 종합 실습 (집합 + 그래프 + 해시).


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 비밀번호 저장 코드를 분석해서
bcrypt 적용 가이드와 마이그레이션
전략을 만들어줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

한국 SaaS의 비밀번호 정책과 해싱 알고리즘
사례 5개를 보안 강도 관점에서 비교해줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 데이터베이스의 인덱스 구조를 분석해서
해시 인덱스 vs B-Tree 적합성과
예상 성능 향상을 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 비밀번호 해싱(bcrypt/argon2/scrypt)
실무 권장사항과 패스키 전환 트렌드를
솔직히 알려줘.

⭐ 이것만 기억하세요
해시 함수: 빠른 검색의 수학 이 3가지만 확실히 잡으세요
1.해시 함수는 가변 입력 → 고정 출력 + 결정적·균등·단방향 — HashMap의 O(1) 검색의 핵심
2.비밀번호는 SHA가 아닌 bcrypt/argon2 — 의도적으로 느려서 무차별 공격 방어
3.다음 챕터 CH.25에서 모듈 3 종합 — 집합 + 그래프 + 해시 결합 실전 문제


공유하기
진행도 24 / 45