std.base64 — Codificação e Decodificação Base64
O módulo std.base64 oferece codificação e decodificação Base64 conforme as RFCs 4648 e 2045. Base64 é amplamente utilizado para representar dados binários em formato texto — em cabeçalhos HTTP, tokens JWT, codificação de imagens inline, transferência de dados em APIs e muito mais. O Zig oferece implementações tanto para o alfabeto padrão quanto para o URL-safe.
Visão Geral
const std = @import("std");
const base64 = std.base64;
Variantes Disponíveis
// Base64 padrão (RFC 4648 §4)
const standard = base64.standard;
// Base64 URL-safe (RFC 4648 §5) — usa '-' e '_' em vez de '+' e '/'
const url_safe = base64.url_safe;
Cada variante oferece sub-variantes com e sem padding:
// Com padding '=' (padrão)
standard.Encoder // codifica
standard.Decoder // decodifica
// Sem padding
standard.Encoder.no_pad
standard.Decoder.no_pad
Funções Principais
Codificação
// Calcula o tamanho da saída codificada
pub fn calcSize(source_len: usize) usize
// Codifica para um buffer de destino
pub fn encode(dest: []u8, source: []const u8) []u8
// Retorna o tamanho codificado
pub fn Encoder.calcSize(source_len: usize) usize
Decodificação
// Calcula o tamanho máximo da saída decodificada
pub fn calcSizeForSlice(encoded: []const u8) !usize
// Decodifica para um buffer de destino
pub fn decode(dest: []u8, source: []const u8) ![]u8
Exemplo 1: Codificação e Decodificação Básica
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const texto = "Olá, Zig! Base64 é útil para codificar dados binários.";
// Codificação
const encoder = std.base64.standard.Encoder;
var buf_encode: [256]u8 = undefined;
const encoded = encoder.encode(&buf_encode, texto);
try stdout.print("Original: {s}\n", .{texto});
try stdout.print("Base64: {s}\n", .{encoded});
// Decodificação
const decoder = std.base64.standard.Decoder;
var buf_decode: [256]u8 = undefined;
const decoded = try decoder.decode(&buf_decode, encoded);
try stdout.print("Decodificado: {s}\n", .{decoded});
try stdout.print("Iguais: {}\n", .{std.mem.eql(u8, texto, decoded)});
}
Exemplo 2: Base64 URL-Safe para Tokens
const std = @import("std");
fn codificarToken(dados: []const u8, buf: []u8) []u8 {
const encoder = std.base64.url_safe_no_pad.Encoder;
return encoder.encode(buf, dados);
}
fn decodificarToken(token: []const u8, buf: []u8) ![]u8 {
const decoder = std.base64.url_safe_no_pad.Decoder;
return decoder.decode(buf, token);
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Simula um payload de token
const payload = "{\"user_id\":42,\"role\":\"admin\",\"exp\":1708560000}";
var buf_encode: [256]u8 = undefined;
const token = codificarToken(payload, &buf_encode);
try stdout.print("Payload: {s}\n", .{payload});
try stdout.print("Token: {s}\n", .{token});
// Decodifica o token
var buf_decode: [256]u8 = undefined;
const decoded = try decodificarToken(token, &buf_decode);
try stdout.print("Decoded: {s}\n", .{decoded});
// Compara standard vs url_safe
var buf_std: [256]u8 = undefined;
const std_encoded = std.base64.standard.Encoder.encode(&buf_std, payload);
try stdout.print("\nStandard: {s}\n", .{std_encoded});
try stdout.print("URL-safe: {s}\n", .{token});
}
Exemplo 3: Codificação de Dados Binários
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const stdout = std.io.getStdOut().writer();
// Dados binários (bytes arbitrários)
const dados_binarios = [_]u8{
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // Header PNG
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0xFF, 0xFE, 0xFD, 0x00, 0x01, 0x02, 0x03, 0x04,
};
// Codifica
const encoder = std.base64.standard.Encoder;
const tamanho_necessario = encoder.calcSize(dados_binarios.len);
const encoded = try allocator.alloc(u8, tamanho_necessario);
defer allocator.free(encoded);
_ = encoder.encode(encoded, &dados_binarios);
try stdout.print("Bytes originais: {d}\n", .{dados_binarios.len});
try stdout.print("Base64 ({d} chars): {s}\n", .{ encoded.len, encoded });
// Decodifica e verifica
const decoder = std.base64.standard.Decoder;
const tamanho_decode = try decoder.calcSizeForSlice(encoded);
const decoded = try allocator.alloc(u8, tamanho_decode);
defer allocator.free(decoded);
const resultado = try decoder.decode(decoded, encoded);
try stdout.print("Bytes decodificados: {d}\n", .{resultado.len});
// Mostra como hex
try stdout.writeAll("Hex: ");
for (resultado) |byte| {
try stdout.print("{x:0>2} ", .{byte});
}
try stdout.writeAll("\n");
try stdout.print("Dados iguais: {}\n", .{
std.mem.eql(u8, &dados_binarios, resultado),
});
}
Referência Rápida
| Variante | Alfabeto | Padding | Uso Comum |
|---|---|---|---|
standard | A-Z, a-z, 0-9, +, / | = | Email (MIME), PEM |
standard_no_pad | A-Z, a-z, 0-9, +, / | Não | Algumas APIs |
url_safe | A-Z, a-z, 0-9, -, _ | = | URLs |
url_safe_no_pad | A-Z, a-z, 0-9, -, _ | Não | JWT, tokens |
Módulos Relacionados
- std.crypto — Funções criptográficas
- std.Uri — Parsing de URIs
- std.http — HTTP
- std.fmt — Formatação de strings