개발자를 위한 아티클
인코딩 형식, JSON 다루기 등 개발자에게 유용한 주제에 대한 설명과 관련 tulzy 온라인 도구 링크.
인코딩
Base64: 인코딩이 필요한 이유와 작동 방식
Base64가 바이너리 데이터를 ASCII 텍스트로 바꾸는 방법과 실제로 언제 필요한지.
Base32: Base64와 다른 점과 더 편리한 경우
대소문자를 구분하지 않는 Base32 알파벳과 Base64보다 편리한 상황.
URL Encode/Decode: 링크에서의 퍼센트 인코딩
주소와 매개변수의 특수 문자가 %XX 시퀀스로 바뀌는 과정.
HTML Entities: 특수 문자를 안전하게 표시하는 방법
< > & 문자를 이스케이프해야 하는 이유와 이것이 마크업 손상을 막는 방법.
JWT: 토큰 구조와 JWT를 "디코딩"한다는 것의 의미
JWT의 header, payload, signature와, 디코딩이 서명 검증과 다른 이유.
Unicode Escape: \uXXXX 시퀀스의 의미
JSON과 JS 문자열에 나타나는 \u0041 같은 시퀀스가 어디서 오는지, 무엇을 의미하는지.
ROT13과 시저 암호: 단순한 문자 치환
13글자 이동이 ROT13을 자기 역함수로 만드는 이유와 오늘날에도 쓰이는 이유.
Punycode: 국제화 도메인이 DNS에서 작동하는 방식
라틴 문자가 아닌 문자를 포함한 도메인이 xn-- 접두사가 붙은 ASCII 형식으로 바뀌는 과정.
모스 부호: 텍스트가 점과 선으로 바뀌는 원리
문자를 점과 선으로 인코딩하는 원리와 모스 부호가 오늘날 어디에 쓰이는지.
Data URI: 이미지를 코드에 직접 삽입해야 할 때
Data URI가 파일 내용을 HTML이나 CSS에 직접 삽입하는 방식과 그럴 만한 가치가 있는 경우.
Gzip + Base64: 텍스트로 전송하기 위한 데이터 압축
압축된 바이너리 데이터를 텍스트 필드에 넣기 전에 Base64로도 인코딩하는 이유.
XML Entities: XML 문서에서 문자 이스케이프하기
이것이 없으면 파싱 중 문서가 깨지는, XML의 다섯 가지 필수 엔티티.
JSON
JSON Formatter: 포맷팅, 압축, 검증
가독성을 위한 포맷팅, 크기를 위한 압축, 정확성을 위한 검증 — JSON에 관한 세 가지 다른 작업.
JSONPath: 수동 파싱 없이 JSON 데이터 조회하기
JSONPath가 큰 JSON에서 필요한 값을 수동 탐색 없이 하나의 표현식으로 꺼내는 방법.
JSON Diff: 구조적 비교가 텍스트 비교와 다른 점
키 순서가 두 JSON 문서의 비교에 영향을 주면 안 되는 이유.
JSON Schema: JSON 구조를 기술하고 검증하는 방법
JSON Schema가 데이터가 예상된 계약과 일치하는지 자동으로 확인할 수 있게 하는 방법.
JSON Flatten: 중첩된 구조를 평평한 목록으로 바꾸기
깊이 중첩된 JSON이 user.address.city 같은 평평한 키 목록으로 어떻게 바뀌는지.
JSON Sort Keys: 객체의 키를 왜 정렬하는가
JSON 키 순서가 명시되지 않은 이유와, 그럼에도 실무에서 정렬이 여전히 유용한 이유.
JSON Repair: JSON이 왜 깨지고 어떻게 고치는가
"깨진" JSON의 흔한 원인과 자동 복구가 고칠 수 있는 것과 없는 것.
Mock JSON Generator: 가짜 데이터가 왜 유용한가
목 데이터가 백엔드가 준비되기 전에 UI 개발을 시작할 수 있게 하는 방법.
JSON ↔ YAML/CSV/XML/TOML: 언제, 왜 변환하는가
JSON을 CSV로 변환할 때 어떤 데이터가 사라지는지, YAML과 TOML이 설정 파일에 인기 있는 이유.
텍스트
camelCase, snake_case, kebab-case: 언제 어떤 스타일을 쓸까
camelCase, snake_case, kebab-case가 왜 존재하며, 각각 보통 어디에 쓰이는지.
Text Diff: 텍스트 차이를 찾는 알고리즘의 작동 원리
diff 알고리즘이 텍스트 두 버전 사이의 최소 변경 집합을 찾는 방법.
정규 표현식: 기초와 탐욕적 매칭의 함정
정규 표현식에서 탐욕적 매칭과 게으른 매칭의 차이, 그리고 실무에서 왜 중요한지.
줄 정렬: 알파벳순과 숫자순은 왜 다를까
알파벳순 정렬이 숫자를 텍스트처럼 다루는 이유와, 숫자 정렬과의 차이.
문자열 이스케이핑: JS, JSON, 셸, 정규식마다 규칙이 다른 이유
모든 곳에 통하는 단 하나의 이스케이핑 규칙이 없는 이유 — JS, JSON, 셸, 정규식 각각 고유한 규칙이 있다.
CRLF와 LF: 줄바꿈 문자가 여전히 문제를 일으키는 이유
CRLF와 LF 차이가 어디서 왔는지, git과 스크립트에서 왜 지금도 문제를 일으키는지.
문자 수와 단어 수 세기: 유니코드가 왜 이것을 복잡하게 만드는가
유니코드에서 시각적으로 하나의 이모지가 여러 코드 포인트로 이루어질 수 있는 이유.
Lorem Ipsum: 이 더미 텍스트는 어디서 왔고 왜 의미가 없을까
Lorem Ipsum 텍스트가 실제로 어디서 왔는지, 실제 텍스트 대신 무의미한 텍스트를 쓰는 이유.
Slugify: 제목이 유효한 URL로 바뀌는 과정
기사 제목이 하이픈으로 구분된 깔끔하고 읽기 쉬운 URL로 바뀌는 과정.
Markdown: 문서화의 표준이 된 이유
HTML과 달리 Markdown이 원본 상태에서도 읽기 쉬운 이유.
보이지 않는 공백: 겉보기에 같은 텍스트 비교가 왜 실패할까
보이지 않는 공백 하나가 겉보기에 같은 두 텍스트의 비교를 실패하게 만드는 방법.
텍스트 뒤집기: 이모지에서 왜 깨질까
단순한 텍스트 뒤집기가 여러 코드 포인트로 이루어진 이모지를 왜 깨뜨리는지.
텍스트 빈도 분석: 워드 클라우드부터 암호 해독까지
문자 빈도 분석이 역사적으로 단순 치환 암호를 해독하는 데 어떻게 도움이 되었는지.
해시/암호화
Hash Generator: MD5, SHA-1, SHA-256은 서로 어떻게 다른가
MD5가 아직도 파일 무결성 검증에는 쓰이지만 비밀번호에는 쓰이지 않는 이유.
Checksum Verifier: 파일이 손상되지 않았는지 확인하는 방법
일치하는 체크섬이 파일의 무결성은 확인해주지만 누가 만들었는지는 확인해주지 않는 이유.
HMAC: 키가 있는 해시는 일반 해시와 어떻게 다른가
일반 SHA-256이 메시지 위변조를 막지 못하지만 HMAC은 막을 수 있는 이유.
Bcrypt: 비밀번호를 빠르게가 아니라 느리게 해시하는 이유
빠른 SHA-256이 비밀번호에는 나쁜 선택이고, 느린 bcrypt가 올바른 선택인 이유.
UUID: 거의 절대 중복되지 않는 식별자는 어떻게 만들어지는가
UUID v4를 수백만 대의 기계에서 충돌 위험 없이 독립적으로 생성할 수 있는 이유.
비밀번호 생성기: 비밀번호를 진짜로 강하게 만드는 것
사전 단어로 만든 긴 비밀번호가 기호와 숫자가 든 짧은 비밀번호보다 강한 이유.
AES: 대칭 암호화는 어떻게 동작하는가
AES에서 같은 키가 데이터를 암호화하고 복호화하는 이유, 그리고 이것이 비대칭 암호화와 다른 점.
Argon2: 이 알고리즘이 비밀번호 해싱 경진대회에서 우승한 이유
Argon2가 오래된 비밀번호 해싱 알고리즘보다 GPU를 이용한 공격을 더 잘 방어하는 방법.
Scrypt: 이 알고리즘이 왜 그렇게 많은 메모리를 필요로 하는가
scrypt가 ASIC 장치에서의 크래킹을 어렵게 만들기 위해 일부러 많은 메모리를 요구하는 이유.
TOTP: 인증 앱의 일회용 코드는 어떻게 작동하는가
Google Authenticator의 코드가 인터넷 없이 작동하고 시간만으로 서버와 동기화되는 이유.
PBKDF2: 가장 오래된 키 스트레칭 표준
PBKDF2의 권장 반복 횟수가 매년 늘어나는 이유.
X.509: SSL 인증서 안에는 무엇이 들어있는가
초록색 자물쇠를 보여주기 전에 브라우저가 사이트 인증서에서 정확히 무엇을 확인하는지.
PGP: 공개 키와 개인 키 암호화는 어떻게 작동하는가
PGP 공개 키는 자유롭게 공유할 수 있지만 개인 키는 절대 공유해서는 안 되는 이유.
시간/숫자
유닉스 시간: 컴퓨터가 1970년부터 시간을 세는 이유
1970년 1월 1일이 대부분의 컴퓨터 시스템에서 시간의 기준점이 된 이유.
Cron 표현식: 작업 일정을 해독하는 방법
*/15 * * * * 같은 표현식을 해독해 작업이 정확히 언제 실행되는지 아는 방법.
진법: 2진법, 8진법, 16진법이 존재하는 이유
CSS에서 색상 #FF5733이 10진수가 아니라 16진수로 표기되는 이유.
비트 연산: AND, OR, XOR이 비트 수준에서 어떻게 동작하는가
비트 AND가 논리 AND와 어떻게 다른지, 그리고 숫자의 개별 비트를 조작해야 하는 이유.
날짜 차이: 날짜 세기가 보이는 것보다 까다로운 이유
윤년 때문에 날짜를 단순하게 빼면 잘못된 결과가 나올 수 있는 이유.
나이 계산: 단순히 연도를 빼는 것이 아닌 이유
태어난 연도를 단순히 빼면 실제보다 한 살 많은 나이가 나올 수 있는 이유.
시간대: UTC가 GMT와 같지 않은 이유
UTC는 1년에 두 번 바뀌지 않지만 런던 시간(GMT/BST)은 바뀌는 이유.
기간 계산기: 시, 분, 초를 올바르게 더하는 방법
분과 초를 더할 때 10진법 덧셈과 마찬가지로 나머지를 다음 자리로 "올림"해야 하는 이유.
ISO 8601 Duration: 표준 형식으로 기간을 쓰는 방법
PT1H30M이 "1시간 30분"을 의미하고 "1분 30시간"이 아닌 이유.
주차 번호: 나라마다 주를 세는 방식이 다른 이유
ISO 8601 표준에 따라 1월 1일이 가끔 전년도 52주차나 53주차에 속하는 이유.
로마 숫자: 0과 자릿값이 없는 체계는 어떻게 작동하는가
IV가 6이 아니라 4를 의미하는 이유, 그리고 로마 숫자에서 뺄셈 규칙이 작동하는 방식.
IEEE 754: 코드에서 0.1 + 0.2가 0.3과 같지 않은 이유
거의 모든 프로그래밍 언어에서 0.1 + 0.2가 0.30000000000000004로 나오는 이유.
숫자를 글자로: 숫자를 단어로 바꾸는 이유
은행 문서가 금액을 숫자와 글자로 동시에 쓰는 이유.
네트워크/HTTP
URL 파싱: 웹 주소는 어떤 부분으로 이루어져 있을까
URL의 # 이후 프래그먼트 부분은 서버에 전혀 전달되지 않고 브라우저만 처리한다.
쿼리 문자열과 JSON: 복잡한 데이터를 전달할 때 무엇이 더 나을까
쿼리 문자열로 배열을 전달하는 표준 방법이 없는 이유.
User-Agent: Chrome 문자열에 "Mozilla"와 "Safari"가 있는 이유
Chrome의 User-Agent가 실제로는 아닌 "Mozilla"와 "Safari"를 자처하는 이유.
HTTP Basic 인증: Authorization 헤더는 어떻게 만들어지는가
Base64는 암호화가 아니다 — Basic 인증 비밀번호는 몇 초 만에 디코딩될 수 있다.
HTTP 헤더: 요청과 응답에 딸려오는 메타데이터
Content-Type 헤더가 응답을 HTML, JSON, 이미지 중 어떻게 처리할지 브라우저에 알려주는 방식.
쿠키: Secure, HttpOnly, SameSite 속성이 중요한 이유
HttpOnly 속성이 XSS 공격에서 세션 쿠키를 훔치지 못하게 막는 이유.
CORS 오류: 브라우저가 응답을 차단하는 이유
Postman에서는 되는 요청이 브라우저에서는 CORS 오류가 나는 이유.
이메일 헤더: SPF, DKIM, DMARC로 발신자를 검증하는 방식
이메일의 실제 발신 경로를 추적하기 위해 Received 헤더를 아래에서 위로 읽는 이유.
SEO
메타 태그: 검색과 소셜 미디어에 실제로 영향을 주는 것은 무엇인가
검색 엔진이 meta description을 무시하고 페이지 텍스트에서 자체 스니펫을 생성하는 이유.
robots.txt: 검색 봇은 무엇을 크롤링할 수 있는지 어떻게 결정하는가
robots.txt의 Disallow 규칙이, 다른 곳에서 링크된 페이지를 검색 결과에서 숨기지 못하는 이유.
Sitemap.xml: 검색 엔진에 사이트 지도가 필요한 이유
sitemap.xml에 등록되어 있다고 해서 검색 엔진이 그 페이지를 색인한다고 보장하지 않는 이유.
Favicon: 아이콘 하나에 왜 이렇게 많은 크기와 형식이 필요한가
모든 기기에서 올바르게 표시되려면 favicon.ico 하나만으로는 더 이상 충분하지 않은 이유.
sitemap.xml 생성: 사이트 지도를 자동으로 만드는 방법
명세의 일부임에도 검색 엔진이 sitemap.xml의 priority 필드를 대부분 무시하는 이유.
웹 개발
HEX, RGB, HSL: 색을 표현하는 방법이 이렇게 많은 이유
디자이너가 손으로 색조를 고를 때 HEX 대신 HSL을 자주 선택하는 이유.
CSS 압축: 파일에서 실제로 제거되는 것은 무엇이고 왜인가
압축된 CSS가 사람에게는 읽을 수 없게 되어도 브라우저에서 정확히 똑같이 작동하는 이유.
JavaScript 압축: 압축과 난독화의 차이
원하면 압축된 코드는 여전히 읽을 수 있지만, 난독화된 코드는 그럴 수 없는 이유.
HTML 압축: 마크업 안의 공백이 애초에 왜 중요한가
<pre>나 textarea 안의 공백을 제거하면, 다른 거의 모든 곳과 달리 페이지의 모양이 깨지는 이유.
CSS 그라디언트: linear가 radial, conic과 다른 점
conic-gradient는 파이 차트에 적합하고, radial-gradient는 빛 웅덩이 효과를 만드는 이유.
Luhn 알고리즘: 카드 번호의 정확성을 확인하는 방법
Luhn 검사를 통과하는 카드 번호가 그 카드가 실제로 존재한다는 뜻은 아닌 이유.
IBAN: 국제 은행 계좌 번호가 구성되는 방식
IBAN의 첫 두 글자가 계좌 번호 자체의 일부가 아니라 국가 코드인 이유.
QR 코드: 픽셀로 된 정사각형 안에 링크가 들어가는 방식
가운데에 로고가 있는 QR 코드가 패턴 일부가 가려져도 여전히 스캔되는 이유.
바코드: Code 128이 EAN-13과 다른 점
매장 진열대 위 제품이 거의 항상 Code 128 대신 EAN-13을 사용하는 이유.
플레이스홀더 이미지: 개발 중 가짜 이미지가 중요한 이유
레이아웃이 아직 만들어지는 중일 때 개발자가 실제 사진 대신 일부러 회색 상자를 넣는 이유.