Abseil Escape — CEscape·HexEscape·Base64
#한 줄 요약
문자열을 안전한 표현으로 바꾸는 두 갈래가 있다. 사람이 읽을 표현(CEscape, HexEscape)과 전송용 인코딩(Base64Escape). Abseil은 모두 absl/strings/escaping.h 한 헤더에 통합 제공하며, web-safe variant, padding 옵션, in-place reverse 함수까지 지원한다.
#동기
log 출력, 디버깅 dump, 직렬화. 임의 바이트 문자열을 사람이 읽거나 텍스트 전송하려면 escape가 필요하다. 표준 라이브러리에는 명확한 helper가 없다 — iomanip의 std::hex는 단일 정수용이고, base64는 표준에 없다.
// 회피 — 로그에 raw bytesLOG(INFO) << "buffer: " << raw_data; // 제어 문자, NUL, non-printable이 그대로
// GoodLOG(INFO) << "buffer: " << absl::CEscape(raw_data);// "buffer: hello\x00world\n"#API와 사용법
#include "absl/strings/escaping.h"
namespace absl {// C-style escape: \n, \t, \xHH, \\std::string CEscape(absl::string_view src);std::string CHexEscape(absl::string_view src); // 모든 non-printable을 \x로bool CUnescape(absl::string_view src, std::string* dest, std::string* error = nullptr);
// 16진 문자열std::string BytesToHexString(absl::string_view from);std::string HexStringToBytes(absl::string_view from);
// Base64 (RFC 4648 표준 alphabet)void Base64Escape(absl::string_view src, std::string* dest);std::string Base64Escape(absl::string_view src);bool Base64Unescape(absl::string_view src, std::string* dest);
// Web-safe Base64 (URL/filename 안전 alphabet)void WebSafeBase64Escape(absl::string_view src, std::string* dest);std::string WebSafeBase64Escape(absl::string_view src);bool WebSafeBase64Unescape(absl::string_view src, std::string* dest);}#CEscape — C 스타일 이스케이프
std::string s = absl::CEscape("hello\x01world\n");// "hello\\x01world\\n"규칙은 다음과 같다.
\n,\r,\t,\\,\",\'는 backslash 이스케이프.- printable ASCII는 그대로.
- non-printable은
\xHH(2자리 16진).
CHexEscape는 더 엄격하다. printable이라도 8진 escape 가능 character까지 모두 \xHH로 출력한다. 디버깅/binary dump에 적합.
absl::CEscape("\x07ABC"); // "\\aABC" (\\a = BEL)absl::CHexEscape("\x07ABC"); // "\\x07ABC"CUnescape는 역변환. 파싱 에러는 error 문자열에 담아 반환한다.
std::string out, err;if (!absl::CUnescape("hello\\x01world", &out, &err)) { LOG(ERROR) << "unescape failed: " << err;}#HexString — 단순 16진
std::string hex = absl::BytesToHexString("\x00\xff\x10");// "00ff10"
std::string bytes = absl::HexStringToBytes("DEADBEEF");// "\xde\xad\xbe\xef" (소문자/대문자 모두 허용)체크섬, hash 값, 메모리 dump 등 완전 16진이 필요할 때 쓴다. CHexEscape는 사람이 읽기 위해 printable과 섞이고, BytesToHexString은 순수 16진이다.
#Base64
std::string encoded;absl::Base64Escape("hello world", &encoded);// "aGVsbG8gd29ybGQ="표준 alphabet A–Z a–z 0–9 + /와 = padding. RFC 4648 준수.
std::string decoded;if (!absl::Base64Unescape(encoded, &decoded)) { // invalid base64}엄격하다. 잘못된 문자, 패딩 누락, 길이 mismatch는 false. raw 바이트가 임의 0x00을 포함해도 안전.
#WebSafeBase64 — URL/filename 안전
표준 base64의 +와 /는 URL/filename에서 escape가 필요하다. WebSafe variant는 alphabet을 바꾼다.
표준: A-Z a-z 0-9 + / =WebSafe: A-Z a-z 0-9 - _ =std::string token;absl::WebSafeBase64Escape(raw_uuid_bytes, &token);// URL safe — query string, path, cookie에 그대로 사용 가능WebSafeBase64Unescape도 대칭. 표준 base64로 인코딩된 문자열을 web-safe로 디코딩하려고 하면 false다(+ / 미허용).
padding = 처리 차이도 알아두면 좋다. JWT 등 일부 protocol은 padding 없는 WebSafeBase64를 쓴다 — absl::WebSafeBase64Unescape는 padding 있음/없음 모두 허용한다(Escape 측은 padding을 붙인다).
#내부 구현
Base64는 6-bit 단위 lookup table로 동작한다. 핵심 인코더는 다음과 같은 구조다.
// absl/strings/escaping.cc (요약)constexpr char kBase64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
constexpr char kWebSafeBase64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
size_t Base64EscapeInternal(const unsigned char* src, size_t slen, char* dest, size_t szdest, const char* base64, bool do_padding) { // 3 bytes → 4 chars 반복 // 마지막 1~2 bytes 처리 + 옵션 padding}알고리즘은 같고 alphabet과 padding만 다르다. 두 함수 모두 한 번의 alloc(또는 dest reserve)으로 끝난다.
CEscape는 byte 단위 상태 머신이다. lookup 없이 단순 if 분기로 처리. 작은 입력에서 가장 빠른 경로다.
#코드 리뷰 포인트
1. log/error message의 raw bytes
// 회피 — 제어 문자가 터미널을 깨뜨림, NUL이 잘림LOG(ERROR) << "got: " << buffer;
// GoodLOG(ERROR) << "got: " << absl::CEscape(buffer);2. URL token 생성
// 회피 — 표준 base64는 URL에 부적합std::string token;absl::Base64Escape(secret_bytes, &token);// "+/" 등이 들어가면 URL escape가 또 필요
// Goodstd::string token;absl::WebSafeBase64Escape(secret_bytes, &token);// 그대로 URL에 사용3. config dump
// 사람이 읽기 좋은 형식for (const auto& [k, v] : config) { LOG(INFO) << absl::StrCat(" ", k, " = \"", absl::CEscape(v), "\"");}#안티패턴
HexString vs CHexEscape 혼동
| 함수 | 출력 | 용도 |
|---|---|---|
BytesToHexString("AB") | "4142" | 순수 16진 (해시값, 체크섬) |
CHexEscape("AB") | "AB" | C 리터럴 호환 (printable은 그대로) |
CHexEscape("\x01") | "\\x01" | 디버깅 dump |
두 API의 의미가 다르다. 항상 의도와 일치하는 쪽을 고른다.
unsafe alphabet 가정
base64 결과를 문자열 그대로 SQL/HTML/log에 넣을 때 검증 없이 그러지 않는다. 표준 base64는 SQL injection 측면에서는 안전한 문자만 쓰지만, /가 path traversal 위험이 있는 환경(파일명 등)에서는 위험할 수 있다. WebSafe를 쓴다.
padding 처리 가정
// 회피 — padding 형식 가정assert(encoded.size() % 4 == 0);
// Good — Unescape 결과만 검증std::string out;if (!absl::WebSafeBase64Unescape(encoded, &out)) { return InvalidInput();}#정리
- escape는 두 갈래 — 읽기용(CEscape, HexEscape)과 전송용(Base64).
CEscape는 printable +\xHH,CHexEscape는 모두 16진.BytesToHexString/HexStringToBytes는 순수 16진 변환.Base64Escape는 표준 alphabet,WebSafeBase64Escape는 URL/filename 안전 alphabet.- 모든 Unescape는 검증 실패 시
bool false. silent 무시 금지.
#다음 편
Part 4가 끝났다. Part 5-01 — flat_hash_map에서 Swiss Table 기반 컨테이너로 넘어간다.
#관련 항목
Abseil Code Review · 27 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 회피
관련 글
absl::Cord — 분산 시스템용 대용량 문자열
absl::Cord — tree 구조로 표현되는 immutable-ish 문자열. zero-copy concat, shared substring, Google 내부 RPC payload의 기본 표현.
같은 시리즈에서 이어 읽기
Abseil ASCII 함수 — locale-free 분류·대소문자 변환
Part 4-07: absl::ascii_* — locale 독립 ASCII 분류, AsciiStrToLower / AsciiStrToUpper / StripAsciiWhitespace.
같은 시리즈에서 이어 읽기
absl::StrFormat — type-safe printf·FormatSpec
Part 4-06: absl::StrFormat — printf 호환 syntax의 type-safe 포맷팅, FormatSpec 컴파일 타임 검증, FormatUntyped.
같은 시리즈에서 이어 읽기