Library for Base58Check encoding and decoding
This simple C library has two primary functions, base58check_encode
and base58check_decode
. Please refer to the auto-generated Doxygen documentation for usage details.
The library comes with a command-line utility for Base58Check encoding/decoding from stdin
to stdout
.
There are also overloaded C++ convenience functions if you are writing in C++.
Here's an example of generating a 256-bit private key and encoding it as Base58Check in Bitcoin's Wallet Import Format (WIF).
$ { printf '\x80' ; head -c32 /dev/urandom ; printf '\x01' ; } | base58check
KxmBZwPrX3u2dukBawC9u88BKAXuRRHmPwuLzLo8skAgBQoGnC6c
#include <base58check.h>
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <ranges>
int main() {
// fill a 32-byte key from std::random_device
using random_t = std::random_device::result_type;
std::array<random_t, 32 / sizeof(random_t)> key;
std::random_device random;
std::ranges::generate(key, std::reference_wrapper(random));
// wrap the key between a 0x80 type byte and a 0x01 flag byte
std::array<std::byte, 34> bytes;
bytes[0] = std::byte { 0x80 };
std::ranges::copy(as_bytes(std::span(key)), bytes.begin() + 1);
bytes[33] = std::byte { 0x01 };
// Base58Check encode the wrapped key and print it out
std::cout << base58check::encode(bytes) << std::endl;
return 0;
}
#include <base58check.h>
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <sysexits.h>
#include <sys/random.h>
int main() {
struct {
uint8_t type;
uint8_t key[32];
uint8_t flag;
} buf;
int ret = 0;
// fill a 32-byte key using getrandom()
if (getrandom(buf.key, sizeof buf.key, 0) < sizeof buf.key)
err(EX_OSERR, "getrandom");
// wrap the key between a 0x80 type byte and a 0x01 flag byte
buf.type = 0x80, buf.flag = 0x01;
// Base58Check encode the wrapped key
char *out = NULL;
size_t n_out = 1; // 1 excess char for null terminator
if (base58check_encode(&out, &n_out, (unsigned char *) &buf, sizeof buf, 0) < 0)
errx(EX_UNAVAILABLE, "base58check_encode failed");
out[n_out] = '\0';
// print it out
if (puts(out) < 0 || fflush(stdout) < 0)
err(EX_IOERR, "stdout");
// be tidy
base58check_free(out);
return EX_OK;
}
And here's an example of decoding a Base58Check encoding from standard input.
$ echo 1BitcoinEaterAddressDontSendf59kuE | base58check -d | hexdump -C
00000000 00 75 9d 66 77 09 1e 97 3b 9e 9d 99 f1 9c 68 fb |.u.fw...;.....h.|
00000010 f4 3e 3f 05 f9 |.>?..|
00000015
#include <base58check.h>
#include <iostream>
#include <sstream>
int main() {
// read all input from cin to EOF
std::ostringstream ss;
ss << std::cin.rdbuf();
// chop off any trailing newline character
auto str = std::move(ss).str();
if (str.ends_with('\n'))
str.pop_back();
// decode the Base58Check and output the raw bytes
auto bytes = base58check::decode(str);
std::cout.write(reinterpret_cast<const char *>(bytes.data()),
bytes.size()) << std::flush;
return 0;
}
#include <base58check.h>
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
int main() {
// read a line from stdin
char *in = NULL;
ssize_t n_in = 0;
if ((n_in = getline(&in, (size_t *) &n_in, stdin)) < 0 && ferror(stdin))
err(EX_IOERR, "stdin");
// chop off any trailing newline character
if (n_in && in[n_in - 1] == '\n')
in[--n_in] = '\0';
// decode the Base58Check
unsigned char *out = NULL;
size_t n_out = 0;
if (base58check_decode(&out, &n_out, in, n_in, 0) < 0)
errx(EX_DATAERR, "base58check_decode failed");
// output the raw bytes
if (fwrite(out, 1, n_out, stdout) < n_out || fflush(stdout) < 0)
err(EX_IOERR, "stdout");
// be tidy
base58check_free(out);
free(in);
return EX_OK;
}
-
Install the prerequisites — most/all of which you probably already have:
-
Then it's just your standard Autotools madness:
$ autoreconf -i $ ./configure $ make $ sudo make install