JWT'nin üç bölümü Base64URL ile encode edilmiştir. Google Authenticator'ın ürettiği TOTP tohum değerleri Base32 olarak saklanır. Bir SHA-256 hash değeri ise genellikle hex — yani Base16 — biçiminde gösterilir. Üçü de binary veriyi metin karakterlerine çevirir; ama farklı alfabeler, farklı boyut maliyetleri ve farklı tasarım öncelikleriyle.
Çoğu durumda format seçimini siz yapmazsınız — kütüphane ya da protokol belirler. Ama bu kararların ardındaki mantığı anlamak, padding hatalarının nereden kaynaklandığını, iki sistem arasında veri taşırken neden bozulma yaşandığını ve hangisi gereken yerde hangisinin kullanıldığını çok daha hızlı görmenizi sağlar.
Alfabe boyutu ve boyut artışı
Her üç sistem de binary veriyi belirli sayıda karakterden oluşan bir alfabe üzerine eşler. Alfabe ne kadar büyükse, her karakter o kadar fazla bit taşır ve toplam çıktı uzunluğu o kadar kısa olur.
- Base16, 0-9 ve A-F arasındaki 16 sembolü kullanır; her karakter 4 bit temsil eder ve her byte tam olarak 2 karaktere karşılık gelir. Boyut artışı %100'dür.
- Base32, A-Z ve 2-7 arasındaki 32 sembolü kullanır; her karakter 5 bit taşır ve 5 byte 8 karaktere dönüşür. Boyut artışı yaklaşık %60'tır.
- Base64, A-Z, a-z, 0-9, + ve / karakterlerinden oluşan 64 sembolü kullanır; her karakter 6 bit taşır ve 3 byte 4 karaktere dönüşür. Boyut artışı yaklaşık %33'tür.
Boyut farkının kaynağı doğrudan logaritmiktir: Base16 için log₂(16) = 4 bit, Base32 için 5 bit, Base64 için 6 bit. Her ekstra bit, aynı binary veriyi daha az karakterle ifade edebilmek anlamına gelir. 100 KB'lık bir binary dosyayı Base16'ya çevirirseniz 200 KB metin elde edersiniz; Base64 ile aynı dosya yaklaşık 133 KB'a çıkar, Base32 ile 160 KB civarında. Bu fark küçük görünse de yüksek trafikli API yanıtlarında veya büyük dosya işlemlerinde bant genişliği ve bellek açısından somut bir maliyet oluşturur.
Base64 ve Base32, çıktıyı sabit blok boyutlarına hizalamak için = padding karakteri ekler — Base64 en fazla iki, Base32 ise altıya kadar. Base16 ise her byte'ı tam olarak iki karakterle temsil ettiğinden padding gerektirmez. Bu padding farkı, sistemler arası veri iletiminde beklenmedik hataların sık görülen kaynağıdır: Base64 çıktısını Base64URL olarak parse etmeye çalışan bir kütüphane, eşittir işaretini geçersiz karakter olarak değerlendirip sessizce yanlış veri döndürebilir.
Üç format arasındaki boyut farkının en belirgin hissedildiği yer inline resimlerdir. Zaten tartışmalı bir boyut maliyeti taşıyan Base64 inline yaklaşımını Base32 ile uygulamak akla gelmez; Base16 ile denemek ise dosyayı orijinalinin iki katına çıkarır.
Base16: Hash değerleri ve düşük seviyeli veri gösterimi
MD5, SHA-1, SHA-256 gibi kriptografik hash fonksiyonlarının çıktısı neredeyse her zaman hex olarak gösterilir. İki pratik sebebi var: insan gözüyle karakter karakter karşılaştırılabilir ve büyük/küçük harf duyarsızdır — a3f2c1 ile A3F2C1 aynı değeri temsil eder. Bu özellik, sistem bağımsız tutarlılık sağlar.
SHA-256'nın çıktısı 256 bit, yani 32 byte'tır. Her byte 2 hex karaktere karşılık geldiğinden SHA-256 hash değeri her zaman tam 64 hex karakterdir. Bu sayıyı bilmek, üretilen değerin bütünlüğünü hızlıca kontrol etmenizi sağlar — 63 ya da 65 karakter görüyorsanız bir şeyler yanlış gitmiştir.
HTML renk kodları (#FF5733), HTTP ETag başlıkları, bellek adresleri ve SSL sertifika parmak izleri de hex formatındadır. Bu alanlarda okunabilirlik ve tutarlılık, boyut verimliliğinden önce gelir.
Düşük seviyeli hata ayıklamada hex biçer. Bir binary dosyanın ilk birkaç byte'ını hex olarak okuyabilmek — PNG için 89504E47, PDF için 25504446, ZIP için 504B0304 — dosya türünü protokol katmanı olmadan doğrulamanızı sağlar. Hasarlı veya kimliği belirsiz bir dosyayı incelerken hex editörü açmak standart bir reflekstir; bunu Base64 ile yapmak hem boyut hem okunabilirlik açısından anlamsız olurdu.
Sınırı açıktır: büyük binary veri taşımak için kullanılmaz. Yüzlerce KB'lık bir resim veya API payload'ı hex encode etmek gereksiz boyut artışı ve işlem yükü oluşturur. Bu senaryo için Base64 tercih edilir.
Base32: İnsan hatalarına karşı tasarlanmış alfabe
Base32 alfabesi, görsel karışıklığa yol açacak karakterleri dışarıda bırakacak şekilde seçilmiştir. Sıfır (0) yoktur — büyük O ile karıştırılır. Bir (1) yoktur — büyük I ile benzer görünür. Kalan alfabe A-Z ve 2-7'dir. Büyük/küçük harf ayrımı da yoktur: JBSWY3DP ile jbswy3dp aynı veriyi temsil eder.
Google Authenticator ve Authy gibi TOTP uygulamaları, ürettikleri tohum değerlerini Base32 olarak sunar. Kullanıcı bu değeri farklı bir cihaza elle yazabilmeli, kağıda kopyalayabilmelidir. El yazısındaki o/0 ve i/1 karışıklığını minimize eden bu alfabe seçimi, iki faktörlü kimlik doğrulamanın kesintisiz çalışması için belirleyici bir tasarım kararıdır.
DNS ortamlarında da Base32 tercih edilir: bazı DNSSEC kayıt türlerinde imza verileri Base32hex ile encode edilir (RFC 4648 Bölüm 7). Burada harf/rakam karışıklığını önlemek kadar, büyük/küçük harf duyarsızlığı da belirleyicidir çünkü DNS kayıtları büyük harfe normalize edilir. Aynı mantık dosya sistemi uyumluluğu için de geçerlidir; büyük harf duyarsızlığı olmayan sistemlerde Base64'ün küçük harf karakterleri sorun çıkarabilirken Base32 bunu kısmen engeller.
Base32'nin en belirgin dezavantajı boyut artışıdır. Base64'e kıyasla yaklaşık %20 daha uzun çıktı üretir ve altı adet padding karakteri ekleme olasılığı taşır. Bu nedenle ikisi arasında seçim yapılırken elle giriş veya insan okunabilirliği gereksinimleri belirleyici olur. Performans öncelikliyse Base64, güvenilirlik ve elle giriş öncelikliyse Base32.
Base64 nasıl standart haline geldi
MIME standardıyla birlikte 1990'ların başında yaygınlaşan Base64, e-posta eklerinin text protokolü üzerinden taşınması sorununa çözüm olarak gelişti. SMTP, 7-bit ASCII kanalı üzerinden çalışır; binary dosyalar direkt gönderilemez. Base64 bu sorunu çözdü ve hızla başka sistemlere de yayıldı.
HTTP, HTML, JavaScript — hepsi Base64'ü farklı biçimlerde benimsedi. Ancak standart Base64 alfabesindeki + ve / karakterleri URL'lerde sorun çıkarır. Bu yüzden JWT ve OAuth 2.0 gibi web protokolleri Base64URL varyantını kullanır: + yerine -, / yerine _ ve padding karakterleri çoğunlukla kaldırılır.
Bu iki varyant arasındaki fark, pratikte sık karşılaşılan bir hata kaynağıdır. Standart Base64 ile decode etmeye çalıştığınız bir JWT payload'ı, - ve _ karakterleri nedeniyle hata verir ya da yanlış veri döner. Çalıştığınız kütüphanenin hangi varyantı beklediğini bilmek, bu tür sorunları kaynağında keser.
Base64 ile kodlanmış veri güvenli değildir — sadece aktarılabilirdir. Authorization: Basic dXNlcjpwYXNz başlığını decode ettiğinizde user:pass düz metin olarak karşınıza çıkar. Basic Auth, Base64'ü şifreleme için değil, özel karakterleri HTTP başlığında güvenle taşımak için kullanır. HTTPS olmadan bu yöntemi kullanan her uygulama, kimlik bilgilerini açık metin olarak iletmiş olur.
Base64 encode/decode işlemleri için tarayıcı tabanlı araç kullanmak, özellikle API response'larını hızlıca inceleme ya da payload debug etme sırasında pratik bir seçenektir — terminal açmadan, kütüphane kurmadan. JWT token'ı parse ederken de aynı araç işe yarar: header ve payload bölümleri ayrı ayrı Base64URL ile kodlanmıştır, her birini decode etmek içeriği doğrudan ortaya koyar.
Hangi formatı ne zaman kullanmalısınız
Format seçimi çoğunlukla kullanım bağlamına göre kendiliğinden belirlenir. Ama karar alanı bıraktığı durumlarda şu tablo yol gösterici olabilir:
| Format | Tercih edildiği durumlar | Boyut artışı | Padding |
|---|---|---|---|
| Base16 (hex) | Hash değerleri, parmak izi, dosya imzası, renk kodu, bellek adresi | %100 | Yok |
| Base32 | TOTP tohum değeri, elle girilecek kodlar, DNS kayıtları | ~%60 | = (6'ya kadar) |
| Base64 | E-posta ekleri, Data URI, HTTP header, API payload | ~%33 | = (2'ye kadar) |
| Base64URL | JWT, OAuth token, URL parametresi, cookie | ~%33 | Genellikle yok |
Aynı veriyi farklı sistemler arasında taşırken en sık karşılaşılan sorun, çıktının bir uçta bir formata encode edilip diğer uçta yanlış formata decode edilmesidir. Özellikle JSON payload'ları incelediğinizde bir alanın Base64 mı, Base64URL mi yoksa hex mi olduğunu anlamak için içerdiği karakterlere bakabilirsiniz: + veya / görüyorsanız standart Base64, - veya _ görüyorsanız Base64URL, yalnızca 0-9 ve A-F içeriyorsa hex.
Protokol size format dayatmıyorsa kısa yol: insanın okuyacağı veya elle gireceği her şey için Base32, URL'de taşınacak ya da boyut önemliyse Base64URL, düşük seviyeli kimlik ve doğrulama verisi için hex. Aynı alfabe değil; farklı sorunlara farklı çözümler.