Skip to content

How to Base64 encode/decode (without breaking Unicode)

Practical Base64 snippets for UTF-8 text. Includes notes to avoid common bytes vs strings mistakes.

← Developer Zone
Updated: 2026-03-22

Use this article when...

This section is built for speed: one concrete task, multiple stacks, and the minimum context needed not to copy the wrong thing.

Use this after capturing the real payload

Work from the request or response body that actually failed instead of rebuilding JSON from memory.

Pick the language that matches the incident

The useful path here is fast adaptation: choose your stack, then copy only after reading the notes around parsing and formatting.

Validate the result with the tool

Once the snippet runs, inspect the live payload with JSON Formatter or the related tool to confirm the structure is really fixed.

What this article gives you

A short path from incident to implementation: context, language-specific snippets, and the warning signs that usually get skipped.

Languages

13

Related tools

3

Topics

base64, encoding, debugging, web

Base64 is not “encryption”: it is a representation to transport bytes as text. It is used in headers, tokens, payloads, and to debug binary data.

The common mistake: treating Base64 as “plain text” without defining UTF-8. Practical rule: string → UTF-8 bytes → Base64, and back.

Dependency snapshot by language

Check this first to see which snippets use built-in/runtime APIs and which ones need external packages before you start copying code.

Bash
Check notes

Review the notes for setup details.

C#
Built-in

Built-in or runtime API

Delphi
Check notes

Review the notes for setup details.

Go
Check notes

Review the notes for setup details.

Java
Built-in

Built-in or runtime API

JavaScript
Built-in

Built-in or runtime API

Kotlin
Check notes

Review the notes for setup details.

PHP
Built-in

Built-in or runtime API

Python
Built-in

Built-in or runtime API

Ruby
Built-in

Built-in or runtime API

Rust
External

base64 = "0.22".

TypeScript
Built-in

Built-in or runtime API

VB.NET
Built-in

Built-in or runtime API

How to use these code examples well

The snippet is only the fast path. The explanation and notes are what keep you from copying the wrong assumption into production.

1. Start with the problem

Make sure the article really matches the issue you are debugging before copying code just because the title looks close.

2. Read the notes

That is where portability limits, dependency requirements, and runtime assumptions usually appear.

3. Validate the output

If the code runs but the bug remains, jump to the related tool and inspect the real payload, token, timestamp, or config.

Code examples by language

Snippets that compile/run, plus short explanations and real-world notes.

Bash

bash
Bash
echo -n 'Hello world' | base64
echo 'SGVsbG8gd29ybGQ=' | base64 -d
Explanation

The base64 CLI encodes stdin to Base64 and can decode it back. Useful for quick debugging of small payloads.

Notes
  • On macOS, decode flag is often -D instead of -d.
  • For binary data, redirect to a file (do not print in terminal).

C#

csharp
C#
using System;
using System.Text;

var text = "Hola mundo";
var b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(text));
var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(b64));
Console.WriteLine(b64);
Console.WriteLine(decoded);
Explanation

Converts string → UTF-8 bytes → Base64. To decode, reverse: Base64 → bytes → UTF-8.

Notes
  • Std.
  • If input may be invalid, catch FormatException from FromBase64String.

Delphi

delphi
Delphi
program Base64Utf8;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.NetEncoding;

var
  Text: string;
  B64: string;
  Decoded: string;

begin
  Text := "Hola mundo";
  B64 := TNetEncoding.Base64.Encode(Text);
  Decoded := TNetEncoding.Base64.Decode(B64);
  Writeln(B64);
  Writeln(Decoded);
end.
Explanation

TNetEncoding.Base64 can encode/decode strings directly. For binary flows, work with bytes/streams.

Notes
  • Std: System.NetEncoding.
  • For binary data, use overloads that work with bytes/streams.

Go

go
Go
package main

import (
  "encoding/base64"
  "fmt"
)

func main() {
  text := "Hola mundo"
  b64 := base64.StdEncoding.EncodeToString([]byte(text))
  raw, err := base64.StdEncoding.DecodeString(b64)
  if err != nil {
    panic(err)
  }
  fmt.Println(b64)
  fmt.Println(string(raw))
}
Explanation

EncodeToString and DecodeString cover the common UTF-8 string ↔ Base64 use case.

Notes
  • Std: encoding/base64.
  • If your Base64 is URL-safe, use RawURLEncoding or URLEncoding.

Java

java
Java
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Main {
  public static void main(String[] args) {
    String text = "Hola mundo";
    String b64 = Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8));
    String decoded = new String(Base64.getDecoder().decode(b64), StandardCharsets.UTF_8);
    System.out.println(b64);
    System.out.println(decoded);
  }
}
Explanation

java.util.Base64 is standard since Java 8. It is the simplest correct approach for UTF-8 text.

Notes
  • Std.
  • For Base64URL use Base64.getUrlEncoder()/getUrlDecoder().

JavaScript

javascript
JavaScript
const text = "Hola mundo";
const b64 = Buffer.from(text, "utf8").toString("base64");
const decoded = Buffer.from(b64, "base64").toString("utf8");
console.log(b64);
console.log(decoded);
Explanation

In Node.js, Buffer handles UTF-8 and Base64 directly. Great for scripts and JS backends.

Notes
  • Node.js.
  • In browsers, avoid atob/btoa with Unicode unless you use TextEncoder/TextDecoder.

Kotlin

kotlin
Kotlin
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val text = "Hola mundo"
  val b64 = Base64.getEncoder().encodeToString(text.toByteArray(StandardCharsets.UTF_8))
  val decoded = String(Base64.getDecoder().decode(b64), StandardCharsets.UTF_8)
  println(b64)
  println(decoded)
}
Explanation

Kotlin/JVM uses the same Java Base64 API to encode/decode UTF-8 bytes.

Notes
  • Std (JVM).

PHP

php
PHP
<?php
$text = "Hola mundo";
$b64 = base64_encode($text);
$decoded = base64_decode($b64, true);
echo $b64 . PHP_EOL;
echo $decoded . PHP_EOL;
Explanation

base64_encode/base64_decode work well for UTF-8 text. Use strict=true on decode to catch invalid input.

Notes
  • Std.
  • If input is Base64URL, normalize -_ to +/ and add padding.

Python

python
Python
import base64

text = "Hola mundo"
b64 = base64.b64encode(text.encode("utf-8")).decode("ascii")
decoded = base64.b64decode(b64).decode("utf-8")
print(b64)
print(decoded)
Explanation

Convert to UTF-8 bytes before b64encode. For output, decode bytes back to UTF-8.

Notes
  • Std.

Ruby

ruby
Ruby
require "base64"

text = "Hola mundo"
b64 = Base64.strict_encode64(text)
decoded = Base64.decode64(b64)
puts b64
puts decoded
Explanation

strict_encode64 avoids newlines in Base64 output, which is typically what you want for tokens/headers.

Notes
  • Std.

Rust

rust
Rust
use base64::{engine::general_purpose::STANDARD, Engine as _};

fn main() {
  let text = "Hola mundo";
  let b64 = STANDARD.encode(text.as_bytes());
  let decoded = String::from_utf8(STANDARD.decode(&b64).unwrap()).unwrap();
  println!("{}", b64);
  println!("{}", decoded);
}
Explanation

The base64 crate encodes/decodes bytes. Convert to UTF-8 when the content is text.

Notes
  • Dependency: base64 = "0.22".

TypeScript

ts
TypeScript
const text = "Hola mundo";
const b64 = Buffer.from(text, "utf8").toString("base64");
const decoded = Buffer.from(b64, "base64").toString("utf8");
console.log(b64);
console.log(decoded);
Explanation

Same pattern as JS in Node: Buffer handles UTF-8 and Base64 directly.

Notes
  • Node.js.

VB.NET

vbnet
VB.NET
Imports System
Imports System.Text

Module Program
  Sub Main()
    Dim text = "Hola mundo"
    Dim b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(text))
    Dim decoded = Encoding.UTF8.GetString(Convert.FromBase64String(b64))
    Console.WriteLine(b64)
    Console.WriteLine(decoded)
  End Sub
End Module
Explanation

In .NET, the correct pattern is always string ↔ UTF-8 bytes ↔ Base64.

Notes
  • Std.

Related tools

Use the tool when you need to generate or validate output fast.

Trust and privacy

Copy/paste-friendly by design. Still, treat real production secrets carefully.

  • Prefer synthetic examples when sharing screens or recording.
  • Do not paste real API keys, tokens, or personal data unless you fully trust your environment.
  • If you need ordering, do not use UUID v4 as a sortable id: add createdAt or use sortable ids.