Декодування Base64 у Go трапляється постійно — перевірка JWT, двійкові вкладення файлів, корисні навантаження API від хмарних сервісів. Стандартний пакет Go encoding/base64 вирішує всі ці завдання, однак вибір неправильного варіанта кодування (стандартне або URL-безпечне, з відступом або без) — найпоширеніша причина помилок “illegal base64 data”. Цей посібник охоплює StdEncoding, URLEncoding, RawURLEncoding, потокове декодування за допомогою base64.NewDecoder, аналіз корисних навантажень JWT і чотири помилки, на які наштовхується майже кожен з першого разу. Для разового декодування в браузері Base64 Decoder від ToolDeck впорається миттєво без жодного рядка коду.
- ✓encoding/base64 входить до стандартної бібліотеки Go — go get не потрібен
- ✓Використовуйте RawURLEncoding для JWT-токенів і більшості сучасних API (без відступу, URL-безпечний алфавіт)
- ✓StdEncoding використовує + та / з відступом =; URLEncoding замінює їх на - та _, але зберігає відступ
- ✓base64.NewDecoder обгортає будь-який io.Reader для потокового декодування без завантаження в пам'ять
- ✓Завжди перевіряйте повернуту помилку — неправильний відступ і невірний алфавіт спричиняють illegal base64 data
Що таке декодування Base64?
Кодування Base64 представляє двійкові дані у вигляді ASCII-тексту, використовуючи 64 друковані символи (A–Z, a–z, 0–9 плюс ще два). Декодування — зворотна операція: воно перетворює це ASCII-представлення назад у вихідні байти. Кожні 4 символи Base64 декодуються рівно в 3 байти. Схема існує тому, що багато транспортних рівнів (електронна пошта, HTTP-заголовки, JSON-поля) розраховані на текст, а не на сирі двійкові дані. Важливо розуміти: Base64 — це кодування, а не шифрування. Будь-хто, хто бачить закодований рядок, може тривіально його декодувати без жодного ключа. Саме тому JWT підписуються і, у разі потреби, шифруються окремо. Ось як виглядає повний цикл:
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, яка повертає зріз байтів і помилку. На відміну від деяких інших мов, де функція декодування повертає nil або порожній рядок при некоректному введенні, Go явно сигналізує про помилку разом із точною позицією байта, де стався збій — це суттєво спрощує налагодження.
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 працює зі зрізами байтів, а не з рядками, і записує результат у наперед виділений буфер призначення. Необхідно правильно розрахувати розмір буфера — використовуйте base64.StdEncoding.DecodedLen(len(src)), щоб отримати максимальний розмір (він може бути на кілька байтів більший за фактичну довжину декодованих даних через відступ).
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 надає чотири об'єкти кодування, і вибір неправильного гарантовано призведе до помилки. Різниця зводиться до двох речей: алфавіту і відступу.
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-потоку або SDK хмарного провайдера, спочатку спробуйте RawURLEncoding. Якщо вони надійшли з вкладень електронної пошти або старомодних веб-форм, спробуйте StdEncoding. Якщо джерело невідоме, ставте RawURLEncoding першим — більшість сучасних сервісів (OAuth 2.0, OIDC, AWS, Google) дотримуються URL-безпечного Base64 без відступу як стандарту. Повідомлення про помилку завжди вказує точну позицію байта, де декодування завершилось невдачею.
Декодування 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 часто повертають двійкові дані (ключі шифрування, підписані блоки, мініатюри) як рядки Base64 всередині JSON. Спочатку розберіть JSON, а потім декодуйте потрібне поле. Зверніть увагу на правильне загортання помилок — вихідне повідомлення від encoding/base64 містить позицію байта збою, що дуже корисно при налагодженні:
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) замість того, щоб втрачати контекст. Оригінальне повідомлення про помилку від encoding/base64 містить позицію байта, де сталась невдача, що корисно під час налагодження.Потокове декодування великих файлів Base64
Завантаження файлу Base64 розміром 500 МБ у пам'ять за допомогою os.ReadFile і подальший виклик DecodeString використовують приблизно 750 МБ RAM (закодований рядок плюс декодовані байти). base64.NewDecoder обгортає будь-який io.Reader і виконує декодування по шматках, підтримуючи майже постійне використання пам'яті. Це особливо важливо в контейнерних середовищах із жорсткими лімітами оперативної пам'яті: потокова обробка дозволяє декодувати файли будь-якого розміру у межах фіксованого бюджету ресурсів. Ще одна перевага — base64.NewDecoder повертає стандартний io.Reader, тому він сумісний з будь-яким кодом, який очікує ридер: io.Copy, json.NewDecoder, архіватори та ін. Поєднайте його з 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. Якщо вихідний файл містить переноси рядків (що характерно для файлів PEM і MIME), оберніть читач джерела фільтрувальним reader-ом або попередньо обробіть файл для видалення переносів рядків перед потоковою обробкою.Декодування Base64 з командного рядка
Більшість Go-розробників першочергово звертаються до командного рядка при налагодженні. На кожній системі macOS і Linux є утиліта base64; у Windows PowerShell є вбудований еквівалент. Для швидкого огляду корисних навантажень API вони швидші за написання Go-скрипту. Зверніть увагу: у macOS потрібно використовувати прапорець -D замість --decode через відмінності у версії утиліти, встановленої за замовчуванням. На Linux обидва варіанти працюють.
# 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 Decoder від ToolDeck — розділіть за крапками і декодуйте кожну частину.
Висока продуктивність: encoding/base64 вже достатньо швидкий
На відміну від Python, де порівняння orjson і json має реальний сенс, encoding/base64 у Go вже оптимізований на рівні асемблера і справді швидкий для більшості навантажень. Перш ніж додавати зовнішню залежність заради продуктивності, перевірте за допомогою pprof, що Base64 дійсно є вузьким місцем — на практиці причиною затримки частіше є мережевий ввід-вивід або серіалізація JSON. Проте якщо ви обробляєте мільйони записів у щільному циклі, filippo.io/base64 забезпечує декодування з прискоренням SIMD і сумісним 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 — бенчмарки демонструють поліпшення пропускної здатності в 2–4 рази на великих вхідних даних. Для повсякденного декодування відповідей API (кілька сотень байтів за раз) використовуйте стандартну бібліотеку. Типовий мікросервіс, який декодує JWT-заголовок і навантаження на кожен запит, витрачає незначну частку загального часу обробки на операцію Base64 — профілювання реальних Go-сервісів підтверджує це навіть при десятках тисяч запитів на секунду.
Декодування корисного навантаження JWT Base64 у Go
Аналіз JWT трапляється майже в кожному бекенд-сервісі. За моїм досвідом, більшість сесій налагодження зводиться до питання “що насправді в цьому токені?” — і відповісти на нього можна без підключення повноцінної бібліотеки JWT. Важливо пам'ятати: наведений нижче код лише декодує вміст без верифікації підпису. Для production-сервісів верифікацію підпису потрібно виконувати окремо за допомогою відповідної бібліотеки. Токен має три сегменти в кодуванні Base64url, розділені крапками. Середній сегмент — це корисне навантаження, яке вас цікавить:
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 — перші дві з'являються майже щоразу, коли хтось інтегрує нового провайдера аутентифікації. Третя і четверта помилки частіше трапляються у розробників, що переходять з Python або JavaScript: вони звикають до неявного trim і безпечного перетворення рядків та забувають, що в Go ці операції потрібно виконувати явно.
Проблема: JWT-токени та OAuth-токени використовують URL-безпечний алфавіт Base64 (- та _). Передача їх до StdEncoding.DecodeString завершується помилкою 'illegal base64 data'.
Рішення: Перевірте джерело вхідних даних: токени від систем аутентифікації потребують RawURLEncoding; двійкові вкладення потребують 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 записує у наперед виділений буфер і повертає кількість фактично записаних байтів. DecodedLen повертає верхню межу, тому хвіст буфера може містити сміттєві байти.
Рішення: Завжди зрізайте результат через 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Проблема: Рядки Base64, скопійовані з терміналів, електронних листів або конфігураційних файлів, часто мають кінцеві переноси рядків або пробіли. Передача їх безпосередньо до DecodeString завершується невдачею на пробільному символі.
Рішення: Викличте strings.TrimSpace (і strings.ReplaceAll для вбудованих переносів рядків) перед декодуванням.
// 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) на двійкових даних (зображення, стиснуті корисні навантаження) створює некоректні рядки UTF-8. Рядки Go можуть зберігати довільні байти, але деякі операції спотворять вміст.
Рішення: Зберігайте двійкові дані як []byte протягом усього конвеєра. Викликайте 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)Порівняння методів
Усі варіанти входять до стандартної бібліотеки — жодних зовнішніх залежностей не потрібно. Вибір між ними зводиться до двох питань: звідки надходять дані і чи містять вони відступ. Якщо джерело — JWT або OAuth-токен, це майже завжди RawURLEncoding. Якщо джерело — вкладення електронної пошти або стара веб-форма, це StdEncoding. Якщо джерело невідоме — спробуйте RawURLEncoding першим, адже переважна більшість сучасних API дотримується цього стандарту. Таблиця нижче допомагає порівняти всі варіанти за одним поглядом. Для нестандартних алфавітів base64.NewEncoding(alphabet) створює об'єкт кодування з довільними символами — рідкісний, але реальний сценарій при інтеграції зі застарілими системами, що визначають власні відображення для 62-го і 63-го знаків алфавіту Base64. Виклик .WithPadding(base64.NoPadding) на будь-якому об'єкті кодування дає його Raw-варіант програмно.
Для JWT-токенів і OAuth-потоків: RawURLEncoding. Для вкладень електронної пошти та MIME-даних: StdEncoding. Для великих двійкових файлів із диска або мережі: оберніть reader у base64.NewDecoder — він підтримує постійне використання пам'яті незалежно від розміру файлу. Потрібен власний алфавіт? base64.NewEncoding(alphabet) створює новий об'єкт кодування для нестандартних випадків.
Для швидких разових перевірок під час розробки онлайн Base64 Decoder швидший за запуск Go-програми.
Часті запитання
Як декодувати рядок Base64 у Go?
Імпортуйте encoding/base64 і викличте base64.StdEncoding.DecodeString(s). Функція повертає ([]byte, error) — завжди перевіряйте помилку. Якщо рядок містить URL-безпечні символи (- та _ замість + та /), використовуйте base64.URLEncoding.DecodeString. Для JWT-токенів і більшості сучасних API правильним вибором є RawURLEncoding (без відступу).
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 із символами + та / і відступом = — визначено в RFC 4648 §4. URLEncoding замінює + на - та / на _, що робить вивід безпечним у URL та HTTP-заголовках без percent-encoding — визначено в RFC 4648 §5. Використовуйте URLEncoding для JWT-токенів, OAuth-токенів і будь-яких даних, вбудованих у рядки запитів.
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?
Ця помилка означає, що вхідні дані містять символи поза очікуваним алфавітом або неправильний відступ. Три поширені причини: використання StdEncoding для URL-безпечних вхідних даних (замініть на URLEncoding), використання кодувальника з відступом для даних без відступу (замініть на 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 у 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)
}Чи можна декодувати корисне навантаження JWT Base64 у Go без бібліотеки JWT?
Так. JWT — це три сегменти в кодуванні Base64url, розділені крапками. Розділіть рядок за символом "." і декодуйте другий сегмент (індекс 1) за допомогою base64.RawURLEncoding.DecodeString — заголовки та корисні навантаження JWT використовують URL-безпечний алфавіт без відступу. Сегмент підпису (індекс 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) використовують URL-безпечний Base64 без відступу.
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 Encoder — кодуйте двійкові дані або текст у Base64 в браузері; зручно для генерації тестових фікстур, які потім вставляють у юніт-тести Go.
- JWT Decoder — розбиває і декодує всі три сегменти JWT одразу з поперечною перевіркою полів корисного навантаження — Go-код не потрібен, якщо вам просто треба прочитати токен під час налагодження.
- URL Decoder — декодує рядки у percent-encoding; зручний, коли відповіді API поєднують дані Base64url з percent-закодованими параметрами запиту.
- JSON Formatter — після декодування корисного навантаження JWT Base64 або відповіді API вставте JSON сюди для миттєвого форматування та перевірки структури.