การถอดรหัส Base64 ใน Go พบได้บ่อยมาก — ไม่ว่าจะเป็นการตรวจสอบ JWT, ไฟล์แนบแบบ binary หรือ API payload จากบริการ cloud แพ็กเกจ encoding/base64มาตรฐานของ Go รองรับทั้งหมดนี้ แต่การเลือกรูปแบบการเข้ารหัสผิด (มาตรฐาน vs URL-safe, มี padding vs ไม่มี padding) คือสาเหตุหลักที่ทำให้เกิดข้อผิดพลาด “illegal base64 data” คู่มือนี้ครอบคลุม StdEncoding, URLEncoding, RawURLEncoding, การถอดรหัสแบบ streaming ด้วย base64.NewDecoder, การตรวจสอบ JWT payload และข้อผิดพลาด 4 ประการที่มักพบ สำหรับการถอดรหัสแบบรวดเร็วในเบราว์เซอร์ ตัวถอดรหัส Base64 ของ ToolDeck ช่วยได้ทันทีโดยไม่ต้องเขียนโค้ดแม้แต่บรรทัดเดียว
- ✓encoding/base64 เป็นส่วนหนึ่งของ Go standard library — ไม่ต้องใช้ go get
- ✓ใช้ RawURLEncoding สำหรับ JWT token และ API สมัยใหม่ส่วนใหญ่ (ไม่มี padding, alphabet แบบ URL-safe)
- ✓StdEncoding ใช้ + และ / พร้อม padding =; URLEncoding เปลี่ยนเป็น - และ _ แต่ยังคง padding ไว้
- ✓base64.NewDecoder ครอบ io.Reader ใด ๆ สำหรับการถอดรหัสแบบ streaming โดยไม่โหลดข้อมูลเข้าหน่วยความจำ
- ✓ตรวจสอบ error ที่คืนกลับมาเสมอ — padding ไม่ถูกต้องและ alphabet ผิดจะทำให้เกิด illegal base64 data
การถอดรหัส Base64 คืออะไร?
การเข้ารหัส Base64 แสดงข้อมูล binary เป็นข้อความ ASCII โดยใช้อักขระที่พิมพ์ได้ 64 ตัว (A–Z, a–z, 0–9, บวกอีกสองตัว) การถอดรหัสเป็นการย้อนกลับ — แปลงการแสดง ASCII กลับเป็น byte ต้นฉบับ อักขระ Base64 ทุก 4 ตัวถอดรหัสได้ 3 byte พอดี รูปแบบนี้มีอยู่เพราะ transport layer หลายชั้น (อีเมล, HTTP header, JSON field) ออกแบบมาสำหรับข้อความ ไม่ใช่ binary ดิบ ด้านล่างคือตัวอย่างการทำงานแบบ round-trip:
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 — ไม่มี dependency ภายนอก แพ็กเกจนี้เปิดเผยรูปแบบการเข้ารหัสที่กำหนดไว้ล่วงหน้า 4 แบบเป็น package-level variable ฟังก์ชันที่ใช้บ่อยที่สุดสำหรับ string input คือ DecodeStringซึ่งคืนค่าเป็น byte slice และ error
package main
import (
"encoding/base64"
"fmt"
"log"
)
func main() {
// Standard Base64 — the alphabet uses + and / with = padding
encoded := "eyJob3N0IjoiZGItcHJvZC51cy1lYXN0LTEiLCJwb3J0Ijo1NDMyfQ=="
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 แทน string และเขียนผลลัพธ์ลงใน destination 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 เพื่อตัด slice ให้ถูกต้อง: dst[:n]StdEncoding vs URLEncoding — เลือกรูปแบบที่ถูกต้อง
นี่คือจุดที่สร้างความสับสนมากที่สุด encoding/base64 ของ Go มี encoding object 4 แบบ และการเลือกผิดแบบรับประกันว่าจะได้รับ error ความแตกต่างขึ้นอยู่กับสองสิ่ง: alphabet และ 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"}
}4 รูปแบบในภาษาง่าย ๆ:
หลักการง่าย ๆ ของผม: ถ้ามาจาก JWT, OAuth flow หรือ cloud provider SDK ให้ลอง RawURLEncoding ก่อน ถ้ามาจากไฟล์แนบอีเมลหรือเว็บฟอร์มแบบเก่าให้ลอง StdEncoding ข้อความ error จะบอกตำแหน่ง byte ที่แน่นอนที่การถอดรหัสล้มเหลวเสมอ
ถอดรหัส Base64 จากไฟล์และ API Response
อ่านไฟล์ที่เข้ารหัส Base64
ไฟล์ binary (รูปภาพ, PDF, certificate) บางครั้งถูกเก็บในรูปแบบ Base64 บนดิสก์ อ่านไฟล์, ลบ whitespace ที่ท้าย แล้วถอดรหัส:
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))
}ถอดรหัส field Base64 จาก API JSON response
Cloud API มักคืนข้อมูล binary (encryption key, signed blob, thumbnail) เป็น string Base64 ภายใน JSON Unmarshal JSON ก่อน จากนั้นถอดรหัส field ที่ต้องการ:
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 ข้อความ error ต้นฉบับจาก encoding/base64 รวมตำแหน่ง byte ที่เกิดความล้มเหลว ซึ่งมีประโยชน์มากระหว่างการ debugStreaming ไฟล์ขนาดใหญ่ที่เข้ารหัส Base64
การโหลดไฟล์ที่เข้ารหัส Base64 ขนาด 500 MB เข้าหน่วยความจำด้วย os.ReadFile แล้วเรียก DecodeString ใช้ RAM ประมาณ 750 MB (encoded string บวก decoded bytes) base64.NewDecoder ครอบ io.Reader ใด ๆ และถอดรหัสเป็น chunk ทำให้การใช้ หน่วยความจำเกือบคงที่ ใช้ร่วมกับ io.Copy เพื่อ pipeline streaming ที่สะอาด:
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 ที่สะอาดและต่อเนื่อง ถ้าไฟล์ต้นทาง มี line break (พบบ่อยในไฟล์ PEM และ MIME-encoded) ให้ครอบ source reader ด้วย line-stripping reader หรือประมวลผลไฟล์ล่วงหน้าเพื่อลบ newline ก่อน streamingถอดรหัส Base64 จาก Command Line
นักพัฒนา Go ส่วนใหญ่ใช้ command line ก่อนเมื่อต้อง debug ทุกระบบ macOS และ Linux มาพร้อมกับคำสั่ง base64; บน Windows PowerShell มีฟีเจอร์ที่เทียบเท่ากัน สำหรับการตรวจสอบ API payload อย่างรวดเร็ว วิธีเหล่านี้เร็วกว่าการเขียน Go script
# 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 token โดยไม่ต้องติดตั้งเครื่องมือใด ๆ วาง token ลงใน ตัวถอดรหัส Base64 ของ ToolDeck — แยกด้วยจุดและถอดรหัสแต่ละส่วน
ทางเลือกประสิทธิภาพสูง: encoding/base64 เร็วอยู่แล้ว
ต่างจาก Python ที่ orjson vs json เป็นการสนทนาเรื่องประสิทธิภาพที่มีนัยสำคัญencoding/base64 ของ Go ถูก optimize ด้วย assembly และเร็วพอสำหรับ workload ส่วนใหญ่ อย่างไรก็ตาม หากคุณกำลังประมวลผล record หลายล้านรายการใน tight loop filippo.io/base64 ให้การถอดรหัสแบบ SIMD-accelerated พร้อม API ที่ใช้แทนกันได้
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 เท่าสำหรับ input ขนาดใหญ่ สำหรับการถอดรหัส API response ในชีวิตประจำวัน (ข้อมูลไม่กี่ร้อย byte ต่อครั้ง) ให้ใช้ standard library ก็เพียงพอแล้ว
ถอดรหัส JWT Payload แบบ Base64 ใน Go
การตรวจสอบ JWT พบได้ในแทบทุก backend service จากประสบการณ์ของผม session การ debug ส่วนใหญ่สรุปได้ว่า “จริง ๆ แล้วมีอะไรอยู่ใน token นี้?” — และคุณสามารถตอบได้ โดยไม่ต้องดึง JWT library เต็มรูปแบบมา Token มีสามส่วนที่เข้ารหัส 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]
}ข้อผิดพลาดที่พบบ่อย
ผมพบข้อผิดพลาดทั้งสี่นี้ในการ code review จริง — โดยเฉพาะสองข้อแรกที่ปรากฏขึ้นเกือบทุกครั้ง ที่ใครบางคน integrate auth provider ใหม่
ปัญหา: JWT token และ OAuth token ใช้ Base64 alphabet แบบ URL-safe (- และ _) การส่งให้ StdEncoding.DecodeString จะล้มเหลวด้วย 'illegal base64 data'
วิธีแก้ไข: ตรวจสอบแหล่งที่มาของ input: token จากระบบ auth ใช้ RawURLEncoding; ไฟล์แนบ binary ใช้ StdEncoding
// JWT header — URL-safe, no padding token := "eyJhbGciOiJSUzI1NiJ9" decoded, err := base64.StdEncoding.DecodeString(token) // err: illegal base64 data at input byte 19
// JWT header — correct encoding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.RawURLEncoding.DecodeString(token)
// decoded: {"alg":"RS256"}
// err: nilปัญหา: Decode เขียนลง buffer ที่จัดสรรไว้ล่วงหน้าและคืนจำนวน byte ที่เขียนจริง DecodedLen คืนค่าขอบเขตบน ดังนั้น tail ของ buffer อาจมี garbage byte
วิธีแก้ไข: ตัด slice ผลลัพธ์ด้วย dst[:n] เสมอ — ไม่ใช่ dst[:len(dst)]
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src))) base64.StdEncoding.Decode(dst, src) fmt.Println(string(dst)) // may include trailing zero bytes
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ปัญหา: String Base64 ที่คัดลอกมาจาก terminal, อีเมล หรือ config file มักมี newline หรือ space ที่ท้าย การส่งตรงไปยัง DecodeString จะล้มเหลวที่อักขระ whitespace
วิธีแก้ไข: เรียก strings.TrimSpace (และ strings.ReplaceAll สำหรับ newline ที่ฝังอยู่) ก่อน decode
// 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
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n" cleaned := strings.TrimSpace(encoded) decoded, err := base64.StdEncoding.DecodeString(cleaned) // decoded: "service_key:xKMp2" // err: nil
ปัญหา: การเรียก string(decoded) กับข้อมูล binary (รูปภาพ, compressed payload) ทำให้ได้ UTF-8 string ที่ไม่ถูกต้อง Go string สามารถเก็บ byte ใด ๆ ได้ แต่บางการดำเนินการจะทำให้เนื้อหาเสียหาย
วิธีแก้ไข: เก็บข้อมูล binary เป็น []byte ตลอด pipeline เรียก string(decoded) เฉพาะเมื่อมั่นใจว่าเนื้อหาที่ถอดรหัสเป็นข้อความเท่านั้น
decoded, _ := base64.StdEncoding.DecodeString(pngBase64)
// Treating binary PNG as a string loses data
imageStr := string(decoded)
os.WriteFile("image.png", []byte(imageStr), 0644) // may corruptdecoded, err := base64.StdEncoding.DecodeString(pngBase64)
if err != nil {
log.Fatal(err)
}
// Write bytes directly — no string conversion
os.WriteFile("image.png", decoded, 0644)การเปรียบเทียบเมธอด
ทุกรูปแบบมาพร้อมกับ standard library — ไม่มี dependency ภายนอกสำหรับสิ่งเหล่านี้
สำหรับ JWT token และ OAuth flow: RawURLEncoding สำหรับไฟล์แนบอีเมลและ MIME data: StdEncoding สำหรับไฟล์ binary ขนาดใหญ่จากดิสก์หรือเครือข่าย: ครอบ reader ด้วย base64.NewDecoder — ทำให้การใช้หน่วยความจำคงที่ไม่ว่าไฟล์จะมีขนาดเท่าใด ต้องการ alphabet กำหนดเอง? base64.NewEncoding(alphabet) สร้าง encoding object ใหม่สำหรับกรณีใช้งานพิเศษ
สำหรับการตรวจสอบแบบรวดเร็วระหว่างการพัฒนา ตัวถอดรหัส Base64 ออนไลน์ เร็วกว่าการเปิด Go program
คำถามที่พบบ่อย
จะถอดรหัส Base64 ใน Go ได้อย่างไร?
import encoding/base64 แล้วเรียก base64.StdEncoding.DecodeString(s) ฟังก์ชันนี้คืนค่า ([]byte, error) — ต้องตรวจสอบ error เสมอ หากข้อความใช้อักขระ URL-safe (- และ _ แทน + และ /) ให้ใช้ base64.URLEncoding.DecodeString แทน สำหรับ JWT token และ 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 header โดยไม่ต้อง percent-encoding ตามที่กำหนดใน RFC 4648 §5 ใช้ URLEncoding สำหรับ JWT token, OAuth token และข้อมูลที่ฝังใน 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 ได้อย่างไร?
ข้อผิดพลาดนี้หมายความว่า input มีอักขระที่อยู่นอก alphabet ที่คาดหวัง หรือ padding ไม่ถูกต้อง สาเหตุที่พบบ่อย 3 ประการ: ใช้ StdEncoding กับ input แบบ URL-safe (เปลี่ยนไปใช้ URLEncoding), ใช้ encoder แบบมี padding กับ input ที่ไม่มี padding (เปลี่ยนไปใช้ RawStdEncoding/RawURLEncoding) หรือมี whitespace/newline ที่ท้าย แก้ด้วยการใช้ strings.TrimSpace ก่อน decode
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 ใด ๆ และถอดรหัสแบบ on-the-fly จากนั้นส่งผ่าน io.Copy เพื่อเขียนไปยังปลายทางโดยไม่ต้องบัฟเฟอร์ไฟล์ทั้งหมดในหน่วยความจำ นี่คือรูปแบบมาตรฐานสำหรับการถอดรหัสไฟล์แนบแบบ binary ที่เข้ารหัส Base64 หรือ payload ข้อมูลขนาดใหญ่
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)
}ถอดรหัส JWT payload แบบ Base64 ใน Go โดยไม่ใช้ library JWT ได้หรือไม่?
ได้ JWT คือสามส่วนที่เข้ารหัส Base64url คั่นด้วยจุด แยกด้วย "." แล้วถอดรหัสส่วนที่สอง (index 1) ด้วย base64.RawURLEncoding.DecodeString — header และ payload ของ JWT ใช้ alphabet แบบ URL-safe และไม่มี padding ส่วน signature (index 2) เป็นข้อมูล binary และมักต้องการเฉพาะเพื่อการตรวจสอบความถูกต้องเท่านั้น
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 response?
ตรวจสอบเอกสาร API หรือดูที่ encoded string หากมีอักขระ + หรือ / และลงท้ายด้วย = ให้ใช้ StdEncoding หากใช้อักขระ - และ _ โดยไม่มี = ให้ใช้ RawURLEncoding เมื่อไม่แน่ใจ ลอง RawURLEncoding ก่อน — API สมัยใหม่ส่วนใหญ่ (OAuth2, JWT, Google Cloud, AWS) ใช้ Base64 แบบ URL-safe โดยไม่มี 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 — เข้ารหัสข้อมูล binary หรือข้อความเป็น Base64 ในเบราว์เซอร์ มีประโยชน์สำหรับสร้าง test fixture เพื่อวางใน Go unit test
- ตัวถอดรหัส JWT — แยกและถอดรหัสทั้งสาม JWT segment พร้อมกัน พร้อมการตรวจสอบ payload ทีละ field — ไม่ต้องใช้โค้ด Go เมื่อต้องการอ่าน token ระหว่างการ debug
- ตัวถอดรหัส URL — ถอดรหัส URL-encoded string แบบ percent-decode มีประโยชน์เมื่อ API response ผสม Base64url data กับ query parameter แบบ percent-encoded
- ตัวจัดรูปแบบ JSON — หลังจากถอดรหัส JWT payload หรือ API response แบบ Base64 วาง JSON ที่นี่เพื่อ pretty-print และตรวจสอบโครงสร้างทันที