La codificación Base16 es un mecanismo estándar para representar secuencias de bytes como cadenas legibles compuestas únicamente por caracteres alfanuméricos. Su nombre proviene del uso de una base numérica de 16 símbolos, equivalente al sistema hexadecimal tradicional.
Fundamentos matemáticos
En aritmética posicional, la base define la cantidad de dígitos distintos disponibles en un sistema numérico. Por ejemplo:
- Base2: emplea
0y1. - Base10: usa los dígitos del
0al9. - Base16: combina
0–9yA–F(oa–f), totalizando 16 símbolos únicos.
Propósito en informática
Base16 no es un cifrado, sino una transformación reversible que convierte datos binarios en texto plano. Sus aplicaciones clave incluyen:
- Compatibilidad con protocolos textuales: muchos sistemas (como HTTP headers o URLs) rechazan bytes fuera del rango ASCII imprimible; Base16 garantiza que todos los bytes se mapeen a caracteres válidos.
- Legibilidad humana: facilita la depuración y el intercambio manual de hashes, claves o firmas digitales.
- Integridad de transmisión: evita interpretaciones erróneas de bytes como caracteres de control (ej.
\x00,\x0A) durante el transporte.
Conjunto de símbolos
El alfabeto Base16 está normalizado en RFC 4648 y consiste en:
0 1 2 3 4 5 6 7 8 9 A B C D E F
Las variantes minúsculas (a–f) son aceptables si se mantiene la consistencia dentro de un contexto dado.
Mecanismo de conversión
Cada byte (8 bits) se divide en dos nibbles (4 bits cada uno). Cada nibble se traduce directamente a un carácter Base16:
- Convertir el byte original a su representación binaria de 8 bits (ej.
'H'→01001000en ASCII). - Dividirlo en dos grupos:
0100y1000. - Mapear cada grupo a su valor decimal (
0100₂ = 4,1000₂ = 8) y luego al símbolo correspondiente (4 → '4',8 → '8').
Aplicado a la cadena "Hel":
| Carácter | Código ASCII (hex) | Base16 resultante |
|---|---|---|
| H | 48 | 48 |
| e | 65 | 65 |
| l | 6C | 6C |
Resultado final: "48656C".
Impacto en tamaño
Base16 introduce una expansión fija del 100%: cada byte de entrada genera exactamente dos caracteres ASCII imprimibles. Esto contrasta con Base64 (expansión ~33%) y es una ventaja cuando se prioriza simplicidad sobre eifciencia.
Implementación práctica
En Python, se puede implementar sin dependencias externas:
def to_base16(data: bytes) -> str:
return ''.join(f'{b:02X}' for b in data)
def from_base16(encoded: str) -> bytes:
if len(encoded) % 2 != 0:
raise ValueError("Longitud impar no válida")
return bytes(int(encoded[i:i+2], 16) for i in range(0, len(encoded), 2))
# Ejemplo
original = b"Hel"
codificado = to_base16(original) # "48656C"
decodificado = from_base16(codificado) # b"Hel"