1. 程式人生 > >Openssl實現生成比特幣地址的base58編碼

Openssl實現生成比特幣地址的base58編碼

比特幣協議中比特幣地址的生成演算法如下:

比特幣地址(Bitcoin Address)是ECDSA公鑰(public key)的雜湊,它是這樣計算出來的:

Version = 1 個位元組 0 ; 在測試網路上, 這個值是 1 個位元組 111
Key hash = Version 與 RIPEMD-160(SHA-256(public key)) 相接
Checksum = SHA-256(SHA-256(Key hash))的前4個位元組
Bitcoin Address = Base58Encode(Key hash 與 Checksum 相接)

下面介紹使用openssl庫實現base58編碼:

#include <stdlib.h>
#include <iostream>
#include <string>
#include <openssl/bn.h>
#include "ecdsa_test.h"


using namespace std;

#define DOMAIN_CHECK(c) ('0'<=(c)&&(c)<='9'||'a'<=(c)&&(c)<='f'||'A'<=(c)&&(c)<='F')


#define BASE58TABLE "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
std::string base58encode(const std::string & hexstring) { std::string result = ""; BN_CTX * bnctx = BN_CTX_new(); BIGNUM * bn = BN_new(); BIGNUM * bn0= BN_new(); BIGNUM * bn58=BN_new(); BIGNUM * dv = BN_new(); BIGNUM * rem= BN_new(); BN_hex2bn(&bn, hexstring.c_str()); //printf("bn:%s\n", BN_bn2dec(bn));
BN_hex2bn(&bn58, "3a");//58 BN_hex2bn(&bn0,"0"); while(BN_cmp(bn, bn0)>0){ BN_div(dv, rem, bn, bn58, bnctx); BN_copy(bn, dv); //printf("dv: %s\n", BN_bn2dec(dv)); //printf("rem:%s\n", BN_bn2dec(rem)); char base58char = BASE58TABLE[BN_get_word(rem)]; result += base58char; } std::string::iterator pbegin = result.begin(); std::string::iterator pend = result.end(); while(pbegin < pend) { char c = *pbegin; *(pbegin++) = *(--pend); *pend = c; } return result; } int main() { std::string hex_string = "00010966776006953D5567439E5E39F86A0D273BEED61967F6"; cout << base58encode(hex_string).c_str() << endl; return 0; }