رمزگشایی 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) برای متن طراحی شدهاند، نه داده باینری خام. مثال زیر این چرخه رفت و برگشت را نشان میدهد:
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 و یک خطا برمیگرداند.
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 چند بایت بزرگتر از طول واقعی رمزگشاییشده باشد).
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.
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"}
}چهار نوع به زبان ساده:
قانون کلی من: اگر از JWT، OAuth flow، یا یک SDK ارائهدهنده ابری آمده، ابتدا RawURLEncoding را امتحان کنید. اگر از پیوستهای ایمیل یا فرمهای وب قدیمی آمده، StdEncoding را امتحان کنید. پیام خطا همیشه موقعیت دقیق بایتی که رمزگشایی در آن شکست خورده را به شما میگوید.
رمزگشایی Base64 از فایل و پاسخ API
خواندن یک فایل رمزگذاریشده با Base64
فایلهای باینری (تصاویر، PDFها، گواهینامهها) گاهی رمزگذاریشده با Base64 روی دیسک ذخیره میشوند. فایل را بخوانید، فاصلههای انتهایی را حذف کنید، سپس رمزگشایی کنید:
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 کنید، سپس فیلد هدف را رمزگشایی کنید:
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 ترکیب کنید:
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 سریعتر هستند.
# 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 ارائه میدهد.
go get filippo.io/base64
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 است که واقعاً به آن نیاز دارید:
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 جدید را یکپارچه میکند ظاهر میشوند.
مشکل: توکنهای JWT و OAuth از الفبای Base64 ایمن برای URL استفاده میکنند (- و _). ارسال آنها به StdEncoding.DecodeString با خطای 'illegal base64 data' شکست میخورد.
راهحل: منبع ورودی را بررسی کنید: توکنهای از سیستمهای auth از RawURLEncoding استفاده میکنند؛ پیوستهای باینری از StdEncoding.
// 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
مشکل: Decode داده را در یک buffer از پیش تخصیصیافته مینویسد و تعداد بایتهای واقعاً نوشتهشده را برمیگرداند. DecodedLen یک کران بالا برمیگرداند، بنابراین انتهای buffer ممکن است حاوی بایتهای زباله باشد.
راهحل: همیشه نتیجه را با dst[:n] برش دهید — نه dst[:len(dst)].
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 bytesdst := 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 برای خطوط جدید تعبیهشده) را فراخوانی کنید.
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) را فراخوانی کنید که مطمئن هستید محتوای رمزگشاییشده متن است.
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مقایسه متدها
تمام انواع در کتابخانه استاندارد ارائه میشوند — هیچکدام نیاز به وابستگی خارجی ندارند.
برای توکنهای 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) انتخاب درست است.
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 جاسازی میشود استفاده کنید.
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 فاصلهها را حذف کنید.
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 یا بارهای داده بزرگ است.
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) باینری است و معمولاً فقط برای تأیید اعتبار لازم است.
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 استفاده میکنند.
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 شده و ساختار آن اعتبارسنجی شود.