Binary-to-text encoding used by Bitcoin.

Base-58 is a special binary-to-text encoding used by the Bitcoin project. The encoding is alphanumeric and excludes punctuation and the character pairs (0, O) and (I, l) because in many fonts they are visually indistinguishable. These simple changes provide better usability than the more common base-64.

Encoding implementation

Base-58 can be nicely implemented on plan9 using its extended precision integer arithmetic library.

// base58.c

#include <u.h>
#include <libc.h>
#include <mp.h>
#include <String.h>

static char *Base58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

void
s_b58reverse(String *instr)
{
	char ch;
	char *beg, *end;

	beg = instr->base;
	end = instr->ptr - 1;
	while (end > beg) {
		ch = *beg;
		*beg = *end;
		*end = ch;
		beg++; end--;
	}
}

int
b58val(char ch)
{
	ulong i;
	for(i = 0; i < strlen(Base58chars); ++i) {
		if(Base58chars[i] == ch)
			return i;
	}
	return -1;
}

String*
b58enc(mpint *invalue)
{
	mpint *base, *rem, *v;
	String *result;

	base = uitomp(58, nil);
	rem = mpnew(0);
	v = mpcopy(invalue);
	result = s_new();
	while(mpcmp(v, mpzero) > 0) {
		mpdiv(v, base, v, rem);
		ulong chidx = mptoui(rem);
		s_nappend(result, &Base58chars[chidx], 1);
	}
	s_b58reverse(result);
	mpfree(base);
	mpfree(rem);
	mpfree(v);
	return result;
}

void
b58dec(char *instr, ulong instrlen, mpint *outvalue)
{
	mpint *base, *digit;
	ulong i;

	uitomp(0, outvalue);
	base = uitomp(58, nil);
	digit = mpnew(0);
	for(i = 0; i < instrlen; ++i) {
		mpmul(outvalue, base, outvalue);
		itomp(b58val(instr[i]), digit);
		mpadd(outvalue, digit, outvalue);
	}
	mpfree(base);
	mpfree(digit);
}

void
main(int argc, char* argv[])
{
	mp *tv, *dec;

	USED(argc, argv);

	tv = uitomp(0x626262, nil);
	result = b58enc(tv);
	print("base-58 encoded: %s\n", s_to_c(result));

	dec = mpnew(0);
	b58dec(s_to_c(result), s_len(result), dec);
	print("base-58 decoded: %08X\n", mptoui(dec));

	mpfree(dec);
	mpfree(tv);
	s_free(result);
	exits(0);
}

Last update on 7E4B19, edited 1 times. 1/1thh