JavaScript'te Base64 Çözme — atob() ve Buffer

·Front-end & Node.js Developer·İnceleyenSophie Laurent·Yayınlandı

Ücretsiz Base64 Çözücü Online aracını doğrudan tarayıcınızda kullanın — kurulum gerektirmez.

Base64 Çözücü Online Online Dene →

Üretimde bir kimlik doğrulama sorununu debug ederken ilk başvurduğum şey Base64 Çözücü oluyor — JWT payload'ları, webhook imzaları ve kodlanmış yapılandırma değerlerinin hepsi Base64 dizelerinin içine saklanır. JavaScript, base64 kod çözmek için iki temel yerleşik yaklaşım sunar: atob() (tarayıcı + Node.js 16+) ve Buffer.from(encoded, 'base64').toString() (Node.js) — ve orijinal veri Unicode karakter içerdiğinde bu ikisi çok farklı davranır. Kod yazmadan hızlı bir çözme işlemi için ToolDeck Base64 Çözücü bunu tarayıcınızda anında halleder. Bu kılavuz her iki ortamı da kapsar — Node.js 16+ ve modern tarayıcılar (Chrome 80+, Firefox 75+, Safari 14+) hedeflenerek — üretime hazır örneklerle: UTF-8 kurtarma, URL-güvenli varyantlar, JWT çözme, dosyalar, API yanıtları, Node.js stream'leri ve gerçek kod tabanlarında tutarlı biçimde bozuk çıktı üreten dört hata.

  • atob(encoded) tarayıcıya özgüdür ve Node.js 16+ sürümünde global olarak kullanılabilir; ancak ikili dize döndürür — ASCII üzerindeki herhangi bir içerik için UTF-8 metnini kurtarmak üzere TextDecoder kullanın.
  • Buffer.from(encoded, "base64").toString("utf8"), Node.js'e özgü deyimsel yaklaşımdır ve UTF-8'i otomatik olarak, ekstra adım gerektirmeden işler.
  • URL-güvenli Base64 (JWT'lerde kullanılır) + yerine -, / yerine _ kullanır ve = dolgusu olmaz. atob() çağrısından önce bunları geri yükleyin veya Node.js 18+'de Buffer.from(encoded, "base64url").toString() kullanın.
  • Kodunu çözmeden önce boşlukları ve satır sonlarını temizleyin — GitHub Contents API ve pek çok MIME kodlayıcısı Base64 çıktısını satır başına 60–76 karakterde sarar.
  • Uint8Array.prototype.fromBase64() (TC39 Aşama 3), Node.js 22+ ve Chrome 130+'da kullanılabilir ve zamanla her iki ortamı da birleştirecektir.

Base64 Kod Çözme Nedir?

Base64 kod çözme, kodlamanın tersidir — 64 karakterli ASCII temsilini orijinal ikili veriye veya metne geri dönüştürür. Her 4 Base64 karakteri tam olarak 3 byte'a karşılık gelir. Kodlanmış bir dizenin sonundaki = dolgu karakterleri, çözücüye son 3 byte'lık grubu tamamlamak için kaç ekstra byte eklendiğini söyler.

Base64 şifreleme değildir — işlem, kodlanmış dizeye sahip herkes tarafından tamamen tersine çevrilebilir. Amacı aktarım güvenliğidir: 7-bit ASCII metin için tasarlanmış protokoller ve depolama biçimleri rastgele ikili byte'ları işleyemez; Base64 bu boşluğu kapatır. Yaygın JavaScript kod çözme senaryoları arasında JWT payload'larını inceleme, ortam değişkenlerinden Base64 ile kodlanmış JSON yapılandırmalarını açma, REST API'lerinden ikili dosya içeriği çıkarma ve tarayıcıda data URI'lerini çözme yer alır.

Before · text
After · text
ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=
deploy-bot:sk-prod-a7f2c91e4b3d8

atob() — Tarayıcıya Özgü Kod Çözme Fonksiyonu

atob()(ASCII-to-binary), IE10'dan bu yana tarayıcılarda mevcuttur ve WinterCG uyumluluk girişiminin bir parçası olarak Node.js 16.0'da global hale gelmiştir. Deno, Bun ve Cloudflare Workers'da da içe aktarma gerekmeksizin doğal olarak çalışır.

Fonksiyon bir ikili dize döndürür: her karakterin kod noktasının bir ham byte değerine (0–255) eşit olduğu bir JavaScript dizesi. Bu önemlidir: orijinal veri U+007F üzerindeki karakterler içeren UTF-8 metni (aksanlı harfler, Kiril, CJK, emoji) ise, döndürülen dize ham byte dizisidir, okunabilir metin değil. Kurtarmak için TextDecoder kullanın (sonraki bölümde ele alınmıştır).

Minimal çalışan örnek

JavaScript (browser / Node.js 16+)
// Decoding an HTTP Basic Auth credential pair received in a request header
// Authorization: Basic ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=

function parseBasicAuth(header: string): { serviceId: string; apiKey: string } {
  const base64Part = header.replace(/^Basics+/i, '')
  const decoded    = atob(base64Part)
  const [serviceId, apiKey] = decoded.split(':')
  return { serviceId, apiKey }
}

const auth = parseBasicAuth('Basic ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=')

console.log(auth.serviceId) // deploy-bot
console.log(auth.apiKey)    // sk-prod-a7f2c91e4b3d8

Gidiş-dönüş doğrulaması

JavaScript
// Verify lossless recovery for ASCII-only content
const original = 'service:payments region:eu-west-1 env:production'

const encoded = btoa(original)
const decoded = atob(encoded)

console.log(encoded)
// c2VydmljZTpwYXltZW50cyByZWdpb246ZXUtd2VzdC0xIGVudjpwcm9kdWN0aW9u

console.log(decoded === original) // true
Not:atob() ve btoa() şunun parçasıdır: WinterCG Minimum Common API — tarayıcı dışı çalışma zamanlarında Fetch, URL ve crypto'yu yöneten aynı spec. Node.js 16+, Bun, Deno ve Cloudflare Workers'da aynı şekilde davranırlar.

Kod Çözme Sonrası UTF-8 Metnini Kurtarma

En yaygın atob()tuzağı, dönüş türünü yanlış anlamaktır. Orijinal metin Base64'ten önce UTF-8 olarak kodlandığında, atob() okunabilir metni değil Latin-1 ikili dizesi döndürür:

JavaScript
// 'Алексей Иванов' was UTF-8 encoded then Base64 encoded before transmission
const encoded = '0JDQu9C10LrRgdC10Lkg0JjQstCw0L3QvtCy'

// ❌ atob() returns the raw UTF-8 bytes as a Latin-1 string — garbled output
console.log(atob(encoded))
// "Алексей Р˜РІР°РЅРѕРІ"  ← byte values misread as Latin-1

Doğru yaklaşım, ham byte'ları UTF-8 olarak yorumlamak için TextDecoder kullanır:

TextDecoder yaklaşımı — herhangi bir Unicode çıktısı için güvenli

JavaScript (browser + Node.js 16+)
// Unicode-safe Base64 decode utilities
function fromBase64(encoded: string): string {
  const binary = atob(encoded)
  const bytes  = Uint8Array.from(binary, ch => ch.charCodeAt(0))
  return new TextDecoder().decode(bytes)
}

function toBase64(text: string): string {
  const bytes = new TextEncoder().encode(text)
  const chars = Array.from(bytes, byte => String.fromCharCode(byte))
  return btoa(chars.join(''))
}

// Works with any language or script
const orderNote = 'Confirmed: 田中太郎 — São Paulo warehouse, qty: 250'
const encoded   = toBase64(orderNote)
const decoded   = fromBase64(encoded)

console.log(decoded === orderNote) // true
console.log(decoded)
// Confirmed: 田中太郎 — São Paulo warehouse, qty: 250
Not:Node.js'de TextDecoder adımını tamamen atlayın — şunu kullanın: Buffer.from(encoded, 'base64').toString('utf8'). Çözülen byte'ları otomatik olarak UTF-8 olarak yorumlar ve büyük girdiler için daha hızlıdır.

Node.js'de Buffer.from() — Eksiksiz Kod Çözme Kılavuzu

Node.js'de Buffer, Base64 kod çözme de dahil olmak üzere tüm ikili işlemler için deyimsel API'dir. UTF-8'i doğal olarak işler, uygun bir Bufferdöndürür (ikili güvenli) ve Node.js 18'den itibaren URL-güvenli varyantlar için 'base64url' kodlama kısayolunu destekler.

Ortam değişkeni yapılandırmasını çözme

Node.js
// Server config stored as Base64 in an env variable (avoids JSON escaping in shell)
// DB_CONFIG=eyJob3N0IjoiZGItcHJpbWFyeS5pbnRlcm5hbCIsInBvcnQiOjU0MzIsImRhdGFiYXNlIjoiYW5hbHl0aWNzX3Byb2QiLCJtYXhDb25uZWN0aW9ucyI6MTAwfQ==

const raw = Buffer.from(process.env.DB_CONFIG!, 'base64').toString('utf8')
const dbConfig = JSON.parse(raw)

console.log(dbConfig.host)           // db-primary.internal
console.log(dbConfig.port)           // 5432
console.log(dbConfig.maxConnections) // 100

Bir .b64 dosyasından ikili dosyayı geri yükleme

Node.js
import { readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'

// Read the Base64-encoded certificate and restore the original binary
const encoded = readFileSync(join(process.cwd(), 'dist', 'cert.b64'), 'utf8').trim()
const certBuf  = Buffer.from(encoded, 'base64')

writeFileSync('./ssl/server.crt', certBuf)

console.log(`Restored ${certBuf.length} bytes`)
// Restored 2142 bytes

Hata işleme ile asenkron kod çözme

Node.js
import { readFile, writeFile } from 'node:fs/promises'

async function decodeBase64File(
  encodedPath: string,
  outputPath:  string,
): Promise<number> {
  try {
    const encoded = await readFile(encodedPath, 'utf8')
    const binary  = Buffer.from(encoded.trim(), 'base64')
    await writeFile(outputPath, binary)
    return binary.length
  } catch (err) {
    const code = (err as NodeJS.ErrnoException).code
    if (code === 'ENOENT') throw new Error(`File not found: ${encodedPath}`)
    if (code === 'EACCES') throw new Error(`Permission denied: ${encodedPath}`)
    throw err
  }
}

// Restore a PDF stored as Base64
const bytes = await decodeBase64File('./uploads/invoice.b64', './out/invoice.pdf')
console.log(`Decoded ${bytes} bytes — PDF restored`)

Base64 Kod Çözme Fonksiyonları — Parametre Referansı

Kod yazarken veya incelerken başvuru olarak kullanmak üzere biçimlendirilmiş, iki birincil yerel kod çözme API'sinin parametreleri için hızlı referans.

atob(encodedData)

ParametreTürZorunluAçıklama
encodedDatastringEvet+, /, = karakterlerini kullanan standart Base64 dizesi. URL-güvenli varyantlar (-, _) InvalidCharacterError fırlatır. Boşluğa izin verilmez.
Döndürür:ikili dize — her karakterin kod noktası bir ham byte değerine (0–255) eşittir. Unicode dize değildir; UTF-8 metnini kurtarmak için TextDecoder'dan geçirin.

Buffer.from(input, inputEncoding) / .toString(outputEncoding)

ParametreTürVarsayılanAçıklama
inputstring | Buffer | TypedArray | ArrayBufferzorunluÇözülecek Base64 ile kodlanmış dize veya kodlanmış byte'ları içeren bir buffer.
inputEncodingBufferEncoding"utf8"Standart Base64 (RFC 4648 §4) için "base64", URL-güvenli Base64 (RFC 4648 §5, Node.js 18+) için "base64url" olarak ayarlayın.
outputEncodingstring"utf8".toString() çıktısı için kodlama. Okunabilir metin için "utf8", atob() çıktısıyla uyumlu Latin-1 ikili dize için "binary" kullanın.
startinteger0Okumaya başlanacak çözülmüş Buffer içindeki byte ofseti. .toString()'e ikinci argüman olarak aktarılır.
endintegerbuf.lengthOkumayı durduracak byte ofseti (hariç). .toString()'e üçüncü argüman olarak aktarılır.
Döndürür:.from()'dan Buffer. .toString()'den string döndürür. Çözülen içerik ikili olduğunda (.toString() çağırmadan) Buffer olarak tutun — resimler, PDF'ler, ses.

URL-güvenli Base64 — JWT ve URL Parametrelerini Çözme

JWT'ler, üç segment için de URL-güvenli Base64'ü (RFC 4648 §5) kullanır. URL-güvenli Base64, +'yı - ile ve /'yi _ ile değiştirir ve sondaki = dolgusunu kaldırır. Bunu geri yüklemeden doğrudan atob()'ye geçirmek hatalı çıktı üretir veya hata fırlatır.

Tarayıcı — kod çözmeden önce karakterleri ve dolguyu geri yükleme

JavaScript (browser)
function decodeBase64Url(input: string): string {
  const base64 = input.replace(/-/g, '+').replace(/_/g, '/')
  const padded = base64 + '==='.slice(0, (4 - base64.length % 4) % 4)
  const binary = atob(padded)
  const bytes  = Uint8Array.from(binary, ch => ch.charCodeAt(0))
  return new TextDecoder().decode(bytes)
}

// Inspect a JWT payload segment (the middle part between the two dots)
const jwtToken  = 'eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciIsIndvcmtzcGFjZUlkIjoid3NfM2E3ZjkxYzIiLCJleHAiOjE3MTcyMDM2MDB9'
const payload   = decodeBase64Url(jwtToken)
const claims    = JSON.parse(payload)

console.log(claims.userId)      // usr_9f2a1c3e8b4d
console.log(claims.role)        // editor
console.log(claims.workspaceId) // ws_3a7f91c2

Node.js 18+ — yerel 'base64url' kodlaması

Node.js 18+
// Node.js 18 added 'base64url' as a first-class Buffer encoding — no manual replace needed
function decodeJwtSegment(segment: string): Record<string, unknown> {
  const json = Buffer.from(segment, 'base64url').toString('utf8')
  return JSON.parse(json)
}

const token   = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciIsIndvcmtzcGFjZUlkIjoid3NfM2E3ZjkxYzIiLCJleHAiOjE3MTcyMDM2MDB9.SIGNATURE'
const [headerB64, payloadB64] = token.split('.')

const header  = decodeJwtSegment(headerB64)
const payload = decodeJwtSegment(payloadB64)

console.log(header.alg)          // HS256
console.log(payload.role)        // editor
console.log(payload.workspaceId) // ws_3a7f91c2

Dosyalar ve API Yanıtlarından Base64 Çözme

Üretim kodunda Base64 çözme çoğunlukla, içeriği kodlanmış biçimde sunan harici API'leri tüketirken gerçekleşir. Her iki senaryonun da boşluk ve ikili ile metin çıktısı konusunda önemli tuzakları vardır. Hata ayıklama sırasında yalnızca kodlanmış bir yanıtı incelemeniz gerekiyorsa, doğrudan Base64 Çözücü aracına yapıştırın — standart ve URL-güvenli modları anında işler.

GitHub Contents API'den içerik çözme

JavaScript
// GitHub Contents API returns file content as Base64, wrapped at 60 chars per line
async function fetchDecodedFile(
  owner: string,
  repo:  string,
  path:  string,
  token: string,
): Promise<string> {
  const res = await fetch(
    `https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
    { headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github.v3+json' } }
  )
  if (!res.ok) throw new Error(`GitHub API ${res.status}: ${res.statusText}`)

  const data = await res.json() as { content: string; encoding: string }
  if (data.encoding !== 'base64') throw new Error(`Unexpected encoding: ${data.encoding}`)

  // ⚠️ GitHub wraps at 60 chars — strip newlines before decoding
  const clean = data.content.replace(/\n/g, '')
  return Buffer.from(clean, 'base64').toString('utf8')
}

const openApiSpec = await fetchDecodedFile('acme-corp', 'platform-api', 'openapi.json', process.env.GITHUB_TOKEN!)
const spec = JSON.parse(openApiSpec)
console.log(`API version: ${spec.info.version}`)

API'den Base64 ile kodlanmış ikiliyi çözme (tarayıcı)

JavaScript (browser)
// Some APIs return binary content (images, PDFs) as Base64 JSON fields
async function downloadDecodedFile(endpoint: string, authToken: string): Promise<void> {
  const res = await fetch(endpoint, { headers: { Authorization: `Bearer ${authToken}` } })
  if (!res.ok) throw new Error(`Download failed: ${res.status}`)

  const { filename, content, mimeType } = await res.json() as {
    filename: string; content: string; mimeType: string
  }

  // Decode Base64 → binary bytes → Blob
  const binary = atob(content)
  const bytes  = Uint8Array.from(binary, ch => ch.charCodeAt(0))
  const blob   = new Blob([bytes], { type: mimeType })

  // Trigger browser download
  const url = URL.createObjectURL(blob)
  const a   = Object.assign(document.createElement('a'), { href: url, download: filename })
  a.click()
  URL.revokeObjectURL(url)
}

await downloadDecodedFile('/api/reports/latest', sessionStorage.getItem('auth_token')!)

Node.js ve Shell'de Komut Satırı Base64 Çözme

CI/CD scriptleri, hata ayıklama oturumları veya tek seferlik çözme görevleri için shell araçları ve Node.js tek satırları tam bir scriptten daha hızlıdır. macOS ile Linux arasında bayrak adının farklı olduğuna dikkat edin.

bash
# ── macOS / Linux system base64 ───────────────────────────────────────
# Standard decoding (macOS uses -D, Linux uses -d)
echo "ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=" | base64 -d   # Linux
echo "ZGVwbG95LWJvdDpzay1wcm9kLWE3ZjJjOTFlNGIzZDg=" | base64 -D   # macOS

# Decode a .b64 file to its original binary
base64 -d ./dist/cert.b64 > ./ssl/server.crt       # Linux
base64 -D -i ./dist/cert.b64 -o ./ssl/server.crt   # macOS

# URL-safe Base64 — restore + and / before decoding
echo "eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ" | tr '-_' '+/' | base64 -d

# ── Node.js one-liner — works on Windows too ───────────────────────────
node -e "process.stdout.write(Buffer.from(process.argv[1], 'base64').toString())" "ZGVwbG95LWJvdA=="
# deploy-bot

# URL-safe (Node.js 18+)
node -e "process.stdout.write(Buffer.from(process.argv[1], 'base64url').toString())" "eyJhbGciOiJIUzI1NiJ9"
# {"alg":"HS256"}
Not:macOS'ta base64 çözmek için -D (büyük harf D) kullanırken Linux -d (küçük harf) kullanır. Bu CI scriptlerini sessizce bozar — hedef platformun Linux olacağı garanti değilse Node.js tek satırı kullanın.

Yüksek Performanslı Alternatif: js-base64

Bir kütüphaneye başvurmanın ana nedeni ortamlar arası tutarlılıktır. Bundler yapılandırması olmadan hem tarayıcıda hem Node.js'de çalışan bir paket sunuyorsanız, Buffer ortam tespiti ve atob() TextDecoder geçici çözümü gerektirir. js-base64 (100M+ haftalık npm indirmesi) her ikisini de şeffaf biçimde işler.

bash
npm install js-base64
# or
pnpm add js-base64
JavaScript
import { fromBase64, fromBase64Url, isValid } from 'js-base64'

// Standard decoding — Unicode-safe, works in browser and Node.js
const raw   = fromBase64('eyJldmVudElkIjoiZXZ0XzdjM2E5ZjFiMmQiLCJ0eXBlIjoiY2hlY2tvdXRfY29tcGxldGVkIiwiY3VycmVuY3kiOiJFVVIiLCJhbW91bnQiOjE0OTAwfQ==')
const event = JSON.parse(raw)
console.log(event.type)     // checkout_completed
console.log(event.currency) // EUR

// URL-safe decoding — no manual character replacement needed
const jwtPayload = fromBase64Url('eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciJ9')
const claims     = JSON.parse(jwtPayload)
console.log(claims.role) // editor

// Validate before decoding untrusted input
const untrusted = 'not!valid@base64#'
if (!isValid(untrusted)) {
  console.error('Rejected: invalid Base64 input')
}

// Binary output — second argument true returns Uint8Array
const pngBytes = fromBase64('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', true)
console.log(pngBytes instanceof Uint8Array) // true

Sözdizimi Vurgulamalı Terminal Çıktısı

CLI hata ayıklama araçları veya inceleme scriptleri yazarken, büyük JSON payload'ları için düz console.log çıktısı okunması zordur. Base64 çözme ile birleştirilen chalk (terminal renklendirme için en çok indirilen npm paketi), okunabilir ve taranabilir terminal çıktısı üretir — JWT incelemesi, API yanıtı hata ayıklama ve yapılandırma denetimi için kullanışlıdır.

bash
npm install chalk
# chalk v5+ is ESM-only — use import, not require
Node.js
import chalk from 'chalk'

// Decode and display any Base64 value with smart type detection
function inspectBase64(encoded: string, label = 'Decoded value'): void {
  let decoded: string
  try {
    decoded = Buffer.from(encoded.trim(), 'base64').toString('utf8')
  } catch {
    console.error(chalk.red('✗ Invalid Base64 input'))
    return
  }

  console.log(chalk.bold.cyan(`\n── ${label} ──`))

  // Attempt JSON pretty-print
  try {
    const parsed = JSON.parse(decoded)
    console.log(chalk.green('Type:'), chalk.yellow('JSON'))
    for (const [key, value] of Object.entries(parsed)) {
      const display = typeof value === 'object' ? JSON.stringify(value) : String(value)
      console.log(chalk.green(`  ${key}:`), chalk.white(display))
    }
    return
  } catch { /* not JSON */ }

  // Plain text fallback
  console.log(chalk.green('Type:'), chalk.yellow('text'))
  console.log(chalk.white(decoded))
}

// Inspect a Base64-encoded JWT payload
const tokenParts = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2U4YjRkIiwicm9sZSI6ImVkaXRvciIsImV4cCI6MTcxNzIwMzYwMH0.SIGNATURE'.split('.')
inspectBase64(tokenParts[0], 'JWT Header')
inspectBase64(tokenParts[1], 'JWT Payload')
// ── JWT Header ──
// Type:   JSON
//   alg:  HS256
//   typ:  JWT
//
// ── JWT Payload ──
// Type:   JSON
//   userId: usr_9f2a1c3e8b4d
//   role:   editor
//   exp:    1717203600
Not:chalk'ı yalnızca terminal/CLI çıktısı için kullanın — dosyalara yazılan içerik, API yanıtları veya log toplayıcılar için asla kullanmayın. ANSI escape kodları terminal dışı tüketicileri bozar: log platformları (Datadog, Splunk), JSON log ayrıştırıcıları ve CI log görüntüleyicilerinin tümü bunları okunamaz karakter dizileri olarak gösterir.

Node.js Stream'leriyle Büyük Base64 Dosyalarını Çözme

Base64 ile kodlanmış bir dosya ~50 MB'ı aştığında, readFileSync()ile tamamını belleğe yüklemek sorun haline gelir. Node.js stream'leri veriyi parçalar halinde çözmenizi sağlar — ancak Base64, parça sınırlarında dolgu hatalarını önlemek için parça başına4 karakterkatları gerektirir (her 4 karakterlik grup tam olarak 3 byte'a çözülür).

Node.js
import { createReadStream, createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream/promises'

async function streamDecodeBase64(inputPath: string, outputPath: string): Promise<void> {
  const readStream  = createReadStream(inputPath, { encoding: 'utf8', highWaterMark: 4 * 1024 * 192 })
  const writeStream = createWriteStream(outputPath)

  let buffer = ''

  await pipeline(
    readStream,
    async function* (source) {
      for await (const chunk of source) {
        buffer += (chunk as string).replace(/\s/g, '') // strip any whitespace/newlines

        // Decode only complete 4-char groups to avoid mid-stream padding issues
        const remainder = buffer.length % 4
        const safe      = buffer.slice(0, buffer.length - remainder)
        buffer          = buffer.slice(buffer.length - remainder)

        if (safe.length > 0) yield Buffer.from(safe, 'base64')
      }
      if (buffer.length > 0) yield Buffer.from(buffer, 'base64')
    },
    writeStream,
  )
}

// Decode a 200 MB video that was stored as Base64
await streamDecodeBase64('./uploads/product-demo.b64', './dist/product-demo.mp4')
console.log('Stream decode complete')
Not:Base64 metni okunurken parça boyutu 4 karakterin katı olmalıdır; böylece her parça yalnızca tam 4 karakterlik gruplar içerir. Örnekte 4 × 1024 × 192 = 786.432karakter (768 KB) kullanılmaktadır. 50 MB'ın altındaki dosyalar için readFile() + Buffer.from(content.trim(), 'base64') daha basit ve yeterince hızlıdır.

Yaygın Hatalar

Bu dört hatayı JavaScript kod tabanlarında defalarca gördüm — ASCII olmayan bir karakter veya satır sarmalamalı bir API yanıtı üretimdeki çözme yoluna ulaşana kadar gizli kalmaya devam ederler.

Hata 1 — UTF-8 içerik için TextDecoder olmadan atob() kullanmak

Sorun: atob(), her karakterin bir ham byte değeri olduğu ikili dize döndürür. UTF-8 çok byte'lı diziler (Kiril, CJK, aksanlı karakterler) bozuk Latin-1 karakterleri olarak görünür. Çözüm: çıktıyı TextDecoder'a sarın.

Before · JavaScript
After · JavaScript
// ❌ atob() returns the raw UTF-8 bytes as a Latin-1 string
const encoded = '0JDQu9C10LrRgdC10Lkg0JjQstCw0L3QvtCy'
const decoded  = atob(encoded)
console.log(decoded)
// "Алексей Р˜РІР°РЅРѕРІ"  ← wrong
// ✅ Use TextDecoder to correctly interpret the UTF-8 bytes
const encoded  = '0JDQu9C10LrRgdC10Lkg0JjQstCw0L3QvtCy'
const binary   = atob(encoded)
const bytes    = Uint8Array.from(binary, ch => ch.charCodeAt(0))
const decoded  = new TextDecoder().decode(bytes)
console.log(decoded) // Алексей Иванов ✓

Hata 2 — URL-güvenli Base64'ü doğrudan atob()'ye geçirmek

Sorun: JWT segmentleri + ve / yerine - ve _ kullanır, dolgu olmaksızın. atob() yanlış veri döndürebilir veya hata fırlatabilir. Çözüm: önce standart karakterleri ve dolguyu geri yükleyin.

Before · JavaScript
After · JavaScript
// ❌ URL-safe JWT segment passed directly — unreliable
const jwtPayload = 'eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ'
const decoded    = atob(jwtPayload) // May produce wrong result or throw
// ✅ Restore standard Base64 chars and padding first
function decodeBase64Url(input: string): string {
  const b64  = input.replace(/-/g, '+').replace(/_/g, '/')
  const pad  = b64 + '==='.slice(0, (4 - b64.length % 4) % 4)
  const bin  = atob(pad)
  const bytes = Uint8Array.from(bin, ch => ch.charCodeAt(0))
  return new TextDecoder().decode(bytes)
}
const decoded = decodeBase64Url('eyJ1c2VySWQiOiJ1c3JfOWYyYTFjM2UifQ')
// {"userId":"usr_9f2a1c3e"} ✓

Hata 3 — Satır sarmalamalı Base64'ten satır sonlarını kaldırmamak

Sorun: GitHub Contents API ve MIME kodlayıcıları Base64 çıktısını satır başına 60–76 karakterde sarar. atob(), \n karakterlerinde InvalidCharacterError fırlatır. Çözüm: kod çözmeden önce tüm boşlukları kaldırın.

Before · JavaScript
After · JavaScript
// ❌ GitHub API content field contains embedded newlines
const data    = await res.json()
const decoded = atob(data.content) // ❌ throws InvalidCharacterError
// ✅ Strip newlines (and any other whitespace) before decoding
const data    = await res.json()
const clean   = data.content.replace(/\s/g, '')
const decoded = atob(clean) // ✓

Hata 4 — Çözülmüş ikili içerik üzerinde .toString() çağırmak

Sorun: Orijinal veri ikili olduğunda (resimler, PDF'ler, ses), .toString('utf8') çağırmak tanınmayan byte dizilerini U+FFFD ile değiştirerek çıktıyı sessizce bozar. Çözüm: sonucu Buffer olarak tutun — string'e dönüştürmeyin.

Before · JavaScript
After · JavaScript
// ❌ .toString('utf8') corrupts binary content
import { readFileSync, writeFileSync } from 'node:fs'
const encoded   = readFileSync('./uploads/invoice.b64', 'utf8').trim()
const corrupted = Buffer.from(encoded, 'base64').toString('utf8') // ❌
writeFileSync('./out/invoice.pdf', corrupted) // ❌ unreadable PDF
// ✅ Keep the Buffer as binary — do not convert to a string
import { readFileSync, writeFileSync } from 'node:fs'
const encoded = readFileSync('./uploads/invoice.b64', 'utf8').trim()
const binary  = Buffer.from(encoded, 'base64') // ✓ raw bytes preserved
writeFileSync('./out/invoice.pdf', binary)      // ✓ valid PDF

JavaScript Base64 Kod Çözme Yöntemleri — Hızlı Karşılaştırma

YöntemUTF-8 çıktıİkili çıktıURL-güvenliOrtamlarKurulum gerektirir
atob()❌ TextDecoder gerekli✅ ikili dize❌ manuel geri yüklemeTarayıcı, Node 16+, Bun, DenoHayır
TextDecoder + atob()✅ UTF-8✅ Uint8Array ile❌ manuel geri yüklemeTarayıcı, Node 16+, DenoHayır
Buffer.from().toString()✅ utf8✅ Buffer olarak tut✅ base64url (Node 18+)Node.js, BunHayır
Uint8Array.fromBase64() (TC39)✅ TextDecoder ile✅ yerel✅ alphabet seçeneğiChrome 130+, Node 22+Hayır
js-base64✅ her zaman✅ Uint8Array✅ yerleşikEvrenselnpm install

atob()'yi yalnızca çözülen içeriğin kesinlikle ASCII metin olduğu durumlarda seçin. Tarayıcıda kullanıcı tarafından sağlanan veya çok dilli herhangi bir metin için TextDecoder + atob() kullanın. Node.js sunucu tarafı kodu için Bufferdoğru varsayılandır — UTF-8'i otomatik işler ve ikili veriyi bütün halde tutar. Ortamlar arası kütüphaneler için js-base64 tüm uç durumları ortadan kaldırır.

Sıkça Sorulan Sorular

Neden atob() okunabilir metin yerine bozuk karakterler döndürüyor?
atob(), her karakterin bir ham byte'ı (0–255) temsil ettiği ikili dize döndürür; Unicode kod noktası değil. Orijinal metin UTF-8 olarak kodlandıysa, U+007F üzerindeki herhangi bir karakter — Kiril, Arapça, CJK ideograflar, aksanlı harfler — iki veya daha fazla bozuk Latin-1 karakteri olarak görünür. Çözüm: çıktıyı TextDecoder'dan geçirin: const bytes = Uint8Array.from(atob(encoded), ch => ch.charCodeAt(0)); const text = new TextDecoder().decode(bytes). Node.js'de bunu otomatik olarak işleyen Buffer.from(encoded, 'base64').toString('utf8') kullanın.
JavaScript'te JWT token payload'ını nasıl çözerim?
Bir JWT, noktalarla ayrılmış üç URL-güvenli Base64 segmentine sahiptir: header.payload.signature. Payload'ı çözmek için: const [, payloadB64] = token.split('.'). Tarayıcıda: standart karakterleri geri yükleyin, dolgu ekleyin, atob() ve TextDecoder ile çözün. Node.js 18+'de: Buffer.from(payloadB64, 'base64url').toString('utf8'). Önemli: çözme yalnızca talepleri ortaya çıkarır — imzayı doğrulamaz. Üretimde doğrulanmış çözme için uygun bir JWT kütüphanesi (jsonwebtoken, jose) kullanın.
Kod çözme için atob() ile Buffer.from() arasındaki fark nedir?
atob(), tüm JavaScript ortamlarında (tarayıcı, Node.js 16+, Bun, Deno) içe aktarma olmadan kullanılabilir; ancak ikili dize döndürür — UTF-8 içeriğini okunabilir metne dönüştürmek için TextDecoder gerekir. Buffer.from(encoded, 'base64') yalnızca Node.js / Bun'a özgüdür, gerçek Buffer döndürür (ikili güvenli), UTF-8'i doğal olarak işler ve Node.js 18+'de 'base64url' destekler. Sunucu tarafı kodu için Buffer daha basittir. Tarayıcı kodu için atob() + TextDecoder standarttır. Ortamlar arası kütüphaneler için js-base64 farkı soyutlar.
Tarayıcıda URL-güvenli Base64'ü nasıl çözerim?
URL-güvenli Base64, + yerine -, / yerine _ kullanır ve = dolgusu olmaz. atob() çağrısından önce bunları geri yükleyin: const b64 = input.replace(/-/g, '+').replace(/_/g, '/'); const padded = b64 + '==='.slice(0, (4 - b64.length % 4) % 4); const text = new TextDecoder().decode(Uint8Array.from(atob(padded), c => c.charCodeAt(0))). Node.js 18+'de: Buffer.from(input, 'base64url').toString('utf8') bunu tek çağrıda halleder.
JavaScript'te GitHub API'den Base64 içeriği nasıl çözerim?
GitHub Contents API, dosya içeriğini her 60 karakterde satır sonu karakterleriyle sarılmış standart Base64 olarak döndürür. Kod çözmeden önce temizleyin: const clean = data.content.replace(/\n/g, ''). Tarayıcıda: new TextDecoder().decode(Uint8Array.from(atob(clean), c => c.charCodeAt(0))). Node.js'de: Buffer.from(clean, 'base64').toString('utf8'). İkili dosyalar için (resimler, PDF'ler), .toString() çağırmadan Buffer'ı tutun — doğrudan writeFile'a veya yanıt akışına aktarın.
JavaScript'te kütüphane olmadan Base64 ile kodlanmış bir resmi çözebilir miyim?
Evet. Tarayıcıda: const binary = atob(encoded); const bytes = Uint8Array.from(binary, ch => ch.charCodeAt(0)); const blob = new Blob([bytes], { type: 'image/png' }); const url = URL.createObjectURL(blob). Bir img src'si için bunun yerine data URI oluşturun: const src = 'data:image/png;base64,' + encoded — bu çözme adımını tamamen atlar. Node.js'de: Buffer.from(encoded, 'base64') ardından writeFileSync('./out.png', buffer). Temel kural: içerik ikili olduğunda çözülmüş Buffer üzerinde .toString() çağırmayın.

İlgili Araçlar

Kod yazmadan tek tıklamayla çözme için Base64 dizenizi doğrudan Base64 Çözücü aracına yapıştırın — tarayıcınızda anında çıktıyla standart ve URL-güvenli modları işler.

Şu dillerde de mevcut:PythonGoJavaC#
AC
Alex ChenFront-end & Node.js Developer

Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.

SL
Sophie LaurentTeknik İnceleyici

Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.