테마 선택

📚 지식 노트

AI·하드웨어·주변기기·게임·컴퓨터 시스템·이론 컴퓨터 과학·수학·개발과 운영·보안·응용 분야에 대해 알아 두면 좋은 내용을 정리한 노트다. 위에서 분야를 고르고 아래에서 노트를 고른다.

해시 문제

개념마다 확인(뜻을 맞게 알았나) → 추적(손으로 한 단계씩) → 응용(처음 보는 상황) 순서로 푼다. 풀이 보기를 누르기 전에 종이에 먼저 적어 보자.

목차 (5)
  1. 해시 함수
  2. 체이닝
  3. 오픈 어드레싱
  4. 부하율과 재해시
  5. 블룸 필터

해시 함수

확인

키 item1부터 item8까지 여덟 개를 칸 4개짜리 표에 나눈다. 첫 글자의 코드만 보는 해시와, 글자마다 31을 곱해 더하는 다항식 해시를 쓰면 칸마다 몇 개씩 들어가는가? 첫 글자 해시가 나쁜 까닭은?

키 item1부터 item8키 끝 숫자12345678
나눌 키 여덟 개. 모두 item으로 시작한다.
풀이 보기

첫 글자 해시는 1번 칸에 8개가 모두 몰리고, 다항식 해시는 칸마다 2개씩 고르게 나뉜다. i의 코드 105를 4로 나눈 나머지가 1이라 모든 키가 1번 칸으로 간다.

첫 글자 해시는 칸 0부터 3에 0, 8, 0, 0개, 다항식 해시는 2, 2, 2, 2개첫 글자00810203다항식20212223
칸마다 들어간 키의 수. 빨간 칸이 몰린 칸이다.

첫 글자 해시는 키의 일부만 보므로, 키가 다른 곳(끝 숫자)에서만 달라지면 구별하지 못한다. 실제 키는 같은 접두사를 공유하는 일이 흔하다. 그러면 칸 하나에 모두 몰려 찾기가 O(n)이 된다. 좋은 해시는 키의 모든 글자를 결과에 섞는다.

추적

다항식 해시 h = h × 31 + (글자 코드)를 h = 0에서 시작해 "abc"에 적용하라. 글자를 하나 읽을 때마다 h는 얼마인가? 칸 8개짜리 표에서는 몇 번 칸인가? 글자 코드를 그냥 더하는 해시와 비교해 "cab"는 어떻게 되는가?

글자 a, b, c와 코드 97, 98, 99글자abc코드979899
글자 코드: a = 97, b = 98, c = 99.
풀이 보기

h는 97, 3105, 96354로 바뀌고, 96354 mod 8 = 2번 칸이다. 0 × 31 + 97 = 97, 97 × 31 + 98 = 3105, 3105 × 31 + 99 = 96354다.

abc를 읽는 동안 h는 97, 3105, 96354h97310596354
글자를 읽은 뒤의 h. 앞 글자일수록 31이 여러 번 곱해진다.

"cab"의 다항식 해시는 98244로 8로 나누면 4번 칸이라 "abc"와 갈린다. 글자 코드를 그냥 더하면 둘 다 97 + 98 + 99 = 294로 같아 같은 칸(6번)에 충돌한다. 더하기는 순서를 보지 못하므로, 같은 글자로 된 다른 키(애너그램)가 모두 부딪힌다. 31을 곱하는 것은 글자의 위치를 결과에 새기기 위해서다.

응용

주문 번호가 0, 8, 16, …, 56처럼 8의 배수로만 생긴다. 칸 번호를 키 mod 칸 수로 정할 때, 칸이 8개면 어떻게 나뉘는가? 칸이 7개면?

키 0, 8, 16, 24, 32, 40, 48, 56키08162432404856
키 여덟 개. 모두 8의 배수다.
풀이 보기

칸 8개면 모두 0번 칸에 몰리고, 칸 7개면 0~6번에 고르게 흩어진다(0번만 2개).

mod 8은 모두 0, mod 7은 0, 1, 2, 3, 4, 5, 6, 0mod 800000000mod 701234560
키마다 고른 칸 번호. 빨간 칸은 같은 칸에 몰린 키다.

키의 간격(8)과 칸 수가 공약수를 가지면 일부 칸만 쓰인다. 8과 7처럼 서로소면 키가 칸을 골고루 돈다. 그래서 단순한 mod 해시는 칸 수를 소수로 잡곤 한다. 칸 수를 2의 거듭제곱으로 두는 구현(빠른 비트 AND를 쓰려고)은 대신 해시 값을 잘 섞어 아래 비트에도 키의 모든 정보가 퍼지게 한다.

체이닝

확인

칸 5개짜리 체이닝 표에 키 10, 3, 15, 8, 20, 13을 넣었더니 아래처럼 됐다. 20, 25, 4를 찾을 때 키 비교는 각각 몇 번 하는가? 부하율은?

칸 0에 10, 15, 20, 칸 3에 3, 8, 13이 매달려 있고 나머지 칸은 비었다칸매달린 목록01015201∅2∅338134∅
키 mod 5 칸의 목록 끝에 넣은 결과.
풀이 보기

20은 3번, 25는 3번, 4는 0번이고, 부하율은 6 / 5 = 1.2다. 20은 0번 칸 목록의 세 번째라 10, 15, 20과 비교한다. 25도 0번 칸이라 목록 셋을 모두 보고 나서야 없다고 안다. 4는 4번 칸이 비어 있어 비교 없이 바로 없다고 답한다.

평균 목록 길이는 1.2지만, 키가 0번과 3번 칸에만 몰려 실제 목록은 3이다. 부하율은 해시가 고르다는 가정에서만 비용을 알려 준다. 이 키들은 모두 5로 나눈 나머지가 0이나 3이라 mod 5와 궁합이 나쁘다.

추적

빈 칸 5개짜리 체이닝 표에 키 8, 13, 21, 5, 16, 11을 차례로 넣는다. 마지막 표는? 이미 키가 있는 칸에 떨어진(충돌한) 넣기는 몇 번이고, 가장 긴 목록은?

넣을 키 8, 13, 21, 5, 16, 11키8132151611
넣을 키와 그 홈 칸(키 mod 5).
풀이 보기

0번 칸에 5, 1번 칸에 21 → 16 → 11, 3번 칸에 8 → 13이 매달린다. 충돌은 3번(13, 16, 11), 가장 긴 목록은 1번 칸의 3개다.

체이닝 단계 그림: 21, 16, 11은 1번 칸 목록에, 8과 13은 3번 칸 목록에, 5는 0번 칸에 매달린다칸매달린 목록01234부하율 0 / 5 = 0.08넣을 키88 mod 5 = 3빈 칸부하율 1 / 5 = 0.2813넣을 키1313 mod 5 = 3충돌: 앞에 1개부하율 2 / 5 = 0.421813넣을 키2121 mod 5 = 1빈 칸부하율 3 / 5 = 0.6521813넣을 키55 mod 5 = 0빈 칸부하율 4 / 5 = 0.852116813넣을 키1616 mod 5 = 1충돌: 앞에 1개부하율 5 / 5 = 1.05211611813넣을 키1111 mod 5 = 1충돌: 앞에 2개부하율 6 / 5 = 1.2빈 칸에 바로 넣음충돌해 목록 끝에 붙임이미 든 키
1 / 7

칸 5개짜리 빈 표. 키를 5로 나눈 나머지가 칸 번호다.

키 여섯 개를 칸 다섯 개에 체이닝으로 넣는다. 충돌한 키는 빨갛게 목록 끝에 붙는다.

11은 1번 칸에 이미 둘이 있어 충돌 두 개째다. 넣기 자체는 목록 끝(또는 앞)에 붙이면 되지만, 같은 키가 이미 있는지 확인하려면 그 목록을 훑어야 한다. 그래서 넣기도 목록 길이에 비례한다.

응용

공격자가 서버의 해시 함수를 알아내 모두 같은 칸에 떨어지는 키만 골라 보낸다. 키 n개를 차례로 넣을 때, 넣기마다 중복을 확인하느라 하는 비교는 모두 몇 번인가? n = 1,000이면? 어떻게 막는가?

칸 5개 표에서 키 5, 10, 15, 20, 25가 모두 0번 칸 목록에 매달려 있다칸매달린 목록05101520251∅2∅3∅4∅
모든 키가 0번 칸에 몰린 표. 나머지 칸은 비었다.
풀이 보기

0 + 1 + … + (n − 1) = n(n − 1)/2번이고, n = 1,000이면 499,500번이다. k번째 키를 넣을 때 목록에 이미 k − 1개가 있어 모두와 비교한다. 해시 표가 연결 리스트로 무너져 넣기 한 번이 O(n), 전체가 O(n²)이 된다. 고르게 흩어졌다면 약 1,000번이면 됐다.

이것이 해시 폭탄(hash flooding)이다. 막는 방법은 공격자가 칸을 예측하지 못하게 하는 것이다. 파이썬과 Rust는 프로세스마다 무작위 비밀 값을 섞는 SipHash 계열을 쓴다. Java HashMap은 긴 목록을 균형 트리로 바꿔 최악을 O(log n)으로 묶는다. 요청 하나에 받는 키의 수를 제한하는 것도 함께 쓴다.

오픈 어드레싱

확인

칸 7개짜리 선형 탐사 표에 3, 10, 17을 넣었더니 셋 다 홈 칸이 3이라 3, 4, 5번 칸에 앉았다. 10을 지울 때 4번 칸을 그냥 비우면, 그 뒤 17을 찾을 때 무슨 일이 생기는가?

칸 7개 표의 3, 4, 5번 칸에 키 3, 10, 17표012331041756
지우기 전의 표. 빈 칸에는 아무것도 적지 않았다.
풀이 보기

17이 표에 있는데도 "없다"고 답한다. 17의 홈 칸 3에는 3이 있어 4번 칸으로 가는데, 그 칸이 비어 있으니 탐사가 멈춘다. 빈 칸은 "이 키는 여기까지 오지 않았다"는 뜻이기 때문이다.

그냥 비운 표는 4번 칸이 비어 17까지 가지 못하고, 묘비를 세운 표는 4번 칸을 지나 17을 찾는다그냥 비움0123341756묘비01233묘비41756
그냥 비우면 4번 칸에서 탐사가 끊긴다. 묘비를 세우면 찾기가 그 칸을 지나 5번 칸까지 간다.

그래서 지운 칸에는 묘비(tombstone)를 세운다. 찾기는 묘비를 지나가고, 넣기는 키가 없음을 확인한 뒤 묘비 자리를 다시 쓴다. 체이닝에서는 목록에서 빼기만 하면 되므로 이런 문제가 없다.

추적

칸 7개짜리 빈 선형 탐사 표에서 넣기 5, 12, 19, 6, 지우기 12, 찾기 19, 넣기 26을 차례로 한다. 마지막 표는? 찾기 19와 넣기 26은 칸을 각각 몇 개 들여다보는가?

키 5, 12, 19, 6, 26의 홈 칸은 5, 5, 5, 6, 5키51219626홈 칸55565
키와 홈 칸(키 mod 7).
풀이 보기

마지막 표는 0번 19, 1번 6, 5번 5, 6번 26이다. 찾기 19는 3칸, 넣기 26은 5칸을 본다.

선형 탐사 단계 그림: 5, 12, 19가 5번 칸에서 밀려 앉고 끝을 넘어 0번 칸으로 돌며, 12를 지운 묘비를 26이 다시 쓴다0123456탐사 순서넣기 5홈 칸 = 5 mod 7 = 5넣었다홈 ↓51넣기 12홈 칸 = 12 mod 7 = 5다음 칸으로홈 ↓51넣기 12홈 칸 = 12 mod 7 = 5넣었다홈 ↓51212넣기 19홈 칸 = 19 mod 7 = 5다음 칸으로홈 ↓5121넣기 19홈 칸 = 19 mod 7 = 5다음 칸으로홈 ↓51212넣기 19홈 칸 = 19 mod 7 = 5넣었다홈 ↓19512123넣기 6홈 칸 = 6 mod 7 = 6다음 칸으로홈 ↓195121넣기 6홈 칸 = 6 mod 7 = 6다음 칸으로홈 ↓1951212넣기 6홈 칸 = 6 mod 7 = 6넣었다홈 ↓196512123지우기 12홈 칸 = 12 mod 7 = 5다음 칸으로홈 ↓1965121지우기 12홈 칸 = 12 mod 7 = 5묘비를 세웠다홈 ↓1965묘비12찾기 19홈 칸 = 19 mod 7 = 5다음 칸으로홈 ↓1965묘비1찾기 19홈 칸 = 19 mod 7 = 5다음 칸으로홈 ↓1965묘비12찾기 19홈 칸 = 19 mod 7 = 5찾았다홈 ↓1965묘비123넣기 26홈 칸 = 26 mod 7 = 5다음 칸으로홈 ↓1965묘비1넣기 26홈 칸 = 26 mod 7 = 5다음 칸으로홈 ↓1965묘비12넣기 26홈 칸 = 26 mod 7 = 5다음 칸으로홈 ↓1965묘비123넣기 26홈 칸 = 26 mod 7 = 5다음 칸으로홈 ↓1965묘비1234넣기 26홈 칸 = 26 mod 7 = 5넣었다홈 ↓19652612345들여다본 칸(굵게: 지금 칸)묘비(지운 자리)빈 칸빈 칸에서 멈춘다. 묘비는 찾기에선 지나가고 넣기에선 다시 쓴다
1 / 20

칸 7개짜리 빈 표. 키 mod 7 값이 그 키의 홈 칸이다.

홈 칸이 5인 키가 몰려 6번 칸을 지나 0번, 1번으로 돈다. 지운 12의 자리는 묘비로 남았다가 26이 다시 쓴다.

19는 5(키 5) → 6(묘비, 지나감) → 0에서 찾는다. 26은 5 → 6(묘비) → 0(19) → 1(6) → 2(빈 칸)까지 가서 26이 없음을 확인한 뒤, 지나온 첫 묘비인 6번 칸에 넣는다. 묘비에서 바로 넣지 않는 것은 26이 더 뒤에 이미 있을 수 있기 때문이다. 6은 홈 칸 6이 12에게 차지되어 있어 두 칸을 밀려났다. 서로 다른 홈 칸의 키도 한 덩어리로 엉킨다.

응용

칸 10개짜리 선형 탐사 표의 2~6번 칸이 차 있다. 새 키의 홈 칸이 0~9 중 아무 데나 같은 확률로 나온다면, 새 키가 7번 칸에 앉을 확률은? 0번 칸에 앉을 확률은?

칸 10개 표에서 2번부터 6번 칸까지 키 12, 22, 14, 23, 6이 이어져 있다표0112222314423566789
2~6번 칸이 이어진 덩어리다.
풀이 보기

7번 칸은 60%, 0번 칸은 10%다. 홈 칸이 2~6이면 덩어리 끝까지 밀려 7번에 앉고, 7이면 바로 앉는다. 10개 중 6개가 7번으로 간다. 0번에는 홈 칸이 0일 때만 앉는다.

덩어리 바로 뒤 칸은 그만큼 빨리 차고, 차면 덩어리가 더 커져 다음 키를 더 많이 끌어들인다. 이것이 뭉침(primary clustering)이다. 덩어리가 클수록 찾기가 그 길이만큼 길어진다. 제곱 탐사나 이중 해싱은 충돌한 키를 서로 다른 보폭으로 흩어 이 되먹임을 끊는다.

부하율과 재해시

확인

칸 16개짜리 선형 탐사 표에 키 12개가 있다. 부하율은? 아래 곡선(Knuth의 근사식)으로 없는 키를 찾을 때와 있는 키를 찾을 때의 기대 탐사 수를 구하라. 칸 32개로 재해시하면 어떻게 되는가?

부하율에 따른 기대 탐사 수: 선형 탐사에서 없는 키를 찾는 비용은 부하율 0.5에서 2.5칸, 0.9에서 50칸으로 치솟고, 체이닝은 부하율에 비례해 완만하게 는다124681000.250.50.751흔한 재해시 기준없는 키(선형 탐사)있는 키(선형 탐사)없는 키(체이닝)부하율 α = 든 키 수 / 칸 수 →세로: 찾기 한 번에 보는 칸 수의 기댓값선형 탐사, 없는 키선형 탐사, 있는 키체이닝, 없는 키
부하율에 따른 찾기 한 번의 기대 탐사 수.
풀이 보기

부하율 0.75에서 없는 키 8.5칸, 있는 키 2.5칸이다. 32칸으로 키우면 부하율 0.375에서 약 1.78칸과 1.3칸으로 준다. 없는 키는 ½(1 + 1/(1 − α)²) = ½(1 + 16) = 8.5, 있는 키는 ½(1 + 1/(1 − α)) = ½(1 + 4) = 2.5다.

칸 수를 두 배로 하면 메모리는 두 배지만 없는 키 찾기는 다섯 배 가까이 빨라진다. 없는 키 찾기는 넣기마다 한 번씩 하는 일(중복 확인)이라 이 값이 넣기 비용을 정한다. 그래서 선형 탐사 표는 부하율이 0.7 언저리를 넘기 전에 키운다.

추적

칸 7개 표에 키 5, 12, 19, 26을 선형 탐사로 넣었더니 아래처럼 됐다. 이 표를 0번 칸부터 차례로 읽어 칸 14개짜리 새 표에 다시 넣는다. 새 표에서 각 키는 몇 번 칸에 앉는가? 홈 칸에서 밀려난 키는 몇 개로 바뀌는가?

칸 7개 옛 표: 0번 19, 1번 26, 5번 5, 6번 12옛 표19026123455126
옛 표. 네 키의 홈 칸이 모두 5다.
풀이 보기

19는 5번, 26은 12번, 5는 6번, 12는 13번 칸이다. 밀려난 키는 3개(19, 26, 12)에서 2개(5, 12)로 준다.

칸 14개 새 표: 5번 19, 6번 5, 12번 26, 13번 12새 표0123419556789101126121213
새 표. 빨간 칸이 홈 칸에서 밀려난 키다.

읽는 순서대로 19(19 mod 14 = 5), 26(12), 5(5, 이미 19가 있어 6), 12(12, 이미 26이 있어 13)를 넣는다. 칸 번호가 키 mod 칸 수라서 옛 칸을 그대로 옮길 수 없고 모든 키의 홈 칸을 새로 계산해야 한다. 옛 표에서 같은 칸을 노리던 키들이 새 표에서는 5번과 12번 두 무리로 갈라진다. 넣는 순서에 따라 누가 밀려날지는 달라진다.

응용

칸 8개에서 시작해, 넣은 뒤의 부하율이 0.75를 넘게 될 넣기 직전에 칸 수를 두 배로 늘리는 해시 표가 있다. 키 100개를 넣는 동안 재해시는 몇 번 일어나고, 옮기는 키는 모두 몇 개인가? 넣기 한 번당은?

칸 수 8, 16, 32, 64, 128에서 담을 수 있는 키 6, 12, 24, 48, 96칸 수8163264128담을 키612244896
칸 수는 8, 16, 32, …로 늘어난다. 각 칸 수에서 담을 수 있는 키는 그 0.75배다.
풀이 보기

재해시는 5번, 옮기는 키는 모두 186개, 넣기 한 번당 1.86개다.

7, 13, 25, 49, 97번째 넣기에서 칸 수가 16, 32, 64, 128, 256이 되며 6, 12, 24, 48, 96개를 옮긴다몇 번째 넣기713254997새 칸 수163264128256옮긴 키612244896
재해시가 일어나는 넣기와, 그때 옮기는 키의 수.

6 + 12 + 24 + 48 + 96 = 186이다. 옮기는 양이 두 배씩 느는 등비수열이라 합이 마지막 항(96)의 두 배를 넘지 않고, 그 마지막 항도 넣은 키 수보다 작다. 그래서 동적 배열처럼 넣기 한 번의 분할 상환 비용이 O(1)이다. 다만 97번째 넣기 한 번은 96개를 옮기느라 느리다. 지연에 민감한 곳에서는 Redis처럼 연산마다 조금씩 옮기는 점진적 재해시를 쓴다.

블룸 필터

확인

비트 10개, 해시 3개짜리 블룸 필터에 x(비트 1, 4, 7)와 y(비트 2, 4, 9)를 넣었다. 넣지 않은 z(비트 1, 2, 7)와 w(비트 3, 4, 9)를 물으면 각각 뭐라고 답하는가? x를 지우려고 1, 4, 7번 비트를 끄면 어떻게 되는가?

비트 10개 중 1, 2, 4, 7, 9번이 켜져 있다비트00111203140506170819
x와 y를 넣은 뒤의 비트. 파란 칸이 켜진 비트다.
풀이 보기

z는 "아마 있음"(거짓 양성), w는 "확실히 없음"이다. z의 1, 2, 7번은 x와 y가 켜 둔 비트라 모두 켜져 있다. w의 3번은 꺼져 있어, 넣었다면 반드시 켰을 비트가 꺼진 것이니 확실히 없다.

x를 지우려고 비트를 끄면 y가 "없음"으로 바뀐다. 4번 비트는 x와 y가 함께 쓰기 때문이다. 블룸 필터가 약속하는 "거짓 음성 없음"이 깨지므로 일반 블룸 필터는 지우지 않는다. 지우기가 필요하면 비트 대신 개수를 세는 카운팅 블룸 필터를 쓴다.

추적

비트 16개, 해시 3개짜리 블룸 필터에 ant, bee, elk를 넣은 뒤 bee, cow, gnu를 묻는다. 셋 각각의 답은? 거짓 양성이 있다면 어느 키 때문인가?

ant는 6, 13, 4, bee는 15, 2, 5, elk는 13, 2, 7, cow는 0, 11, 6, gnu는 7, 6, 5번 비트ant6134bee1525elk1327cow0116gnu765
해시가 고른 비트 자리.
풀이 보기

bee는 아마 있음(맞음), cow는 확실히 없음, gnu는 거짓 양성이다. gnu의 7번은 elk가, 6번은 ant가, 5번은 bee가 켜 두었다.

블룸 필터 단계 그림: 키를 넣을 때 해시 세 자리의 비트를 켜고, 물을 때 세 비트가 모두 켜졌으면 아마 있음, 하나라도 꺼졌으면 확실히 없음으로 답한다0123456789101112131415넣은 키: 없음0000000000000000넣은 키: ant넣기 "ant"h₁, h₂, h₃ → 6, 13, 40000101000000100넣은 키: ant, bee넣기 "bee"h₁, h₂, h₃ → 15, 2, 50010111000000101넣은 키: ant, bee, elk넣기 "elk"h₁, h₂, h₃ → 13, 2, 70010111100000101넣은 키: ant, bee, elk묻기 "bee"h₁, h₂, h₃ → 15, 2, 50010111100000101모두 켜졌다: 아마 있다(맞았다)넣은 키: ant, bee, elk묻기 "cow"h₁, h₂, h₃ → 0, 11, 60010111100000101꺼진 비트가 있다: 확실히 없다넣은 키: ant, bee, elk묻기 "gnu"h₁, h₂, h₃ → 7, 6, 50010111100000101모두 켜졌다: 아마 있다 → 사실은 없다(거짓 양성)방금 켠 비트켜진 비트(1)물었는데 꺼진 비트
1 / 7

비트 16개가 모두 0인 빈 필터. 키마다 해시 3개로 비트 자리를 고른다.

ant, bee, elk를 넣은 뒤 bee, cow, gnu를 묻는다. gnu는 넣지 않았는데 세 키가 켜 둔 비트에 모두 걸린다.

cow는 0번과 11번이 꺼져 있다. 하나만 꺼져 있어도 충분하다. 키 셋이 비트 16개 중 7개(2, 4, 5, 6, 7, 13, 15)를 켜 두어 거의 절반이 켜졌으니, 아무 키나 세 자리가 모두 켜졌을 확률이 꽤 크다. 비트 수에 비해 키가 많아질수록 거짓 양성이 빠르게 는다.

응용

키 100만 개를 넣을 블룸 필터의 거짓 양성률을 1%로 맞추려 한다. 비트는 몇 개, 해시는 몇 개가 필요한가? 키 하나에 10비트를 줄 때 해시 수 k에 따른 거짓 양성률이 아래와 같다.

해시 1개부터 8개까지 거짓 양성률 9.52, 3.29, 1.74, 1.18, 0.94, 0.84, 0.82, 0.85퍼센트해시 수 k12345678거짓 양성 %9.523.291.741.180.940.840.820.85
키 하나에 10비트일 때 해시 수별 거짓 양성률(%), (1 − e^(−k/10))^k로 계산했다.
풀이 보기

비트 약 958만 개(키당 약 9.6비트, 약 1.2MB)와 해시 7개다. 최적 비트 수는 m = −n ln p / (ln 2)² ≈ 9,585,059개, 최적 해시 수는 k = (m/n) ln 2 ≈ 6.6이라 7개로 올린다.

표처럼 키당 10비트면 k = 7에서 0.82%로 가장 낮다. 해시가 너무 적으면 비트 몇 개만 겹쳐도 걸리고, 너무 많으면 비트가 빨리 차서 오히려 나빠진다. 키가 32바이트 문자열이라면 그대로 저장하는 데 32MB가 드는데, 블룸 필터는 키 길이와 상관없이 1.2MB면 된다. 대신 "있음"은 늘 "아마"다.