absl::BitGen — 모던 난수 생성기
#std::의 random은 왜 불편한가
C++11 <random>은 강력하지만 일상 사용에 boilerplate가 너무 많다.
// std — 일상 사용에도 세 단계std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<int> dist(1, 100);int x = dist(gen);세 객체(엔진 시드, 엔진, 분포)를 매번 결합해야 한다. Abseil은 함수 호출 하나 로 압축한다.
// abslabsl::BitGen bg;int x = absl::Uniform(bg, 1, 101); // [1, 101) — half-open#BitGen의 정체
absl::BitGen은 URBG(Uniform Random Bit Generator) 컨셉을 만족하는 엔진이다. 내부적으로 randen이라는 SIMD 친화 알고리즘을 쓴다. 핵심 특성:
| 특성 | BitGen | std::mt19937 |
|---|---|---|
| 상태 크기 | 256바이트 | 2.5KB |
| 속도 | ~2× 빠름 | 기준 |
| 통계적 품질 | 더 좋음 (Crush 통과) | 통과(MT 고전) |
| 보안 | 비-cryptographic | 비-cryptographic |
| Seed | 자동 OS entropy | 사용자가 직접 |
자동 시드가 큰 차이다. absl::BitGen bg;만 써도 OS entropy로 시드된다. 결정적 재현성이 필요한 경우만 명시 시드를 쓴다.
#include "absl/random/random.h"
absl::BitGen bg; // OS entropy로 시드absl::SeedSeq seed{42, 1337};absl::BitGen reproducible(seed); // 결정적 시드#사용 — Uniform이 대부분
absl::BitGen bg;
// 정수 [0, 10)int i = absl::Uniform(bg, 0, 10);
// 정수 [0, 10] (closed)int j = absl::Uniform(absl::IntervalClosed, bg, 0, 10);
// 실수 [0.0, 1.0)double d = absl::Uniform(bg, 0.0, 1.0);
// 컨테이너에서 무작위 원소std::vector<int> v = {1, 2, 3, 4, 5};int pick = v[absl::Uniform(bg, 0u, v.size())];interval tag로 경계 의미를 명시한다.
| Tag | 의미 |
|---|---|
IntervalClosedClosed / IntervalClosed | [a, b] |
IntervalClosedOpen (기본) | [a, b) |
IntervalOpenOpen / IntervalOpen | (a, b) |
IntervalOpenClosed | (a, b] |
정수 기본은 [a, b), 실수 기본도 동일. C++ STL의 uniform_int_distribution([a, b] closed)과 다르다. 코드 리뷰에서 자주 헷갈리는 부분이다.
// 회피 — std와 같은 closed 가정int dice = absl::Uniform(bg, 1, 6); // ❌ 6은 안 나옴
// Goodint dice = absl::Uniform(absl::IntervalClosed, bg, 1, 6);#그 외 분포
Uniform 외에도 다양한 분포가 자유 함수로 노출된다(다음 챕터에서 자세히).
double mean = absl::Gaussian<double>(bg, 0.0, 1.0);double exp = absl::Exponential<double>(bg, 1.0);bool flag = absl::Bernoulli(bg, 0.5);#InsecureBitGen — 더 가벼운 변종
랜덤 품질 요구가 낮은 곳(빠른 테스트 데이터, 디버그 셔플)에는 absl::InsecureBitGen이 있다.
absl::InsecureBitGen ibg; // 더 작은 상태, 더 빠름int x = absl::Uniform(ibg, 0, 100);다음과 같이 사용처를 나눈다.
| 용도 | 엔진 |
|---|---|
| Production 일반 random | BitGen |
| 테스트 데이터 생성 | InsecureBitGen |
| 암호학적 random | BitGen 안 됨 — boringssl RAND_bytes 사용 |
#코드 리뷰에서 자주 보는 지적
// 회피 — rand() 직접int x = rand() % 100;// 문제 — 모듈로 편향, locale 의존, 시드 불명
// Goodabsl::BitGen bg;int x = absl::Uniform(bg, 0, 100);// 회피 — BitGen을 인라인으로 매번 생성int Pick() { absl::BitGen bg; // ❌ 매 호출마다 256B 할당 + 시드 return absl::Uniform(bg, 0, 100);}
// Good — BitGen은 thread_local 또는 인스턴스 멤버thread_local absl::BitGen tls_bg;int Pick() { return absl::Uniform(tls_bg, 0, 100); }#thread 안전성
absl::BitGen은 thread-safe 하지 않다. URBG 컨셉 자체가 상태를 변경하므로 동시 호출은 정의되지 않은 동작이다.
// 회피 — 멀티스레드에서 공유absl::BitGen shared; // 데이터 레이스
// Good — thread_local 또는 mutex 보호thread_local absl::BitGen tls;대부분의 server는 thread_local이 정답이다. 매 스레드가 독립 BitGen을 가지면 lock-free.
#한 줄 비교 — std vs absl random
| 작업 | std::random | absl::random |
|---|---|---|
| 엔진 + 시드 | 두 줄 | 한 줄(BitGen bg;) |
| Uniform int | dist 생성 + 호출 | Uniform(bg, a, b) |
| Closed interval | 기본 | IntervalClosed 명시 |
| 상태 크기 | 2.5KB (mt19937) | 256B |
| 속도 | 기준 | ~2× |
| Mocking | 없음 | MockingBitGen |
#정리
absl::BitGen은 자동 시드, 작은 상태, 빠른 randen 알고리즘.- 분포는 자유 함수 —
Uniform,Gaussian,Exponential등. - 정수·실수 기본 interval이
[a, b)(half-open).IntervalClosed태그로 명시 변경. - thread-safe 아님 —
thread_local패턴이 표준 사용. InsecureBitGen은 테스트·디버그용 더 가벼운 변종. 암호학 용도 불가.
#다음 장 예고
Part 8-02: Distributions — Uniform 외 분포 카탈로그.
#관련 항목
Abseil Code Review · 45 of 79
- 1 Abseil Code Review — Google production-grade C++ 라이브러리 분석
- 2 Abseil 개요 — Google이 std를 보완한 이유
- 3 Abseil 설계 철학 — std 호환과 추가 기능의 균형
- 4 Abseil 빌드와 의존성 — Bazel vs CMake
- 5 Abseil LTS vs HEAD 릴리스 모델 분석
- 6 Abseil Versioning과 ABI 호환성 정책
- 7 Abseil 매크로 — ABSL_HAVE_*·ABSL_ATTRIBUTE_*
- 8 Abseil ABSL_PREDICT_TRUE/FALSE — branch hint
- 9 absl::LogSeverity — 로그 레벨 타입
- 10 Abseil type_traits — negation·conjunction·void_t
- 11 Abseil Conformance·Policy 분석
- 12 Abseil Memory utilities 분석
- 13 Abseil raw_logging — heap-free 로깅
- 14 Abseil thread_annotations — clang TSA 통합
- 15 absl::Status — exception-free error handling
- 16 absl::StatusOr<T> — 값 또는 에러
- 17 absl status_macros — ASSIGN_OR_RETURN·RETURN_IF_ERROR
- 18 absl::Status payload — 구조화된 에러 컨텍스트
- 19 absl::Status ↔ exception 변환 패턴
- 20 absl::string_view — non-owning 문자열 참조
- 21 absl::string_view 함정 — dangling·c_str·임시 객체
- 22 absl::StrCat — 가변 인자 문자열 연결과 AlphaNum
- 23 absl::StrSplit — Delimiter·Predicate·컨테이너 변환
- 24 absl::StrJoin — 컨테이너 결합과 Formatter
- 25 absl::StrFormat — type-safe printf·FormatSpec
- 26 Abseil ASCII 함수 — locale-free 분류·대소문자 변환
- 27 Abseil Escape — CEscape·HexEscape·Base64
- 28 absl::flat_hash_map — Swiss Table 기반 hash map
- 29 absl::flat_hash_set — set 버전 Swiss Table
- 30 absl::node_hash_map — stable pointer가 필요할 때
- 31 absl::btree_map — sorted·cache-friendly B-tree
- 32 absl::FixedArray — 런타임 크기 stack 배열
- 33 absl::InlinedVector — small buffer optimization
- 34 Abseil Swiss Table internals — control byte·SIMD probing
- 35 absl::Mutex — reader-writer·fairness·deadlock 검출
- 36 absl::Mutex Conditional Critical Section — Await로 cv 없애기
- 37 absl::Notification — once-only signal
- 38 absl::BlockingCounter·Barrier — 다중 thread 조율
- 39 absl::Mutex annotations — clang thread-safety로 race를 컴파일 타임에
- 40 absl::Time·Duration 분석 — 단단한 type
- 41 absl::Time Format·Parse
- 42 absl::CivilTime 분석
- 43 absl::time_zone 분석
- 44 absl::Time mocking — 테스트 친화 시간
- 45 absl::BitGen — 모던 난수 생성기
- 46 Abseil Random Distributions — Uniform·Exponential
- 47 Abseil Mocking Random — 테스트 결정성
- 48 Abseil Random Seeding·Entropy
- 49 absl::int128·uint128 분석
- 50 absl::bits — popcount·countl_zero
- 51 absl::optional vs std::optional
- 52 absl::variant 분석
- 53 absl::span 분석
- 54 absl::any 분석
- 55 absl::compare — three-way 비교
- 56 Abseil utility — apply·in_place
- 57 Abseil AbslHashValue 분석
- 58 Abseil HashState chaining
- 59 Abseil Custom hashable 구현
- 60 Abseil LOG·VLOG·CHECK 분석
- 61 Abseil LogSink 분석
- 62 Abseil LogEntry·structured logging
- 63 Abseil Stack trace·failure_signal_handler
- 64 ABSL_FLAG 정의 분석
- 65 Abseil ParseCommandLine 동작
- 66 Abseil Flag introspection·validation
- 67 Google 스타일의 Abseil 사용 패턴
- 68 Abseil 자주 보는 anti-pattern
- 69 std → absl 마이그레이션 전략
- 70 absl::Cleanup — 함수 종료 시 실행 보장
- 71 Abseil algorithm container 확장 — c_sort·c_find_if·c_count_if
- 72 absl::function_ref와 any_invocable — 함수 객체 전달의 두 축
- 73 absl::bind_front와 Overload — 함수 객체 보조 도구
- 74 absl::Cord — 분산 시스템용 대용량 문자열
- 75 absl::from_chars·SimpleAtoi — 빠른 숫자 변환
- 76 absl::Cord vs std::string — 선택 기준과 메모리 프로파일
- 77 absl::GetStackTrace와 Symbolize — crash 시 readable stack
- 78 absl::ComputeCrc32c — 하드웨어 가속 체크섬
- 79 absl::PeriodicSampler — 적응형 샘플링·jitter 회피
관련 글
Abseil Random Seeding·Entropy
BitGen 시드 관리 — OS entropy, SeedSeq, 결정적 재현성. 그리고 보안 한계.
같은 시리즈에서 이어 읽기
Abseil Mocking Random — 테스트 결정성
MockingBitGen — 분포 호출의 결과값을 결정적으로 강제. flaky random 테스트를 끝낸다.
같은 시리즈에서 이어 읽기
Abseil Random Distributions — Uniform·Exponential
absl::Uniform, Gaussian, Exponential, Poisson 등 — std::*_distribution의 클래스 객체를 함수 호출로 평탄화.
같은 시리즈에서 이어 읽기