Conversión de bases numéricas: binario, hexadecimal, octal y decimal para desarrolladores
Una tarde cualquiera: estás mirando 0x7FFF5FBFF8C0 en el depurador, cambias a un archivo CSS para ajustar #FF5733 y luego ejecutas chmod 755 en la terminal. Tres representaciones distintas, la misma aritmética de fondo. Si alguna vez necesitas pensar antes de convertir entre hexadecimal y binario, o te preguntas por qué Unix usa octal para los permisos, este artículo conectará esos puntos.
Cubrimos los cuatro sistemas numéricos que aparecen a diario en programación, tres métodos de conversión que vale la pena memorizar, y código funcional en JavaScript, Python, Go y C. Si quieres saltarte la teoría y convertir un número directamente, abre nuestro conversor de base — soporta cualquier base de 2 a 36 con precisión arbitraria.
Los cuatro sistemas numéricos que todo desarrollador usa
Cada base existe en programación por una razón práctica.
Binario (base 2) — El idioma de la máquina
Dos dígitos: 0 y 1. Un transistor conduce o no conduce — esa restricción física da origen al binario. Lo encontrarás al trabajar con máscaras de bits, flags, operaciones bit a bit y cálculos de subredes IP.
El binario se vuelve extenso rápidamente. El número 255 en decimal es 11111111 en binario — ocho dígitos para un valor de tres dígitos. Por eso los programadores rara vez escriben binario crudo, excepto cuando la posición de cada bit importa.
Octal (base 8) — La taquigrafía de Unix
Ocho dígitos: 0 a 7. Cada dígito octal mapea exactamente a tres bits binarios, razón por la cual los permisos de archivos en Unix usan octal — chmod 755 comprime tres grupos de tres bits en tres dígitos legibles.
El octal tenía un papel más amplio en la era del PDP-11, cuando las palabras de máquina se dividían en grupos de 3 bits. Hoy es básicamente exclusivo de los permisos Unix, más algún literal en C con prefijo 0 (fuente de bugs cuando alguien escribe 0177 creyendo que es el decimal 177).
Decimal (base 10) — El predeterminado humano
Diez dígitos: 0 a 9. Es el sistema que tu cerebro usa por defecto — números de puerto, índices de arreglo, códigos HTTP, dimensiones en píxeles. La computadora no piensa en decimal, pero los humanos sí, así que todo número orientado al usuario sale en base 10.
Hexadecimal (base 16) — La navaja suiza del desarrollador
Dieciséis símbolos: 0-9 y A-F. Cada dígito hex representa exactamente cuatro bits (un nibble). Dos dígitos hex = un byte. Siempre.
Encontrarás hexadecimal en direcciones de memoria (0x7FFF5FBFF8C0), colores CSS (#FF5733), direcciones MAC (00:1A:2B:3C:4D:5E), formato UUID y resúmenes de hash. Es la lengua franca de la programación a nivel de byte.
Prueba la conversión entre los cuatro sistemas en nuestro conversor de base — ingresa un valor en cualquier base y los demás se actualizan al instante.
Cómo funciona la conversión de bases: tres métodos fundamentales
No necesitas una herramienta para convertir entre bases, aunque ciertamente acelera el proceso. Tres métodos cubren todos los casos.
Método 1 — Expansión posicional (cualquier base → decimal)
Todo sistema posicional funciona igual: cada dígito se multiplica por la base elevada a la potencia de su posición, contando de derecha a izquierda desde cero.
Binario 1011:
1×2³ + 0×2² + 1×2¹ + 1×2⁰
= 8 + 0 + 2 + 1
= 11
Hex FF:
15×16¹ + 15×16⁰
= 240 + 15
= 255
En código, la mayoría de los lenguajes tienen una función de análisis:
parseInt('1011', 2) // 11
parseInt('FF', 16) // 255
parseInt('755', 8) // 493
Método 2 — División sucesiva (decimal → cualquier base)
Para ir en la dirección contraria, divide el número decimal por la base objetivo repetidamente y recopila los restos. Léelos de abajo hacia arriba.
Decimal 255 → hexadecimal:
255 ÷ 16 = 15 resto 15 (F)
15 ÷ 16 = 0 resto 15 (F)
→ De abajo hacia arriba: FF
Decimal 42 → binario:
42 ÷ 2 = 21 resto 0
21 ÷ 2 = 10 resto 1
10 ÷ 2 = 5 resto 0
5 ÷ 2 = 2 resto 1
2 ÷ 2 = 1 resto 0
1 ÷ 2 = 0 resto 1
→ De abajo hacia arriba: 101010
bin(42) # '0b101010'
hex(255) # '0xff'
oct(493) # '0o755'
Método 3 — Agrupación de bits (binario ↔ hex/octal directo)
Este es el método que los desarrolladores experimentados usan a diario. Como 16 = 2⁴ y 8 = 2³, la conversión entre binario y hex (u octal) se hace agrupando bits directamente, sin aritmética.
Binario → Hex: Agrupa en nibbles (4 bits) desde la derecha. Rellena el grupo más a la izquierda con ceros si es necesario.
Binario: 1010 1111
Hexadecimal: A F
→ AF
Binario → Octal: Agrupa en tripletes (3 bits) desde la derecha.
Binario: 111 101 101
Octal: 7 5 5
→ 755
La tabla de correspondencia de nibbles merece ser memorizada:
| Binario | Hex | Binario | Hex |
|---|---|---|---|
0000 | 0 | 1000 | 8 |
0001 | 1 | 1001 | 9 |
0010 | 2 | 1010 | A |
0011 | 3 | 1011 | B |
0100 | 4 | 1100 | C |
0101 | 5 | 1101 | D |
0110 | 6 | 1110 | E |
0111 | 7 | 1111 | F |
Con esta tabla interiorizada, convertir binario a hex se vuelve lectura directa.
Conversión de bases en cada lenguaje
Código práctico en los cuatro lenguajes donde esta operación aparece con más frecuencia.
JavaScript / TypeScript
// Análisis: cadena en cualquier base → número
parseInt('FF', 16) // 255
parseInt('101010', 2) // 42
parseInt('755', 8) // 493
// Formato: número → cadena en cualquier base
(255).toString(16) // 'ff'
(42).toString(2) // '101010'
(493).toString(8) // '755'
// Literales
const bin = 0b11111111; // 255
const oct = 0o377; // 255
const hex = 0xff; // 255
// BigInt para valores mayores a 2⁵³
const big = BigInt('0xFFFFFFFFFFFFFFFF');
big.toString(2) // 64 unos
big.toString(10) // '18446744073709551615'
Python
# Decimal → otras bases (cadenas con prefijo)
bin(255) # '0b11111111'
oct(493) # '0o755'
hex(255) # '0xff'
# Otras bases → decimal
int('11111111', 2) # 255
int('FF', 16) # 255
int('755', 8) # 493
# Salida formateada con relleno
f'{255:08b}' # '11111111' (binario de 8 dígitos)
f'{255:02x}' # 'ff' (hex minúsculas)
f'{255:02X}' # 'FF' (hex mayúsculas)
# Precisión arbitraria nativa en Python
big = int('F' * 64, 16) # número de 256 bits, sin desbordamiento
Go
package main
import (
"fmt"
"strconv"
)
func main() {
// Formato: int → cadena en cualquier base
fmt.Println(strconv.FormatInt(255, 16)) // "ff"
fmt.Println(strconv.FormatInt(255, 2)) // "11111111"
fmt.Println(strconv.FormatInt(493, 8)) // "755"
// Análisis: cadena en cualquier base → int
n, _ := strconv.ParseInt("FF", 16, 64) // 255
fmt.Println(n)
// Verbos de Printf
fmt.Printf("%b %o %x %d\n", 255, 255, 255, 255)
// 11111111 377 ff 255
}
C
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main() {
// Salida en decimal, octal, hexadecimal
printf("%d %o %x\n", 255, 255, 255);
// 255 377 ff
// Análisis desde cualquier base
long val = strtol("FF", NULL, 16); // 255
long bin = strtol("101010", NULL, 2); // 42
// C no tiene printf binario nativo — extracción bit a bit:
uint8_t byte = 0xAF;
for (int i = 7; i >= 0; i--)
putchar(((byte >> i) & 1) ? '1' : '0');
// 10101111
return 0;
}
Escenarios reales de conversión de bases
Cinco situaciones donde la conversión de bases deja de ser académica y pasa a ser parte del trabajo.
1. Depuración de direcciones de memoria
El depurador muestra un puntero en 0x7FFF5FBFF8C0. Convertir los últimos dos bytes a binario — 1000 1100 0000 — revela que la dirección está alineada a 64 bytes (seis ceros finales). La alineación impacta el rendimiento del caché, las operaciones SIMD y la E/S mapeada en memoria.
La aritmética de punteros también es más clara en hex. Un desplazamiento de 0x100 desde una dirección base son exactamente 256 bytes — una página en muchos sistemas embebidos.
2. Colores CSS hexadecimales ↔ RGB
El color #FF5733 son tres bytes empaquetados como pares hexadecimales:
| Par | Hex | Decimal | Canal |
|---|---|---|---|
FF | FF | 255 | Rojo (máx) |
57 | 57 | 87 | Verde |
33 | 33 | 51 | Azul |
La notación abreviada #F00 se expande a #FF0000 — rojo puro. La variante de 8 dígitos #FF573380 agrega canal alfa, donde 80 (decimal 128) es aproximadamente 50% de opacidad.
3. Permisos de archivos Unix (octal)
chmod 755 se descompone así:
7 → 111 → rwx (propietario: lectura + escritura + ejecución)
5 → 101 → r-x (grupo: lectura + ejecución)
5 → 101 → r-x (otros: lectura + ejecución)
Cada dígito octal codifica un grupo de permisos porque tres bits de permiso (lectura=4, escritura=2, ejecución=1) mapean a un solo dígito octal (0-7). Combinaciones comunes:
| Octal | Binario | Permisos | Uso típico |
|---|---|---|---|
755 | 111 101 101 | rwxr-xr-x | Ejecutables, directorios |
644 | 110 100 100 | rw-r--r-- | Archivos regulares |
700 | 111 000 000 | rwx------ | Scripts privados |
600 | 110 000 000 | rw------- | Claves SSH, secretos |
4. Cálculos de subredes
Una máscara /24 significa 24 unos iniciales en binario:
11111111.11111111.11111111.00000000
→ 255.255.255.0
Para encontrar la dirección de red, aplica AND bit a bit entre la IP y la máscara:
192.168.1.37 → 11000000.10101000.00000001.00100101
255.255.255.0 → 11111111.11111111.11111111.00000000
Resultado AND → 11000000.10101000.00000001.00000000
→ 192.168.1.0 (dirección de red)
Los ingenieros de redes alternan constantemente entre decimal (notación IP), binario (cálculos de máscara) y hexadecimal (capturas de paquetes). Nuestro conversor de base permite verificar cada octeto individualmente.
5. Lectura de resúmenes hash y UUID
Un hash MD5 como d41d8cd98f00b204e9800998ecf8427e contiene 32 caracteres hexadecimales, representando 16 bytes (128 bits). Cada par de dígitos hex es un byte.
Un UUID sigue el patrón 8-4-4-4-12 en hexadecimal:
550e8400-e29b-41d4-a716-446655440000
32 dígitos hex separados por guiones — los mismos 128 bits, con distinto formato. El nibble de versión está en la posición 13 (el 4 en 41d4 indica UUID v4).
Genera hashes con nuestro generador de hash MD5 & SHA o crea UUID con nuestro generador de UUID — ambos producen salida hexadecimal.
Más allá de base 16: base 36, base 64 y bases personalizadas
Las cuatro bases estándar cubren la mayoría del trabajo, pero algunas otras aparecen en contextos especializados.
Base 36 — Codificación alfanumérica compacta
Base 36 usa los 10 dígitos más las 26 letras (A-Z), ofreciendo la representación alfanumérica insensible a mayúsculas más compacta posible. Los servicios de acortamiento de URL la aprovechan — IDs de videos de YouTube, enlaces cortos y claves de bases de datos a menudo usan base 36.
(1000000).toString(36) // 'lfls'
parseInt('lfls', 36) // 1000000
Un millón se comprime en cuatro caracteres. Para identificadores cortos compatibles con URL, es difícil mejorar eso.
Base 64 — Codificación de datos (no un sistema numérico)
Base64 parece otra base, pero su propósito es diferente. En lugar de representar un valor numérico en un sistema posicional, Base64 codifica datos binarios arbitrarios (imágenes, archivos, tokens JWT) como texto ASCII. Usa A-Z, a-z, 0-9, + y / — 64 símbolos en total.
Es un esquema de codificación, no un sistema numérico. Para codificar y decodificar Base64, usa nuestro codificador-decodificador Base64.
Bases arbitrarias (2-36) y dónde aparecen
Algunas otras bases surgen ocasionalmente:
- Base 12 (duodecimal): Tiempo (12 horas), cantidades (docena). Algunos matemáticos argumentan que base 12 sería mejor que base 10 porque 12 tiene más divisores.
- Base 60 (sexagesimal): Tiempo (60 segundos, 60 minutos) y ángulos (360°). Heredado de las matemáticas babilónicas.
- Base 32: Codificación Base32 de Crockford para identificadores legibles (excluye caracteres ambiguos como I, L, O). También se usa en geohashing.
Nuestro conversor de base soporta cualquier base entera de 2 a 36.
Operaciones bit a bit y conversión de bases
Entender el binario no es solo para convertir números — es la base de las operaciones bit a bit que aparecen en programación de sistemas, desarrollo de videojuegos y sistemas de permisos.
const READ = 0b100; // 4
const WRITE = 0b010; // 2
const EXEC = 0b001; // 1
// Combinar permisos con OR
const perms = READ | WRITE; // 0b110 = 6
// Verificar un permiso con AND
(perms & READ) !== 0 // true — tiene lectura
(perms & EXEC) !== 0 // false — sin ejecución
// Alternar un permiso con XOR
perms ^ WRITE // 0b100 = 4 — escritura removida
// Desplazamientos
1 << 3 // 0b1000 = 8 (1 desplazado 3 a la izquierda)
0xFF >> 4 // 0b00001111 = 15 (desplazamiento derecho 4 = dividir por 16)
Flags de funcionalidades, registros de hardware, protocolos de red, programación gráfica — todos dependen de operaciones bit a bit. Cuando lees binario con fluidez, la manipulación de bits deja de parecer magia.
FAQ
¿Cuáles son los cuatro sistemas numéricos principales en programación?
Binario (base 2), octal (base 8), decimal (base 10) y hexadecimal (base 16). El binario es la forma física de los datos en el hardware. El octal sirve para permisos Unix. El decimal es el predeterminado para humanos. El hexadecimal comprime el binario en formato legible — cada dígito hex equivale a exactamente 4 bits.
¿Cómo convierto binario a hexadecimal?
Agrupa los bits en conjuntos de 4 desde la derecha, rellenando el último grupo a la izquierda con ceros. Mapea cada grupo: 0000=0, 0001=1, …, 1010=A, …, 1111=F. Ejemplo: binario 10101111 → grupos 1010 1111 → hex AF. Funciona porque 16 = 2⁴.
¿Cómo convierto hexadecimal a decimal?
Multiplica cada dígito hex por 16 elevado a la potencia de su posición (la más a la derecha = 0), luego suma. Recuerda: A=10, B=11, C=12, D=13, E=14, F=15. Ejemplo: hex FF = 15×16¹ + 15×16⁰ = 240 + 15 = 255. En código: JavaScript parseInt('FF', 16), Python int('FF', 16).
¿Por qué los desarrolladores usan hexadecimal en vez de binario?
El hex es compacto. Cada dígito hex mapea exactamente a 4 bits, así que 11111111 00001010 en binario se convierte en FF0A en hex — mucho más corto y fácil de leer. El hex es el estándar para direcciones de memoria, colores CSS (#FF5733), direcciones MAC, salidas de hash y formato UUID.
¿Qué es un nibble y qué relación tiene con la conversión hex?
Un nibble son 4 bits — medio byte. Un nibble mapea exactamente a un dígito hexadecimal, lo que hace que la conversión binario-hex sea una simple consulta nibble por nibble. Un byte = dos nibbles = dos dígitos hex. Esta correspondencia limpia de 4 bits es la razón por la que el hex se convirtió en el estándar para datos a nivel de byte.
¿Por qué los permisos Unix se escriben en octal?
Cada grupo de permisos tiene tres bits: lectura (4), escritura (2), ejecución (1). Hay tres grupos (propietario, grupo, otros). Como 2³ = 8, tres bits de permiso corresponden a un solo dígito octal. 755 significa propietario=7 (rwx), grupo=5 (r-x), otros=5 (r-x). El octal es la base natural para agrupaciones de 3 bits.
¿Cómo manejo números mayores a 2⁵³ en JavaScript?
Usa BigInt. Agrega n a un literal o usa el constructor BigInt(): BigInt('0xFFFFFFFFFFFFFFFF').toString(2) produce la cadena binaria completa de 64 bits. El tipo Number estándar pierde precisión más allá de 9.007.199.254.740.991 (2⁵³ - 1). Nuestro conversor de base usa BigInt internamente, procesando números de cualquier tamaño sin pérdida de precisión.
¿Cómo convierto hexadecimal a binario?
Sustituye cada dígito hex por su equivalente de 4 bits usando la tabla de nibbles al revés: 0=0000, 1=0001, …, A=1010, …, F=1111. Ejemplo: hex AF → A (1010) + F (1111) → binario 10101111. En código: JavaScript parseInt('AF', 16).toString(2) o Python bin(int('AF', 16))[2:].
¿Cómo represento los bits setuid, setgid y sticky en octal?
Los bits especiales se añaden como un cuarto dígito octal inicial: setuid (4), setgid (2), sticky (1). chmod 4755 activa setuid (binario 100 111 101 101 = el ejecutable corre con los privilegios del propietario, como passwd). chmod 2755 activa setgid (binario 010 ..., común en directorios compartidos). chmod 1777 activa el sticky bit (binario 001 ..., como /tmp, donde solo el propietario puede borrar sus propios archivos). Con ls -l estos bits aparecen como s, s y t en lugar de x en la columna correspondiente.