Refer to the Base58.h code of the bitcoin source code using a coded function implemented by the OpenSSL Bignum Library as a validation gadget:
Generated:
g++-O base58encode-g base58encode.cc-lcrypto
Source:
#include <stdio.h> #include <stdlib.h> #include <string> #include <openssl/bn.h> #define DOMAIN _check (c) (' 0 ' <= (c) && (c) <= ' 9 ' | | ' A ' <= (c) && (c) <= ' F ' | | ' A ' <= (c) && (c) <= ' F ') const char * base58table= "
123456789ABCDEFGHJKLMNPQRSTUVWXYZABCDEFGHIJKMNOPQRSTUVWXYZ ";
std::string base58encode (const std::string & hexstring) {std::string result = "";
Bn_ctx * Bnctx = Bn_ctx_new ();
Bn_ctx_init (BNCTX);
Bignum * bn = Bn_new ();
Bignum * bn0= bn_new ();
Bignum * Bn58=bn_new ();
Bignum * dv = bn_new ();
Bignum * rem= bn_new ();
Bn_init (BN);
Bn_init (BN0);
Bn_init (bn58);
Bn_init (DV);
Bn_init (REM);
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 (int argc, char * argv []) {std::string hexstring = "";
FILE * fin = stdin;
while (!feof (Fin)) {char c = fgetc (Fin);
if (Domain_check (c)) hexstring +=c;
} fprintf (stdout, "%s", Base58encode (hexstring). C_STR ());
return 0; }
Test:
Echo-n
00010966776006953d5567439e5e39f86a0d273beed61967f6
|./base58encode
Printed:6UWLL9RISC3QFPQBUVKOFHMBQ7WMTJVM
Because there are 2 leading 0 ahead, the address should be 16UWLL9RISC3QFPQBUVKOFHMBQ7WMTJVM
Reference address generation inside the code: Add the processing of the leading 0, generate the final Bitcoin address
BASE58 definition of leading version byte:
Decimal version |
Leading symbol |
| Use
Example |
0 |
1 |
Bitcoin PubKey Hash |
17vznx1sn5ntka8uqfxwqbfefc3iqryhem |
5 |
3 |
Bitcoin Script Hash |
3ektnhqd7riae6uzmj2zift9ygrrksgzqx |
111 |
M or N |
Bitcoin testnet PubKey Hash |
Mipcbbfg9gmich81kj8tqqdgozub1zjrfn |
128 |
5 |
Bitcoin Private key (for uncompressed PubKey) |
5hwgr3u458glafkbgxtsshspqjnyogrszgqspwlfhlnyskdpyya |
128 |
K or L |
Bitcoin Private key (for compressed pubkey) |
L1aw4aubdfb7yfras2s1mn3bqg9nwysy8nkolmjebsld5bwv3enz |
196 |
2 |
Testnet Script Hash |
2mzqwssnbhwhqsaqttvq6v47xtaisrja1vc |
239 |
9 |
Testnet Private key (for uncompressed PubKey) |
92pg46ruhgtt7romnv7igw6w1gbgdeezqdbjczshkcsynzyyncc |
239 |
C |
Testnet Private key (for compressed pubkey) |
Cnjfgo1drifnpcbdbx8brjrpxchbwxwxcvnh5soskdcf6jxxwhmm
|
The definition of a leading byte that differs from the public key address:
Compute the length of a pubkey with a given first byte.
unsigned int static getlen (unsigned char chheader) {
if (Chheader = = 2 | | chheader = 3)//compression method
return;
if (Chheader = = 4 | | chheader = = 6 | | chheader = = 7)//non-compression method
return;
return 0;
}
Discuss:
1) about the address leading 0, that is, the base58 1, this can be achieved, hexstring every 2 characters is a byte, followed by a byte array, to see the beginning of the 0 subscript, how many bytes are 0x00, the front of how many 1 put to the front, The version number of the general address is 0x00, so you'll almost see a bitcoin address that starts at 1.
Reference:
Https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses
Https://en.bitcoin.it/wiki/List_of_address_prefixes
Https://en.bitcoin.it/wiki/Base58Check_encoding