Modify b58tobin to return canonical size

This commit is contained in:
Luke Dashjr
2014-08-18 15:49:47 +00:00
parent 1e56deac4c
commit 2880b80cbd
9 changed files with 58 additions and 11 deletions

View File

@@ -27,6 +27,9 @@ TESTS = \
tests/decode-b58c.sh \
tests/decode-b58c-fail.sh \
tests/decode-b58c-null.sh \
tests/decode-b58c-toolong.sh \
tests/decode-b58c-tooshort.sh \
tests/decode-zero.sh \
tests/encode.sh \
tests/encode-b58c.sh \
tests/encode-fail.sh

9
README
View File

@@ -13,9 +13,12 @@ This is only required if base58check is used. Raw base58 does not need SHA256.
Decoding Base58
---------------
Simply allocate a buffer to store the binary data in, and call the b58tobin
function:
bool b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz)
Simply allocate a buffer to store the binary data in, and set a variable with
the buffer size, and call the b58tobin function:
bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz)
The "canonical" base58 byte length will be assigned to binsz on success, which
may be larger than the actual buffer if the input has many leading zeros.
Regardless of the canonical byte length, the full binary buffer will be used.
If b58sz is zero, it will be initialised with strlen(b58); note that a true
zero-length base58 string is not supported here.

View File

@@ -29,8 +29,9 @@ static const int8_t b58digits_map[] = {
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
bool b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz)
bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
{
size_t binsz = *binszp;
const unsigned char *b58u = (void*)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + 3) / 4;
@@ -40,13 +41,18 @@ bool b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz)
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = ~((1 << ((bytesleft) * 8)) - 1);
unsigned zerocount = 0;
if (!b58sz)
b58sz = strlen(b58);
memset(outi, 0, outisz * sizeof(*outi));
for (i = 0; i < b58sz; ++i)
// Leading zeros, just count
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i)
++zerocount;
for ( ; i < b58sz; ++i)
{
if (b58u[i] & 0x80)
// High-bit set on invalid digit
@@ -87,6 +93,17 @@ bool b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz)
*((uint32_t*)binu) = htonl(outi[j]);
binu += sizeof(uint32_t);
}
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{
if (binu[i])
break;
--*binszp;
}
*binszp += zerocount;
return true;
}

View File

@@ -10,7 +10,7 @@ extern "C" {
extern bool (*b58_sha256_impl)(void *, const void *, size_t);
extern bool b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz);
extern bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz);
extern int b58check(const void *bin, size_t binsz, const char *b58, size_t b58sz);
extern bool b58enc(char *b58, size_t *b58sz, const void *bin, size_t binsz);

View File

@@ -71,16 +71,33 @@ int main(int argc, char **argv)
if (decode)
{
uint8_t bin[decode];
if (!b58tobin(bin, decode, r, rt))
size_t ssz = decode;
if (!b58tobin(bin, &ssz, r, rt))
return 2;
if (b58c)
{
int chk = b58check(bin, decode, r, rt);
if (chk < 0)
return chk;
if (fwrite(bin, decode, 1, stdout) != 1)
return 3;
}
else
{
// Raw base58 doesn't check length match
uint8_t cbin[ssz];
if (ssz > decode)
{
size_t zeros = ssz - decode;
memset(cbin, 0, zeros);
memcpy(&cbin[zeros], bin, decode);
}
else
memcpy(cbin, &bin[decode - ssz], ssz);
if (fwrite(cbin, ssz, 1, stdout) != 1)
return 3;
}
if (fwrite(bin, decode, 1, stdout) != 1)
return 3;
}
else
{

View File

@@ -0,0 +1,2 @@
#!/bin/sh
! base58 -d 25 -c 1119DXstMaV43WpYg4ceREiiTv2UntmoiA9a >/dev/null

View File

@@ -0,0 +1,2 @@
#!/bin/sh
! base58 -d 25 -c 111111111111111111114oLvT2 >/dev/null

3
tests/decode-zero.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
hex=$(base58 -d 25 111111 | xxd -p)
test x$hex = x000000000000

View File

@@ -1,3 +1,3 @@
#!/bin/sh
hex=$(base58 -d 25 19DXstMaV43WpYg4ceREiiTv2UntmoiA9j | xxd -p)
test x$hex != x005a1fc5dd9e6f03819fca94a2d89669469667f9a1
hex=$(base58 -d 50 19DXstMaV43WpYg4ceREiiTv2UntmoiA9j | xxd -p)
test x$hex = x005a1fc5dd9e6f03819fca94a2d89669469667f9a074655946