Diferencia entre revisiones de «Codificación Base58Check»

De Bitcoin Wiki
Saltar a: navegación, buscar
(Traducción de artículo completo de la wiki inglesa)
 
(Revisión)
Línea 1: Línea 1:
Las [[Dirección|direcciones Bitcoin]] se codifican mediante una forma modificada de la [http://en.wikipedia.org/wiki/Binary-to-text_encoding binary-to-text codificación] Base 58 a la que se conoce como '''Base58Check'''.
+
Las [[Dirección|direcciones Bitcoin]] se codifican mediante una forma modificada de la [http://es.wikipedia.org/wiki/Codificaci%C3%B3n_de_binario_a_texto codificación] Base 58 a la que se conoce como '''Base58Check'''.
  
De manera general, la codificación Base58Check se utiliza para codificar secuencias de bytes utilizadas en Bitcoin en un formato de cadenas de texto legibles para el ser humano. Una dirección Bitcoin es simplemente una cadena de texto codificada como Base58Check que contiene unos datos útiles de 20 bytes, que consisten en el ''hash'' de la [[clave pública]] asociada con la dirección.
+
De manera general, la codificación Base58Check se utiliza para codificar secuencias de bytes utilizadas en Bitcoin convirtiéndolas en un formato de texto legible para el ser humano. Una dirección Bitcoin es simplemente una cadena de texto codificada como Base58Check que contiene unos datos útiles de 20 bytes de longitud, que consisten en el ''hash'' de la [[clave pública]] asociada con la dirección.
  
 
En el código fuente del cliente original de Bitcoin, [[Satoshi Nakamoto]] comentó la justificación del uso de Base58Check:
 
En el código fuente del cliente original de Bitcoin, [[Satoshi Nakamoto]] comentó la justificación del uso de Base58Check:
Línea 21: Línea 21:
  
 
==Caracterísitcas de Base58Check==
 
==Caracterísitcas de Base58Check==
 +
 
Base58Check presenta las siguientes características:
 
Base58Check presenta las siguientes características:
* Unos datos útiles de tamaño arbitrario.
+
* Datos útiles de tamaño arbitrario.
 
* Un conjunto de 58 símbolos alfanuméricos que incluyen letras minúsculas y mayúsculas fácilmente distinguibles (no se utilizan 0OIl).
 
* Un conjunto de 58 símbolos alfanuméricos que incluyen letras minúsculas y mayúsculas fácilmente distinguibles (no se utilizan 0OIl).
* Un byte de información de versión/aplicación. Las direcciones Bitcoin utilizan 0x00 para este byte (en el futuro se podría utilizar 0x05).
+
* Un byte de información de versión/aplicación. Las direcciones Bitcoin tradicionales utilizan 0x00 para este byte. Las nuevas direcciones que permiten multifirma utilizan 0x05.
 
* Cuatro bytes (32 bits) de un código de comprobación de errores basado en SHA-256. Este código puede emplearse para detectar automáticamente e incluso corregir errores tipográficos.
 
* Cuatro bytes (32 bits) de un código de comprobación de errores basado en SHA-256. Este código puede emplearse para detectar automáticamente e incluso corregir errores tipográficos.
 
* Un paso adicional para preservar los ceros iniciales de los datos.
 
* Un paso adicional para preservar los ceros iniciales de los datos.
  
 
==Cómo crear una cadena Base58Check==
 
==Cómo crear una cadena Base58Check==
 +
 
Una cadena de texto Base58Check se crea a partir de un byte de versión/aplicación de la manera siguiente:
 
Una cadena de texto Base58Check se crea a partir de un byte de versión/aplicación de la manera siguiente:
 
# Tomar el byte de versión/aplicación y los bytes de los datos útiles y concatenarlos (como bytes).
 
# Tomar el byte de versión/aplicación y los bytes de los datos útiles y concatenarlos (como bytes).
# Calcular SHA256(SHA256(resultado paso 1)), aplicación reiterada por dos veces del algortimo de ''hash'' SHA256 y quedarse con los cuatro primeros bytes.
+
# Calcular SHA256(SHA256(resultado paso 1)), aplicación reiterada por dos veces del algoritmo de ''hash'' SHA-256, y quedarse con los cuatro primeros bytes.
 
# Concatenar los resultados del paso 1 y el paso 2 (como bytes).
 
# Concatenar los resultados del paso 1 y el paso 2 (como bytes).
# Considerar el resultado del paso 3, una secuencia de bytes, como un ''bignumber'' único en formato ''big-endian'', convertirlo a base-58 utilizando transformaciones matemáticas normales(división de ''bignumbers'') y el alfabeto de base-58 descrito más abajo. Normalizar el resultado para que no tenga ceros de base-58 (el carácter '1') iniciales.
+
# Considerar la secuencia de bytes resultado del paso 3 como un ''bignumber'' único en formato ''big-endian'' y convertirlo a base-58 utilizando transformaciones matemáticas normales(división de ''bignumbers'') y el alfabeto de base-58 descrito más abajo. Normalizar el resultado para que no tenga ceros de base-58 (el carácter '1') iniciales.
# El carácter inicial '1', que corresponde al valor cero en base58, se reserva para representar un '''byte''' cero inicial, al proncipio de los datos y no tiene valor como símbolo base-58. Puede haber uno o más caracteres '1' iniciales para representar uno o más ceros iniciales. Contar el número de bytes cero inicialesque han aparecido en el resultado del paso 3 (para las direcciones Bitcoin antiguas siempre habrá al menos uno para el byte de versión/aplicación; para las direcciones nuevas no habrá ninguno). Cade byte cero inicial estará representado por un '1' en el resultado final.
+
# El carácter inicial '1', que corresponde al valor cero en base58, se reserva para representar un '''byte''' cero inicial, al principio de los datos, y no tiene valor como símbolo base-58. Puede haber uno o más caracteres '1' iniciales para representar uno o más ceros iniciales. Contar el número de bytes cero iniciales que han aparecido en el resultado del paso 3 (para las direcciones Bitcoin antiguas siempre habrá al menos uno para el byte de versión/aplicación; para las direcciones del formato multifirma más nuevo no habrá ninguno). Cada byte cero inicial estará representado por un '1' en el resultado final.
# Concatenar los caracteres '1' del paso 5 con los resultados del paso 4. '''Se obtiene así el resultado Base58Check.'''
+
# Concatenar los caracteres '1' del paso 5 con los resultados del paso 4. '''Se obtiene así el resultado Base58Check.'''
  
 
==Cómo codificar una dirección Bitcoin==
 
==Cómo codificar una dirección Bitcoin==
Línea 42: Línea 44:
 
las direcciones Bitcoin son el resultado de aplicar la codificación Base58Check al valor ''hash'' del [[script]] asociado. En concreto, es Base58Check(5,[[RIPEMD160]]([[SHA256]]([[script]]))), con las siguientes restricciones:
 
las direcciones Bitcoin son el resultado de aplicar la codificación Base58Check al valor ''hash'' del [[script]] asociado. En concreto, es Base58Check(5,[[RIPEMD160]]([[SHA256]]([[script]]))), con las siguientes restricciones:
  
* [[RIPEMD160]] y [[SHA256]] en este caso son siempre exactamente 20 y 32 bytes sin signo respectivamente. Están en formato ''big-endian'' (el byte más significativo en primer lugar). Han de evitarse implementaciones de valores [[bignumber]] que recortan los butes nulos 0x00 iniciales o que agregan bytes nulos 0x00 al final para indicar el signo. El código ha de manejar bien estos casos o, de lo contrario, se generarían direcciones que parecerían válidas pero cuyos saldos nunca podrían ser gastados, con lo que se perderían esos fondos para siempre.
+
* [[RIPEMD160]] y [[SHA256]] en este caso son siempre exactamente 20 y 32 bytes sin signo respectivamente. Están en formato ''big-endian'' (el byte más significativo en primer lugar). Han de evitarse implementaciones de valores [[bignumber]] que recortan los bytes nulos 0x00 iniciales o que agregan bytes nulos 0x00 al final para indicar el signo. El código ha de manejar bien estos casos o, de lo contrario, se generarían direcciones aparentemente válidas pero cuyos saldos nunca podrían ser gastados, con lo que se perderían sus fondos para siempre.
 
* El 0 se usa como byte de versión/aplicación.
 
* El 0 se usa como byte de versión/aplicación.
  
Las direcciones Bitcoin multifirma que utilizan un byte de versión/aplicación 0x05 cominezan siempre con la cifra '3'.
+
Las nuevas direcciones Bitcoin multifirma que utilizan un byte de versión/aplicación 0x05 cominezan siempre con la cifra '3'.
  
 
==Cómo codificar una clave privada==
 
==Cómo codificar una clave privada==
Línea 53: Línea 55:
 
==Tabla de símbolos Base58==
 
==Tabla de símbolos Base58==
  
La tabla de símbolos Base58 utilizada por Bitcoin es específica del proyecto Bitcoin y no pretende ser igual a la de otras implementaciones de Base58 utilizadas fuera del contexto de Bitcoin.
+
La tabla de símbolos Base58 utilizada por Bitcoin es específica del proyecto Bitcoin y no tiene por qué ser igual a la de otras implementaciones de Base58 utilizadas fuera del contexto de Bitcoin.
 
{| class="wikitable"  
 
{| class="wikitable"  
 
|-
 
|-
Línea 256: Línea 258:
 
|}
 
|}
  
En [[Lista de prefijos de direcciones]] se muestra una lista más completa.
+
En [[Lista de prefijos de direcciones]] se muestra una lista más exhaustiva.
  
 
== Fuente ==
 
== Fuente ==
Línea 262: Línea 264:
  
 
== Funciones relacionadas en el código fuente ==
 
== Funciones relacionadas en el código fuente ==
 +
 
* inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
 
* inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
 
* inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
 
* inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
 
* inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
 
* inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
  
[[Categoría:Téchnica]]
+
[[Categoría:Técnica]]
  
 
[[en:Base58Check encoding]]
 
[[en:Base58Check encoding]]

Revisión del 15:59 12 dic 2012

Las direcciones Bitcoin se codifican mediante una forma modificada de la codificación Base 58 a la que se conoce como Base58Check.

De manera general, la codificación Base58Check se utiliza para codificar secuencias de bytes utilizadas en Bitcoin convirtiéndolas en un formato de texto legible para el ser humano. Una dirección Bitcoin es simplemente una cadena de texto codificada como Base58Check que contiene unos datos útiles de 20 bytes de longitud, que consisten en el hash de la clave pública asociada con la dirección.

En el código fuente del cliente original de Bitcoin, Satoshi Nakamoto comentó la justificación del uso de Base58Check:

base58.h:

// Why base-58 instead of standard base-64 encoding?
// - Don't want 0OIl characters that look the same in some fonts and
//      could be used to create visually identical looking account numbers.
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
// - E-mail usually won't line-break if there's no punctuation to break at.
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.

Traducción: ¿Por qué codificación base-58 en lugar del estándar base-64? - No queremos los caracteres 0OIl que parecen iguales en algunas fuentes y que podrían utilizarse para crear números de cuenta visualmente idénticos. - Una cadena de texto con caracteres no alfanuméricos no tendría tan fácil aceptación como un número de cuenta. - El correo electrónico no introducirá saltos de línea si no hay signos de puntuación por los que que cortar. - El doble clic seleccionará el número completo como una sola palabra si todo es alfanumérico.

Caracterísitcas de Base58Check

Base58Check presenta las siguientes características:

  • Datos útiles de tamaño arbitrario.
  • Un conjunto de 58 símbolos alfanuméricos que incluyen letras minúsculas y mayúsculas fácilmente distinguibles (no se utilizan 0OIl).
  • Un byte de información de versión/aplicación. Las direcciones Bitcoin tradicionales utilizan 0x00 para este byte. Las nuevas direcciones que permiten multifirma utilizan 0x05.
  • Cuatro bytes (32 bits) de un código de comprobación de errores basado en SHA-256. Este código puede emplearse para detectar automáticamente e incluso corregir errores tipográficos.
  • Un paso adicional para preservar los ceros iniciales de los datos.

Cómo crear una cadena Base58Check

Una cadena de texto Base58Check se crea a partir de un byte de versión/aplicación de la manera siguiente:

  1. Tomar el byte de versión/aplicación y los bytes de los datos útiles y concatenarlos (como bytes).
  2. Calcular SHA256(SHA256(resultado paso 1)), aplicación reiterada por dos veces del algoritmo de hash SHA-256, y quedarse con los cuatro primeros bytes.
  3. Concatenar los resultados del paso 1 y el paso 2 (como bytes).
  4. Considerar la secuencia de bytes resultado del paso 3 como un bignumber único en formato big-endian y convertirlo a base-58 utilizando transformaciones matemáticas normales(división de bignumbers) y el alfabeto de base-58 descrito más abajo. Normalizar el resultado para que no tenga ceros de base-58 (el carácter '1') iniciales.
  5. El carácter inicial '1', que corresponde al valor cero en base58, se reserva para representar un byte cero inicial, al principio de los datos, y no tiene valor como símbolo base-58. Puede haber uno o más caracteres '1' iniciales para representar uno o más ceros iniciales. Contar el número de bytes cero iniciales que han aparecido en el resultado del paso 3 (para las direcciones Bitcoin antiguas siempre habrá al menos uno para el byte de versión/aplicación; para las direcciones del formato multifirma más nuevo no habrá ninguno). Cada byte cero inicial estará representado por un '1' en el resultado final.
  6. Concatenar los caracteres '1' del paso 5 con los resultados del paso 4. Se obtiene así el resultado Base58Check.

Cómo codificar una dirección Bitcoin

Una dirección Bitcoin está basada en un par de claves criptográficas ECDSA con parámetro de curva elíptica secp256k1.

las direcciones Bitcoin son el resultado de aplicar la codificación Base58Check al valor hash del script asociado. En concreto, es Base58Check(5,RIPEMD160(SHA256(script))), con las siguientes restricciones:

  • RIPEMD160 y SHA256 en este caso son siempre exactamente 20 y 32 bytes sin signo respectivamente. Están en formato big-endian (el byte más significativo en primer lugar). Han de evitarse implementaciones de valores bignumber que recortan los bytes nulos 0x00 iniciales o que agregan bytes nulos 0x00 al final para indicar el signo. El código ha de manejar bien estos casos o, de lo contrario, se generarían direcciones aparentemente válidas pero cuyos saldos nunca podrían ser gastados, con lo que se perderían sus fondos para siempre.
  • El 0 se usa como byte de versión/aplicación.

Las nuevas direcciones Bitcoin multifirma que utilizan un byte de versión/aplicación 0x05 cominezan siempre con la cifra '3'.

Cómo codificar una clave privada

La codificación Base58Check se utiliza también para codificar claves privadas en el formato de importación de monedero. Este se forma exactamente igual que una dirección Bitcoin, excepto en que se utiliza 0x80 como byte de versión/aplicación y los datos útiles constan de 32 bytes en lugar de 20 (una clave privada en Bitcoin es un único entero de 32 bytes en formato big-endian). Este tipo de codificación da lugar siempre a una cadena de 51 caracteres que comienza por '5', o más concretamente '5H', '5J', o '5K'.

Tabla de símbolos Base58

La tabla de símbolos Base58 utilizada por Bitcoin es específica del proyecto Bitcoin y no tiene por qué ser igual a la de otras implementaciones de Base58 utilizadas fuera del contexto de Bitcoin.

Valor Carácter Valor Carácter Valor Carácter Valor Carácter
0 1 1 2 2 3 3 4
4 5 5 6 6 7 7 8
8 9 9 A 10 B 11 C
12 D 13 E 14 F 15 G
16 H 17 J 18 K 19 L
20 M 21 N 22 P 23 Q
24 R 25 S 26 T 27 U
28 V 29 W 30 X 31 Y
32 Z 33 a 34 b 35 c
36 d 37 e 38 f 39 g
40 h 41 i 42 j 43 k
44 m 45 n 46 o 47 p
48 q 49 r 50 s 51 t
52 u 53 v 54 w 55 x
56 y 57 z

El algoritmo para codificar address_byte_string (consistente en 0x01 + hash + 4-byte_check_code) es:

   code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
   x = convert_bytes_to_big_integer(hash_result)
   
   output_string = ""
   
   while(x > 0) 
       {
           (x, remainder) = divide(x, 58)
           output_string.append(code_string[remainder])
       }
   
   repeat(number_of_leading_zero_bytes_in_hash)
       {
       output_string.append(code_string[0]);
       }
   
   output_string.reverse();

Bytes de versión

En la tabla siguiente se indican algunos valores de bytes utilizados para diferenciar versiones:

Versión decimal Símbolo inicial Uso
0 1 Hash de la clave pública Bitcoin
5 3 Hash del script Bitcoin
21 4 Clave pública (compacta) Bitcoin (propuesta)
52 M o N Hash de la clave pública Namecoin
128 5 Clave privada
111 m o n Hash de la clave pública Bitcoin en testnet
196 2 Hash del script Bitcoin en testnet

En Lista de prefijos de direcciones se muestra una lista más exhaustiva.

Fuente

https://github.com/bitcoin/bitcoin/blob/master/src/base58.h

Funciones relacionadas en el código fuente

  • inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
  • inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
  • inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)