ToolDeck

رمزگشایی Base64 در Go — راهنمای کامل encoding/base64

·Systems Engineer·بررسی‌شده توسطHana Nováková·منتشر شده

از رمزگشایی Base64 آنلاین آنلاین رایگان مستقیم در مرورگرتان استفاده کنید — نیازی به نصب نیست.

امتحان کردن رمزگشایی Base64 آنلاین آنلاین ←

رمزگشایی Base64 در Go زیاد پیش می‌آید — بازرسی JWT، پیوست‌های فایل باینری، payloadهای API از سرویس‌های ابری. پکیج استاندارد encoding/base64در Go همه اینها را پوشش می‌دهد، اما انتخاب نوع رمزگذاری اشتباه (استاندارد در برابر ایمن برای URL، با padding در برابر بدون padding) رایج‌ترین علت خطاهای “illegal base64 data” است. این راهنما StdEncoding، URLEncoding، RawURLEncoding، رمزگشایی streaming با base64.NewDecoder، بازرسی payload JWT، و چهار اشتباه رایج را بررسی می‌کند. برای رمزگشایی سریع در مرورگر، رمزگشای Base64 ToolDeck بدون نوشتن یک خط کد کار را انجام می‌دهد.

  • encoding/base64 بخشی از کتابخانه استاندارد Go است — نیازی به go get ندارد
  • برای توکن‌های JWT و اکثر APIهای مدرن از RawURLEncoding استفاده کنید (بدون padding، الفبای ایمن برای URL)
  • StdEncoding از + و / با padding برابر = استفاده می‌کند؛ URLEncoding آنها را با - و _ جایگزین می‌کند اما padding را نگه می‌دارد
  • base64.NewDecoder هر io.Reader را برای رمزگشایی streaming بدون بارگذاری در حافظه می‌پوشاند
  • همیشه خطای بازگشتی را بررسی کنید — padding نامعتبر و الفبای اشتباه باعث تولید illegal base64 data می‌شوند

رمزگشایی Base64 چیست؟

رمزگذاری Base64 داده‌های باینری را با استفاده از 64 کاراکتر قابل چاپ (A–Z، a–z، 0–9 به علاوه دو کاراکتر اضافی) به صورت متن ASCII نمایش می‌دهد. رمزگشایی این فرآیند را معکوس می‌کند — آن نمایش ASCII را به بایت‌های اصلی تبدیل می‌کند. هر 4 کاراکتر Base64 دقیقاً به 3 بایت رمزگشایی می‌شوند. Base64 به این دلیل وجود دارد که بسیاری از لایه‌های انتقال (ایمیل، هدرهای HTTP، فیلدهای JSON) برای متن طراحی شده‌اند، نه داده باینری خام. مثال زیر این چرخه رفت و برگشت را نشان می‌دهد:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Raw bytes → Base64 encoded → decoded back to raw bytes
	original := []byte("service_token:xK9mP2qR")
	// Encoded: "c2VydmljZV90b2tlbjp4SzltUDJxUg=="

	encoded := base64.StdEncoding.EncodeToString(original)
	decoded, _ := base64.StdEncoding.DecodeString(encoded)
	fmt.Println(string(decoded) == string(original)) // true
}

رمزگشایی Base64 در Go با encoding/base64

پکیج encoding/base64 همراه با Go ارائه می‌شود — هیچ وابستگی خارجی ندارد. این پکیج چهار نوع رمزگذاری از پیش تعریف‌شده را به عنوان متغیرهای سطح پکیج در اختیار می‌گذارد. پرکاربردترین تابع برای ورودی رشته‌ای DecodeString است که یک byte slice و یک خطا برمی‌گرداند.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	// Standard Base64 — the alphabet uses + and / with = padding
	encoded := "eyJob3N0IjoiZGItcHJvZCF1cy1lYXN0LTEiLCJwb3J0Ijo1NDMyfQ=="
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode error: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"db-prod.us-east-1","port":5432}
}

متد Decode روی byte sliceها به جای رشته‌ها کار می‌کند و نتیجه را در یک buffer از پیش تخصیص‌یافته می‌نویسد. باید اندازه buffer را به درستی تنظیم کنید — از base64.StdEncoding.DecodedLen(len(src)) برای دریافت حداکثر اندازه استفاده کنید (ممکن است به دلیل padding چند بایت بزرگ‌تر از طول واقعی رمزگشایی‌شده باشد).

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	src := []byte("eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9")
	dst := make([]byte, base64.RawStdEncoding.DecodedLen(len(src)))

	n, err := base64.RawStdEncoding.Decode(dst, src)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(dst[:n]))
	// {"host":"db-prod","port":5432}
}
توجه:DecodedLen یک کران بالا برمی‌گرداند، نه طول دقیق. همیشه از مقدار بازگشتی n از Decode برای برش صحیح نتیجه استفاده کنید: dst[:n].

StdEncoding در برابر URLEncoding — انتخاب نوع مناسب

بیشترین سردرگمی اینجاست. encoding/base64 در Go چهار شیء رمزگذاری ارائه می‌دهد، و انتخاب اشتباه تضمیناً به شما خطا می‌دهد. تفاوت به دو چیز برمی‌گردد: الفبا و padding.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// JWT header payload — URL-safe, no padding
	jwtHeader := "eyJhbGciOiJSUzI1NiIsImtpZCI6IjIwMjMtMDkifQ"

	// Wrong: StdEncoding fails on URL-safe input without padding
	_, err1 := base64.StdEncoding.DecodeString(jwtHeader)
	fmt.Println("StdEncoding error:", err1)
	// StdEncoding error: illegal base64 data at input byte 43

	// Correct: RawURLEncoding — no padding, URL-safe alphabet
	decoded, err2 := base64.RawURLEncoding.DecodeString(jwtHeader)
	fmt.Println("RawURLEncoding ok:", err2, "→", string(decoded))
	// RawURLEncoding ok: <nil> → {"alg":"RS256","kid":"2023-09"}
}

چهار نوع به زبان ساده:

تابع / متد
نوع رمزگذاری
نیاز به Padding
مقدار بازگشتی
base64.StdEncoding.DecodeString(s)
استاندارد (+, /)
بله (=)
([]byte, error)
base64.URLEncoding.DecodeString(s)
ایمن برای URL (-, _)
بله (=)
([]byte, error)
base64.RawStdEncoding.DecodeString(s)
استاندارد (+, /)
خیر
([]byte, error)
base64.RawURLEncoding.DecodeString(s)
ایمن برای URL (-, _)
خیر
([]byte, error)
base64.StdEncoding.Decode(dst, src)
استاندارد (+, /)
بله (=)
(n int, error)
base64.NewDecoder(enc, r)
هر نوع رمزگذاری
بله
io.Reader

قانون کلی من: اگر از JWT، OAuth flow، یا یک SDK ارائه‌دهنده ابری آمده، ابتدا RawURLEncoding را امتحان کنید. اگر از پیوست‌های ایمیل یا فرم‌های وب قدیمی آمده، StdEncoding را امتحان کنید. پیام خطا همیشه موقعیت دقیق بایتی که رمزگشایی در آن شکست خورده را به شما می‌گوید.

رمزگشایی Base64 از فایل و پاسخ API

خواندن یک فایل رمزگذاری‌شده با Base64

فایل‌های باینری (تصاویر، PDFها، گواهینامه‌ها) گاهی رمزگذاری‌شده با Base64 روی دیسک ذخیره می‌شوند. فایل را بخوانید، فاصله‌های انتهایی را حذف کنید، سپس رمزگشایی کنید:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"os"
	"strings"
)

func main() {
	raw, err := os.ReadFile("certificate.pem.b64")
	if err != nil {
		log.Fatalf("read file: %v", err)
	}

	// Strip newlines — Base64 files often have line breaks every 76 chars
	cleaned := strings.ReplaceAll(strings.TrimSpace(string(raw)), "\n", "")

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}

	if err := os.WriteFile("certificate.pem", decoded, 0600); err != nil {
		log.Fatalf("write: %v", err)
	}
	fmt.Printf("decoded %d bytes → certificate.pem\n", len(decoded))
}

رمزگشایی یک فیلد Base64 از پاسخ JSON یک API

APIهای ابری اغلب داده‌های باینری (کلیدهای رمزنگاری، blobهای امضاشده، تصاویر کوچک) را به صورت رشته‌های Base64 درون JSON برمی‌گردانند. ابتدا JSON را Unmarshal کنید، سپس فیلد هدف را رمزگشایی کنید:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type SecretResponse struct {
	Name    string `json:"name"`
	Payload string `json:"payload"` // Base64-encoded secret value
	Version int    `json:"version"`
}

func fetchAndDecodeSecret(secretURL string) ([]byte, error) {
	resp, err := http.Get(secretURL)
	if err != nil {
		return nil, fmt.Errorf("http get: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
	}

	var secret SecretResponse
	if err := json.NewDecoder(resp.Body).Decode(&secret); err != nil {
		return nil, fmt.Errorf("decode json: %w", err)
	}

	value, err := base64.StdEncoding.DecodeString(secret.Payload)
	if err != nil {
		return nil, fmt.Errorf("decode base64: %w", err)
	}
	return value, nil
}

func main() {
	value, err := fetchAndDecodeSecret("https://api.example.com/secrets/db-password")
	if err != nil {
		log.Fatalf("fetch secret: %v", err)
	}
	fmt.Printf("secret value: %s\n", value)
}
توجه:خطاها را با fmt.Errorf("decode base64: %w", err) بپوشانید تا context از دست نرود. پیام خطای اصلی از encoding/base64 شامل موقعیت بایتی خرابی است که در هنگام debugging مفید است.

رمزگشایی Streaming فایل‌های بزرگ رمزگذاری‌شده با Base64

بارگذاری یک فایل 500 مگابایتی رمزگذاری‌شده با Base64 در حافظه با os.ReadFile و سپس فراخوانی DecodeString تقریباً 750 مگابایت RAM مصرف می‌کند (رشته رمزگذاری‌شده به علاوه بایت‌های رمزگشایی‌شده). base64.NewDecoder هر io.Reader را می‌پوشاند و به صورت تکه‌تکه رمزگشایی می‌کند، و مصرف حافظه را تقریباً ثابت نگه می‌دارد. برای یک pipeline streaming تمیز آن را با io.Copy ترکیب کنید:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
)

func streamDecodeFile(srcPath, dstPath string) error {
	src, err := os.Open(srcPath)
	if err != nil {
		return fmt.Errorf("open source: %w", err)
	}
	defer src.Close()

	dst, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("create dest: %w", err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	written, err := io.Copy(dst, decoder)
	if err != nil {
		return fmt.Errorf("stream decode: %w", err)
	}
	fmt.Printf("written %d bytes to %s\n", written, dstPath)
	return nil
}

func main() {
	if err := streamDecodeFile("backup.tar.b64", "backup.tar"); err != nil {
		log.Fatal(err)
	}
}
هشدار:base64.NewDecoder انتظار داده‌های Base64 تمیز و بدون وقفه دارد. اگر فایل منبع دارای newline است (که در فایل‌های PEM و MIME رایج است)، reader ورودی را با یک wrapper که newlineها را حذف کند بپوشانید، یا فایل را قبل از streaming پاک‌سازی کنید.

رمزگشایی Base64 از خط فرمان

اکثر توسعه‌دهندگان Go در هنگام debugging ابتدا به خط فرمان روی می‌آورند. هر سیستم macOS و Linux با base64 ارائه می‌شود؛ در Windows، PowerShell معادل داخلی دارد. برای بازرسی سریع payloadهای API، این روش‌ها از نوشتن یک اسکریپت Go سریع‌تر هستند.

bash
# Decode a Base64 string (Linux / macOS)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode
# {"host":"db-prod","port":5432}

# Decode and pretty-print with jq (pipe the JSON output)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode | jq .
# {
#   "host": "db-prod",
#   "port": 5432
# }

# Decode a Base64-encoded file to binary
base64 --decode < encrypted_payload.b64 > encrypted_payload.bin

# macOS uses -D flag instead of --decode
echo "c2VjcmV0LXRva2Vu" | base64 -D

برای بازرسی توکن‌های JWT بدون نصب هیچ ابزاری، توکن را در رمزگشای Base64 ToolDeck جای‌گذاری کنید — روی نقطه‌ها تقسیم کرده و هر قسمت را رمزگشایی کنید.

جایگزین با کارایی بالا: encoding/base64 از پیش سریع است

برخلاف Python که بحث کارایی orjson در برابر json کاملاً جدی است، encoding/base64 در Go از پیش با assembly بهینه‌سازی شده و برای اکثر workloadها واقعاً سریع است. با این حال، اگر در یک حلقه تنگ میلیون‌ها رکورد پردازش می‌کنید، filippo.io/base64 رمزگشایی شتاب‌یافته با SIMD با یک API drop-in ارائه می‌دهد.

bash
go get filippo.io/base64
Go 1.21+
package main

import (
	"fmt"
	"log"

	"filippo.io/base64"
)

func main() {
	// Drop-in replacement — same API as encoding/base64
	encoded := "eyJob3N0IjoiY2FjaGUtcHJvZCIsInBvcnQiOjYzNzl9"
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"cache-prod","port":6379}
}

افزایش کارایی روی amd64 با پشتیبانی AVX2 بیشتر نمایان است — benchmark‌ها بهبود throughput 2 تا 4 برابری روی ورودی‌های بزرگ نشان می‌دهند. برای رمزگشایی روزمره پاسخ API (چند صد بایت در هر بار)، با کتابخانه استاندارد بمانید.

رمزگشایی payload JWT در Go

بازرسی JWT در تقریباً هر سرویس backend پیش می‌آید. به تجربه من، اکثر session‌های debugging به این خلاصه می‌شوند که «واقعاً چه چیزی در این توکن هست؟» — و می‌توانید بدون وارد کردن یک کتابخانه JWT کامل به این سوال پاسخ دهید. توکن سه بخش رمزگذاری‌شده با Base64url دارد که با نقطه جدا شده‌اند. بخش میانی payload است که واقعاً به آن نیاز دارید:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"strings"
)

type JWTPayload struct {
	Subject  string   `json:"sub"`
	Issuer   string   `json:"iss"`
	Expiry   int64    `json:"exp"`
	Roles    []string `json:"roles"`
}

func decodeJWTPayload(token string) (*JWTPayload, error) {
	parts := strings.Split(token, ".")
	if len(parts) != 3 {
		return nil, fmt.Errorf("invalid JWT: expected 3 segments, got %d", len(parts))
	}

	// JWT uses RawURLEncoding — URL-safe alphabet, no = padding
	raw, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		return nil, fmt.Errorf("decode payload: %w", err)
	}

	var payload JWTPayload
	if err := json.Unmarshal(raw, &payload); err != nil {
		return nil, fmt.Errorf("unmarshal payload: %w", err)
	}
	return &payload, nil
}

func main() {
	token := "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3ItNDQyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIsImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJhdWRpdG9yIl19.SIGNATURE"

	payload, err := decodeJWTPayload(token)
	if err != nil {
		log.Fatalf("jwt: %v", err)
	}
	fmt.Printf("Subject: %s\n", payload.Subject)
	fmt.Printf("Issuer:  %s\n", payload.Issuer)
	fmt.Printf("Roles:   %v\n", payload.Roles)
	// Subject: usr-442
	// Issuer:  auth.example.com
	// Roles:   [admin auditor]
}

اشتباهات رایج

همه چهار مورد را در بررسی‌های واقعی کد دیده‌ام — دو مورد اول به خصوص تقریباً هر بار که کسی یک ارائه‌دهنده auth جدید را یکپارچه می‌کند ظاهر می‌شوند.

استفاده از StdEncoding روی ورودی ایمن برای URL

مشکل: توکن‌های JWT و OAuth از الفبای Base64 ایمن برای URL استفاده می‌کنند (- و _). ارسال آنها به StdEncoding.DecodeString با خطای 'illegal base64 data' شکست می‌خورد.

راه‌حل: منبع ورودی را بررسی کنید: توکن‌های از سیستم‌های auth از RawURLEncoding استفاده می‌کنند؛ پیوست‌های باینری از StdEncoding.

After · Go
Before · Go
// JWT header — correct encoding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.RawURLEncoding.DecodeString(token)
// decoded: {"alg":"RS256"}
// err: nil
// JWT header — URL-safe, no padding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.StdEncoding.DecodeString(token)
// err: illegal base64 data at input byte 19
نادیده گرفتن مقدار بازگشتی n از Decode

مشکل: Decode داده را در یک buffer از پیش تخصیص‌یافته می‌نویسد و تعداد بایت‌های واقعاً نوشته‌شده را برمی‌گرداند. DecodedLen یک کران بالا برمی‌گرداند، بنابراین انتهای buffer ممکن است حاوی بایت‌های زباله باشد.

راه‌حل: همیشه نتیجه را با dst[:n] برش دهید — نه dst[:len(dst)].

After · Go
Before · Go
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
n, err := base64.StdEncoding.Decode(dst, src)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(dst[:n])) // correct — only the decoded bytes
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
base64.StdEncoding.Decode(dst, src)
fmt.Println(string(dst)) // may include trailing zero bytes
حذف نکردن فاصله‌های اضافی قبل از رمزگشایی

مشکل: رشته‌های Base64 کپی‌شده از ترمینال‌ها، ایمیل‌ها، یا فایل‌های پیکربندی اغلب دارای خطوط جدید یا فاصله در انتها هستند. ارسال مستقیم آنها به DecodeString در کاراکتر فاصله شکست می‌خورد.

راه‌حل: قبل از رمزگشایی strings.TrimSpace (و strings.ReplaceAll برای خطوط جدید تعبیه‌شده) را فراخوانی کنید.

After · Go
Before · Go
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
cleaned := strings.TrimSpace(encoded)
decoded, err := base64.StdEncoding.DecodeString(cleaned)
// decoded: "service_key:xKMp2"
// err: nil
// Value read from a config file with a trailing newline
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
decoded, err := base64.StdEncoding.DecodeString(encoded)
// err: illegal base64 data at input byte 24
ذخیره نادرست بایت‌های رمزگشایی‌شده به عنوان رشته

مشکل: فراخوانی string(decoded) روی داده‌های باینری (تصاویر، payloadهای فشرده) رشته‌های UTF-8 نامعتبر تولید می‌کند. رشته‌های Go می‌توانند بایت‌های دلخواه نگه دارند، اما برخی عملیات محتوا را خراب می‌کنند.

راه‌حل: داده‌های باینری را در تمام pipeline به صورت []byte نگه دارید. فقط زمانی string(decoded) را فراخوانی کنید که مطمئن هستید محتوای رمزگشایی‌شده متن است.

After · Go
Before · Go
decoded, err := base64.StdEncoding.DecodeString(pngBase64)
if err != nil {
    log.Fatal(err)
}
// Write bytes directly — no string conversion
os.WriteFile("image.png", decoded, 0644)
decoded, _ := base64.StdEncoding.DecodeString(pngBase64)
// Treating binary PNG as a string loses data
imageStr := string(decoded)
os.WriteFile("image.png", []byte(imageStr), 0644) // may corrupt

مقایسه متدها

تمام انواع در کتابخانه استاندارد ارائه می‌شوند — هیچ‌کدام نیاز به وابستگی خارجی ندارند.

متد
نوع ورودی
انواع رمزگذاری
پشتیبانی از Streaming
الفبای سفارشی
Padding سفارشی
نیاز به نصب
StdEncoding.DecodeString
string
استاندارد
خیر (stdlib)
URLEncoding.DecodeString
string
ایمن برای URL
خیر (stdlib)
RawStdEncoding.DecodeString
string
استاندارد (بدون padding)
خیر (stdlib)
RawURLEncoding.DecodeString
string
ایمن برای URL (بدون padding)
خیر (stdlib)
StdEncoding.Decode
[]byte
استاندارد
خیر (stdlib)
base64.NewDecoder
io.Reader
هر نوع
خیر (stdlib)
encoding/base64 + NewEncoding
string
الفبای سفارشی
خیر (stdlib)

برای توکن‌های JWT و OAuth: RawURLEncoding. برای پیوست‌های ایمیل و داده‌های MIME: StdEncoding. برای فایل‌های باینری بزرگ از دیسک یا شبکه: یک reader را در base64.NewDecoder بپوشانید — این روش مصرف حافظه را صرف نظر از اندازه فایل ثابت نگه می‌دارد. به الفبای سفارشی نیاز دارید؟ base64.NewEncoding(alphabet) یک شیء رمزگذاری جدید برای موارد استفاده خاص می‌سازد.

برای بررسی‌های سریع یک‌بار در طول توسعه، رمزگشای Base64 آنلاین سریع‌تر از راه‌اندازی یک برنامه Go است.

سوالات متداول

چطور یک رشته Base64 را در Go رمزگشایی کنم؟

پکیج encoding/base64 را ایمپورت کرده و base64.StdEncoding.DecodeString(s) را فراخوانی کنید. این تابع ([]byte, error) برمی‌گرداند — همیشه خطا را بررسی کنید. اگر رشته از کاراکترهای ایمن برای URL استفاده می‌کند (- و _ به جای + و /)، از base64.URLEncoding.DecodeString استفاده کنید. برای توکن‌های JWT و اکثر APIهای مدرن، RawURLEncoding (بدون padding) انتخاب درست است.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	encoded := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
	decoded, err := base64.RawURLEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"alg":"HS256","typ":"JWT"}
}

تفاوت بین StdEncoding و URLEncoding در Go چیست؟

StdEncoding از الفبای استاندارد Base64 با کاراکترهای + و / و padding برابر = استفاده می‌کند — که در RFC 4648 §4 تعریف شده است. URLEncoding علامت + را با - و / را با _ جایگزین می‌کند تا خروجی در URLها و هدرهای HTTP بدون percent-encoding ایمن باشد — که در RFC 4648 §5 تعریف شده است. از URLEncoding برای توکن‌های JWT، توکن‌های OAuth، و هر داده‌ای که در query string جاسازی می‌شود استفاده کنید.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Standard: may contain + / and = characters
	std := base64.StdEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(std) // "aGVsbG8vd29ybGQ="

	// URL-safe: replaces + with - and / with _
	url := base64.URLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(url) // "aGVsbG8vd29ybGQ=" (same — diff shows with different bytes)

	// JWT headers never have padding — use RawURLEncoding
	raw := base64.RawURLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(raw) // "aGVsbG8vd29ybGQ" (no trailing =)
}

چطور خطاهای "illegal base64 data" را در Go برطرف کنم؟

این خطا به این معناست که ورودی حاوی کاراکترهایی خارج از الفبای مورد انتظار است، یا padding اشتباه است. سه علت رایج: استفاده از StdEncoding روی ورودی ایمن برای URL (به URLEncoding تغییر دهید)، استفاده از encoder با padding روی ورودی بدون padding (به RawStdEncoding/RawURLEncoding تغییر دهید)، یا وجود فاصله/خط جدید در انتها. قبل از رمزگشایی با strings.TrimSpace فاصله‌ها را حذف کنید.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	// Input from a webhook payload — has newlines stripped from wire format
	raw := "  aGVsbG8gd29ybGQ=  \n"
	cleaned := strings.TrimSpace(raw)

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(decoded)) // hello world
}

چطور یک فایل بزرگ رمزگذاری‌شده با Base64 را به صورت streaming در Go رمزگشایی کنم؟

از base64.NewDecoder(base64.StdEncoding, reader) استفاده کنید که هر io.Reader را می‌پوشاند و به صورت آنی رمزگشایی می‌کند. آن را از طریق io.Copy به مقصد هدایت کنید تا بدون بافر کردن کل فایل در حافظه بنویسید. این الگوی استاندارد برای رمزگشایی پیوست‌های باینری رمزگذاری‌شده با Base64 یا بارهای داده بزرگ است.

Go 1.21+
package main

import (
	"encoding/base64"
	"io"
	"log"
	"os"
)

func main() {
	src, err := os.Open("attachment.b64")
	if err != nil {
		log.Fatal(err)
	}
	defer src.Close()

	dst, err := os.Create("attachment.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	io.Copy(dst, decoder)
}

آیا می‌توان payload یک JWT رمزگذاری‌شده با Base64 را در Go بدون کتابخانه JWT رمزگشایی کرد؟

بله. یک JWT سه بخش رمزگذاری‌شده با Base64url است که با نقطه جدا شده‌اند. رشته را روی "." تقسیم کرده و بخش دوم (ایندکس 1) را با base64.RawURLEncoding.DecodeString رمزگشایی کنید — هدرها و payloadهای JWT از الفبای ایمن برای URL و بدون padding استفاده می‌کنند. بخش signature (ایندکس 2) باینری است و معمولاً فقط برای تأیید اعتبار لازم است.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	token := "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3ItOTAxIiwicm9sZSI6ImFkbWluIn0.SIG"
	parts := strings.Split(token, ".")
	if len(parts) < 2 {
		log.Fatal("invalid JWT format")
	}

	payload, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		log.Fatalf("decode payload: %v", err)
	}
	fmt.Println(string(payload))
	// {"sub":"usr-901","role":"admin"}
}

برای رمزگشایی داده‌های Base64 از یک پاسخ HTTP API باید از چه نوع رمزگذاری استفاده کنم؟

مستندات API را بررسی کنید یا رشته رمزگذاری‌شده را بازرسی کنید. اگر حاوی کاراکترهای + یا / است و با = ختم می‌شود، از StdEncoding استفاده کنید. اگر از کاراکترهای - و _ بدون = استفاده می‌کند، از RawURLEncoding استفاده کنید. در صورت شک، ابتدا RawURLEncoding را امتحان کنید — اکثر APIهای مدرن (OAuth2، JWT، Google Cloud، AWS) از Base64 ایمن برای URL بدون padding استفاده می‌کنند.

Go 1.21+
package main

import (
	"encoding/base64"
	"strings"
)

// Detect encoding variant from the encoded string
func decodeAPIPayload(encoded string) ([]byte, error) {
	// URL-safe characters without padding — common in modern APIs
	if !strings.Contains(encoded, "+") && !strings.Contains(encoded, "/") {
		return base64.RawURLEncoding.DecodeString(encoded)
	}
	// Standard Base64 with padding
	return base64.StdEncoding.DecodeString(encoded)
}

ابزارهای مرتبط

  • رمزگذار Base64 — داده‌های باینری یا متن را در مرورگر به Base64 رمزگذاری کنید، برای تولید fixture‌های تستی که در unit test‌های Go خود جای‌گذاری می‌کنید مفید است.
  • رمزگشای JWT — هر سه بخش JWT را یک‌جا تقسیم و رمزگشایی کنید، با بازرسی payload فیلد به فیلد — وقتی فقط نیاز دارید در حین debugging یک توکن را بخوانید، نیازی به کد Go نیست.
  • رمزگشای URL — رشته‌های رمزگذاری‌شده با URL را percent-decode کنید، وقتی پاسخ‌های API داده‌های Base64url را با پارامترهای query رمزگذاری‌شده با percent ترکیب می‌کنند مفید است.
  • قالب‌بند JSON — پس از رمزگشایی payload JWT یا پاسخ API رمزگذاری‌شده با Base64، JSON را اینجا جای‌گذاری کنید تا فوری pretty-print شده و ساختار آن اعتبارسنجی شود.
همچنین موجود در:JavaC#
JO
James OkaforSystems Engineer

James is a systems engineer and Go enthusiast who focuses on high-performance microservices, command-line tooling, and infrastructure automation. He enjoys the simplicity and explicitness of Go and writes about building fast, reliable backend systems. When not coding he explores distributed systems concepts and contributes to open-source Go libraries.

HN
Hana Novákováبازبین فنی

Hana is a backend engineer who has built production gRPC and REST services in Go for cloud-native environments. She cares deeply about API correctness, protobuf schema design, and the operational side of running Go services in Kubernetes. She writes about the Go standard library, encoding and marshalling patterns, gRPC best practices, and the subtleties of writing idiomatic Go that is easy to test and maintain.