Explorando el contenido de los bloques en Bitcoin es inevitable encontrarnos con el formato hexadecimal. Por si alguno no lo conoce o lo conoce pero poco, vamos a aclararlo de la mejor forma posible.
Formato y valor
En primer lugar hay que diferenciar entre valor y los formatos de representación. El valor numérico 24, por ejemplo, en un ordenador está codificado internamente en formato binario, nosotros los acabamos de escribir en formato decimal y puede ser escrito en formato hexadecimal:
24 (decimal) = 00011000 (binario) = 18 (hexadecimal)
Independientemente de como lo visualice cada software para nosotros, internamente los datos se almacenan en binario. Cuando se trate de un valor numérico entero, las operaciones aritméticas se realizan considerando el valor en base 10 o sistema decimal. Sin embargo, cuando no trabajamos con enteros sino con datos crudos usamos los bits sin interpretar su valor numérico. Esto es así, por ejemplo, cuando hacemos un hash sha256 a una clave publica.
Entonces ¿ porqué tenemos interés en usar el formato hexadecimal cuando no es de utilidad interna ? Porque permite representar valores numéricos en menos espacio que en formato binario o en formato decimal, y porque la traducción de binario-hexadecimal-bytes es muy intuitiva. Veremos un ejemplo. Finalmente, el formato hexadecimal sirve también para tratar datos que no representan valores numéricos.
Sistema de numeración entero posicional
En Bitcoin solo se representan números enteros. No hay operaciones de punto flotante ni decimales. Si te estás preguntando cómo se almacenan las cantidades fraccionarias de Bitcoin como, por ejemplo, 0.5 Bitcoins, la respuesta es que internamente solo se almacena la cantidad entera de satoshis que siempre es un número entero, y puesto que 1e8 satoshis equivalen a 1 Bitcoin, podemos considerar y visualizar la cantidad como de 0.5 Bitcoins.
Un sistema de numeración posicional asigna a cada posición de un número una potencia de la base. En el sistema decimal la base es el 10 y hay 10 dígitos diferentes posibles (del 0 al 9). Así el ejemplo anterior
24 (decimal) = 2 * 10 ^1 + 4 * 10^0
La posición “cero” o unidades se calcula como el dígito multiplicado por la base elevado a 0 (cualquier número elevado a 0 vale 1). La posición de las decenas, se interpreta como el dígito de decenas multiplicado por la base elevada a 1. Las centenas elevarían la base a 2, etc…
Generalización
Un sistema de base b tiene b posibles dígitos. En cada posición de un número de varios dígitos se considerará que el dígito va multiplicado por la base elevada a la potencia que indica su posición. Así, si tenemos una base b con 16 posibles dígitos (b=16) :
18 (hexadecimal) = 1 * 16^1 + 8 * 16^0
Los 16 posibles dígitos hexadecimales son 0123456789ABCDEF.
A = 10 en decimal,
B = 11
C = 12
D = 13
E = 14
F = 15
Por tanto, cuando la base es 16 vemos números en formato hexadecimal y podemos encontrar las letras de la A a la F junto con los dígitos del 0 al 9. Da igual si las letras aparecen en minúsculas o mayúsculas.
De Hexadecimal a Binario
Un byte tiene 8 bits o 2 grupos de 4 bits. 4 bits permiten representar valores de 0 a 15, es decir, 16 valores. Esto nos permite concluir que:
- 1 byte puede almacenar 2 dígitos hexadecimales
- Cada dígito hexadecimal tiene una correspondencia directa con 4 bits en binario
Recuperando el ejemplo anterior:
18 (hexadecimal) = 0001 1000, donde
0001 en binario es "1" en hexadecimal, y
1000 en binario es "8" en hexadecimal.
Otro ejemplo:
AF (hexadecimal) = 1010 1111
Comentarios finales sobre la utilidad del formato hexadecimal
Además de todo lo dicho, hay objetos diferentes dentro de los bloques de la cadena Bitcoin. La mayoría de ellos tienen un tamaño exacto en bytes como las claves públicas, las firmas, los hashes, los txids etc… . Independientemente de que sirvan a la causa como números enteros, como información cruda o como identificador literal, pueden ser expresados para su visualización por el ojo humano de forma uniforme en una cantidad fija de bytes y caracteres gracias al formato hexadecimal.