1. Code
  2. Coding Fundamentals

¿Base qué? Introducción práctica a la codificación de bases

Scroll to top

Spanish (Español) translation by Esther (you can also view the original English article)

A una edad temprana, aprendemos a contar con los dedos, empezando por el 1-5, luego por el 1-10 y quizás, si eres especialmente emprendedor de pequeño, aprenderás a contar hasta el 20, el 30 y más allá. Nadie intenta nunca aclararnos que en realidad estamos haciendo algunos supuestos matemáticos más complejos; todos conocemos Base10, para ser precisos.

En este artículo, empezaremos por conocer mejor Base10 y su estructura, y después hablaremos del binario (Base2, los componentes básicos de la informática). Por último, terminaremos hablando de Base32 y Base64. En cada etapa discutiremos las ventajas y usos de cada tipo.


Por qué Base10

Tenemos 10 dedos.

Entonces, ¿por qué hemos elegido Base10? No es porque existan las formas de letra 0-9; eso fue en realidad el resultado de la elección de utilizar Base10. De hecho, lo más probable es que se deba al proceso de aprendizaje que decidimos anteriormente: tenemos 10 dedos. Esto hace que sea mucho más fácil de entender el sistema.

Así pues, hablemos un poco de cómo está estructurada Base10. Esta será la base de comprensión que utilizaremos en la discusión posterior.

Empezando por el 0, contamos hasta el 9, llenando la columna de los "1". Una vez que la columna de los unos está llena (tiene 9), ese es el máximo de la columna. Así que pasamos a la siguiente columna (a la izquierda), y empezamos en el 1. A todos los efectos, podemos postular que hay un número infinito de ceros a la izquierda antes de nuestra primera columna significativa. En otras palabras, "000008" es lo mismo que "8". Así, a medida que se llena cada columna, la siguiente se incrementa en uno, y volvemos a empezar en la columna anterior para llenarla de nuevo de la misma manera que antes. En concreto, la columna de los 1s aumenta de 0 a 9, y luego se añade otra decena a la columna de las decenas. Esto se continúa, y si la columna de las decenas está en 9 y la columna de los 1s está en 9, se añade 1 a la columna de los 100, y así sucesivamente. Todos conocemos esta pieza de la pizzería.

Consideremos el número 1020. Empezando por la derecha, podemos entenderlo como "0*1 + 2*10 + 0*100 + 1*1000". Ahora, consideremos el número 5.378. Podemos entenderlo como "8*1 + 7*10 + 3*100 + 5*1000". Una función generalizada para entender Base10, entonces, es la siguiente:

(10 elevado a la potencia de la columna de la derecha -1) * (el número encontrado en la columna)

Por lo tanto, si hay un 6 en la 5ª columna desde la derecha, 10^4*6 = 60.000.

Podemos ver que se trata de una fórmula generalizable para entender todos los sistemas de base.


Base2 (Binario)

Por ello, estos sistemas se denominan Base(N).

El siguiente sistema del que hablaremos es Base2, o binario. El binario consiste en dos dígitos, 0 y 1. Esto se presta bien a la informática por muchas razones, fundamentalmente porque los ordenadores se basan en interruptores que tienen dos estados: encendido o apagado. El binario es el sistema más básico necesario para todas las operaciones lógicas (piensa en "verdadero" y "falso").

Entonces, ¿cómo funciona el binario? Toma la fórmula de arriba, y en lugar de usar diez, usa dos. Y en ese sentido, es por lo que estos sistemas se denominan Base(N).

(2 elevado a la potencia de la columna de la derecha -1) * (el número encontrado en la columna)

Así pues, tomemos el número arbitrario 1001101 en binario, y apliquemos esta fórmula.

(1 * 1) + (0 * 2) + (1*4) + (1 * 8) + (16 * 0) + (32 * 0) + (64 * 1) = 77

"¡Espera!", estarás pensando. "Si el binario es todo lo que hacen los ordenadores, ¿cómo se escriben las letras en binario?". Buena pregunta. De hecho, esto nos lleva a la introducción de Base16.


Base16

En cambio, sería una representación de un solo dígito de 10.

Imaginemos, por un momento, que tenemos 11 dedos. Estaríamos utilizando naturalmente un sistema de Base11. Además de parecer incómodo de imaginar actualmente, ¿qué otras implicaciones tendría esto? Quizás la implicación más importante es que habríamos tenido otro incremento más allá del 9 en la columna de los 1s. Pero no sería un "10", porque el 10 no se limita a la columna de los 1s. En su lugar, sería una representación de un solo dígito de 10. Y, de hecho, así es exactamente como funcionan las letras en los sistemas de bases más allá de Base10 hasta Base62, con algunas salvedades (a las que llegaremos más adelante cuando hablemos de Base32).

Imaginemos que utilizamos Base11, pero sustituyendo el "10" de un solo dígito del que hablamos antes por una A mayúscula. ¿Cómo escribiríamos el número 54?

Como sabemos que la primera columna de la izquierda es la del "11", empezaríamos dividiendo 54 entre once, lo que nos da 4 con un resto de 10. Si la "A" representa el 10, en Base11 el número 54 se representaría como 4A.

Hagámoslo a la inversa, con la fórmula que utilizamos anteriormente.

(11 elevado a la potencia de la columna de la derecha - 1) * (el número encontrado en la columna)

En este caso, eso significaría:

(1 * A) + (4 * 11)

Ahora, sustituye A por 10:

(1*10) + (4*11) = 54

Hexadecimal

¿Te preguntarás qué utilidad tiene esto? Base11 no tiene por qué ser útil (a no ser que tengas algún tipo de estructura de datos que se beneficie de un sistema Base11). Sin embargo, Base16 se utiliza en todos los sistemas informáticos para múltiples propósitos. También conocido como hexadecimal, Base16 utiliza los números 0-9 seguidos de las letras a-f (no distingue entre mayúsculas y minúsculas). En particular, verás que se utilizan hexadecimales para definir los colores RGB en CSS (y en la mayoría de los widgets de selección de colores en el software de escritorio), con dos dígitos para cada uno de los canales rojo, verde y azul.

Así, por ejemplo, #A79104 produciría r = A7, g = 91, b = 04. En decimales, esto equivaldría a r = 167, g = 145, b = 4; el color resultante sería un amarillo dorado. Dos dígitos hexadecimales juntos pueden representar 256 números diferentes, por lo que hay 256^3 (16.777.216) combinaciones numéricas posibles en el sistema hexadecimal RGB, representadas por sólo 6 caracteres (o 3 si se utiliza el método abreviado, en el que cada uno de los tres dígitos se duplica implícitamente; por ejemplo, #37d == #3377dd).

Base16 se utiliza a menudo en los lenguajes ensambladores, que es el lenguaje de programación accesible de más bajo nivel. Como los hexadecimales son fáciles de convertir a binario, son una forma más fácil de escribir instrucciones en código ensamblador.

Nota: Lo mismo ocurre en general con la popularidad de Base32 y Base64; estas codificaciones se utilizan porque son naturalmente mejores para los datos binarios (porque son potencias de 2), y porque hay, al menos, 64 caracteres seguros (y no hay 128 caracteres seguros) en casi todos los ordenadores.

Para un ejemplo hexadecimal, tomemos el número 1100 en hexadecimal, que equivale a 4352 en decimal. El mismo número en binario es 0001 0001 0000 0000. La conversión de hexadecimal a binario es una operación sencilla que consiste en utilizar una tabla de conversión, donde el 0 en hexadecimal es 0000 en binario y la F en hexadecimal es 1111 en binario.

Nota que los 0's a la izquierda del primer número denotan que el número binario está en bits, mientras que los 0's del extremo izquierdo son simplemente columnas vacías. Fundamentalmente, no son necesarios; sin embargo, te encontrarás con el binario escrito de esta manera casi exclusivamente. Esta práctica se llama relleno, y se practica porque la longitud de los datos es desconocida, y por lo tanto podría causar problemas cuando se producen múltiples transmisiones de datos; al rellenar la cadena final, se garantiza que el tamaño de los datos sea, por ejemplo, de 4 bits de longitud (para binario). El relleno también se produce en otros esquemas de codificación comúnmente utilizados y basados en especificaciones; en particular, Base32 y Base64 utilizan el signo de igualdad ("=") para el relleno.


Base32

Se podría suponer que Base32 son los números del 0 al 9 y luego las primeras 22 letras del alfabeto (hasta la V).

¿Recuerdas cuando mencionamos la advertencia anterior? Esta es la advertencia: la definición más comúnmente aceptada de Base32 es en realidad una codificación que comienza con las primeras 26 letras del alfabeto y termina con los números 2-7. Se define en la solicitud de comentarios (RCFC) 4648 de la Internet Engineering Task Force, que también define Base16 y Base64. Nota, la diferencia es que la codificación para el 0 es A, no 0. Para codificar una cadena en Base32, suceden las siguientes instrucciones.

En primer lugar, la cadena a codificar se divide en bloques de 5 bytes (40 bits en binario). Las letras se representan con bloques de 8 bits en ASCII (el estándar de los ordenadores), así que por cada 5 letras hay 40 bits. (Esta definición de 8 bits para cada letra permite un total de 255 caracteres en ASCII).

A continuación, divide estos 40 bits en 8 bloques de cinco bits; así, por cada 5 letras, hay 8 bloques para codificar en base32. Asigna cada uno de estos bloques a una asignación de caracteres de 5 bits en el alfabeto Base32. Por ejemplo, si el bloque de cinco bits es 00010 (o decimal 2), el carácter mapeado es la letra c. Si el bloque de cinco bits es 01010 (decimal 10), el carácter mapeado es la letra K.

Apliquemos estos pasos a la cadena "yessir".

Caracter ASCII Decimal Binario ASCII de 8 bits
y 89 01111001
e 101 01100101
s 115 01110011
s 115 01110011
i 105 01101001
r 114 01110010

Tomemos las representaciones binarias y concatémoslas ahora, dividiéndolas en grupos de 5 bits

1
01111 	00101 	 10010 	 10111 	 00110 	 11100 	 11011 	 01001
2
01110 	010(00)   null 	 null 	 null 	 null 	 null 	 null

Una nota sobre lo anterior: como la especificación define que la codificación debe hacerse en trozos de 8 piezas de 5 bits, tenemos que rellenar con 0 si el número de bits no es divisible por 5 (de ahí el 010(00) de la segunda línea) y con = si el número de trozos no es divisible por 8. Los valores "nulos" serán sustituidos por el carácter de relleno, "=".

Cada uno de estos números binarios de 5 bits corresponde a un carácter del alfabeto de 32 bits; en concreto, la salida para yessir sería PFSXG43JOI======

Se sigue un proceso similar para Base64. Hay algunas diferencias fundamentales entre Base32 y Base64. Base64 incluye las letras A-Z, a-z, los números 0-9 y los símbolos + y /. Como se ha mencionado anteriormente, el símbolo "=" se utiliza para el relleno. Las diferencias son principalmente que todas las letras distinguen entre mayúsculas y minúsculas, y que se utilizan todos los dígitos (en lugar del subconjunto 2-7). También se añaden los símbolos + y /.

El proceso de codificación Base64 toma cadenas de 24 bits (3 letras) y las divide en cuatro trozos de 6 bits, asignando el número binario resultante al alfabeto Base64. Veamos nuestro ejemplo anterior, la cadena "yessir".

1
8-bit binary: 01111001 01100101 01110011 01110011 01101001 01110010
2
6-bit chunks: 011110 010110 010101 110011 011100 110110 100101 110010
3
Base64:		  eWVzc2ly

Hay que tener en cuenta algunas cosas importantes. En primer lugar, Base64 distingue entre mayúsculas y minúsculas. En segundo lugar, como el número de bits (48) era divisible por 6, no era necesario el relleno de bits. El número de trozos de 6 bits también era divisible por cuatro (lo que también significa que el número de caracteres de entrada era divisible por 3), por lo que tampoco era necesario el relleno nulo ("=").


Resumen de Base16, Base32 y Base64

Estas bases binario-amigables se aprovechan en todas las estructuras de programación.

Estas bases binario-amigables se aprovechan en todas las estructuras de programación. Los datos binarios se codifican en estas bases para garantizar la fidelidad de la transferencia y bloquear los errores que puedan surgir de una transferencia accidental de datos binarios sin codificar. Se basan en tablas de caracteres basadas en estándares, y solo se garantiza su funcionamiento si tanto el codificador como el descodificador utilizan la misma tabla; por ejemplo, hay versiones modificadas de base32 ampliamente aceptadas, incluida una de Douglas Crockford que cambia algunos de los caracteres aceptables, incluida la letra "u", para evitar obscenidades involuntarias.


La codificación en la práctica

Además de utilizar los números hexadecimales de forma habitual para los colores CSS, Base32 y Base64 se utilizan en la web de forma constante. Aunque el proceso de codificación oficial de Base32 y Base64 infla el tamaño de la cadena, codificar números en Base64 o Base32 puede ser muy beneficioso para cosas como el acortamiento de URL, donde una URL podría apuntar a /foo/id. Considera los siguientes números decimales y sus equivalentes en Base32 y Base64.

Decimal Base16 Base32
20 U U
50 bs y
967 6h PH
745619 WYET C2CT
7241930 G5AGK boDK
798312345192 xhpr7lti LnfH65o

Como puedes ver, hay ventajas significativas al usar Base64 o Base32 para acortar los números. Cuando cada carácter cuenta, el uso de estas codificaciones base permite ahorrar caracteres. En muchos casos, el número codificado tiene aproximadamente la mitad de la longitud del número no codificado.


Nota sobre Base62 y Base64 modificado por Url

¿Qué otros tipos de aplicaciones web encontrarías para estas codificaciones?

Si codificas en Base64 el número 959, el resultado es O/. Por supuesto, este no es un valor seguro para url debido a la "/", por lo que una url que apunte a O/ no se decodificaría como O/, sino como O (que es el valor decimal 14). Además, sería inútil codificar la "/" como su equivalente en código ASCII (%47%), ya que eso alargaría considerablemente la URL. Han surgido dos soluciones principales para combatir este problema. Una de ellas es una variante de Base64 segura para las urls que sustituye el + y el / por el - y el _, respectivamente. También elimina la especificación de añadir caracteres = para el relleno. La otra opción es pasar a una codificación Base62, que conserva casi todas las ventajas de Base64 y elimina el + y el /. Sin embargo, la codificación Base62 no es tan fácil de aplicar como sustituto de la transmisión binaria y, por tanto, es mucho menos popular.


Conclusión

Eso es todo. Ahora, tienes un conocimiento fundamental de los sistemas de bases, particularmente en lo que se refiere a la codificación de datos binarios. ¿Qué otros tipos de aplicaciones web podrías encontrar para estas codificaciones?