patterncMinor
Bitcoin address validator in C
Viewed 0 times
bitcoinaddressvalidator
Problem
Here is a Bitcoin address validator I am looking to have reviewed in C. Normally I would have the
```
/**
* @file bitcoin.c
* @brief Bitcoin address validation
*/
#include
#include
#include
typedef enum {VALID, BAD_CHAR, BAD_LENGTH, BAD_DIGEST} BitcoinAddressState;
/**
@fn BitcoinAddressState unbase58(const char s, unsigned char *out)
* @brief Takes a base58 encoded address and decodes it into the receiver. Errors are returned if the argument is not valid base58 or if the decoded value does not fit in the 25 byte address.
* @param addr The Bitcoin address
* @param out The receiver of the decoded address
* @return The state of decoding the Bitcoin address
*/
BitcoinAddressState unbase58(const char addr, unsigned char out)
{
/ A bitcoin address uses a base58 encoding, which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters 0, O, I and l. /
const char *tmpl = "123456789"
"ABCDEFGHJKLMNPQRSTUVWXYZ"
"abcdefghijkmnopqrstuvwxyz";
const char *p;
memset(out, 0, 25);
for (int i = 0; addr[i]; ++i)
{
if (!(p = strchr(tmpl, addr[i]))) return BAD_CHAR;
size_t c = p - tmpl;
for (int j = 25; --j; )
{
c += 58 * out[j];
out[j] = c % 256;
c /= 256;
}
if (c) return BAD_LENGTH;
}
return VALID;
}
/**
@fn BitcoinAddressState validateAddress(const char s)
* @brief Takes a Bitcoin address as argument, and checks whether or not the address is valid.
* @param addr The Bitcoin address
* @return The state of the Bitcoin address
*/
BitcoinAddressState validateAddress(const char *addr)
{
unsigned char dec[32];
unsigned char d1[SHA256_DIGEST_LENGTH];
unsigned char d2[SHA256_DIGEST_LENGTH];
enum and function prototypes declared in a header file, but I decided for the purpose of this question to integrate them into one for easy copying and compilation.```
/**
* @file bitcoin.c
* @brief Bitcoin address validation
*/
#include
#include
#include
typedef enum {VALID, BAD_CHAR, BAD_LENGTH, BAD_DIGEST} BitcoinAddressState;
/**
@fn BitcoinAddressState unbase58(const char s, unsigned char *out)
* @brief Takes a base58 encoded address and decodes it into the receiver. Errors are returned if the argument is not valid base58 or if the decoded value does not fit in the 25 byte address.
* @param addr The Bitcoin address
* @param out The receiver of the decoded address
* @return The state of decoding the Bitcoin address
*/
BitcoinAddressState unbase58(const char addr, unsigned char out)
{
/ A bitcoin address uses a base58 encoding, which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters 0, O, I and l. /
const char *tmpl = "123456789"
"ABCDEFGHJKLMNPQRSTUVWXYZ"
"abcdefghijkmnopqrstuvwxyz";
const char *p;
memset(out, 0, 25);
for (int i = 0; addr[i]; ++i)
{
if (!(p = strchr(tmpl, addr[i]))) return BAD_CHAR;
size_t c = p - tmpl;
for (int j = 25; --j; )
{
c += 58 * out[j];
out[j] = c % 256;
c /= 256;
}
if (c) return BAD_LENGTH;
}
return VALID;
}
/**
@fn BitcoinAddressState validateAddress(const char s)
* @brief Takes a Bitcoin address as argument, and checks whether or not the address is valid.
* @param addr The Bitcoin address
* @return The state of the Bitcoin address
*/
BitcoinAddressState validateAddress(const char *addr)
{
unsigned char dec[32];
unsigned char d1[SHA256_DIGEST_LENGTH];
unsigned char d2[SHA256_DIGEST_LENGTH];
Solution
-
It would be nice to include a link to an authoritative reference. Until then, no comment on the algorithm compliance is possible.
-
Instead of
-
In C,
It would be nice to include a link to an authoritative reference. Until then, no comment on the algorithm compliance is possible.
-
Instead of
switch I'd rather have a table of strings indexed by BitcoinAddressState values.-
In C,
main must return a value explicitly.Context
StackExchange Code Review Q#57974, answer score: 7
Revisions (0)
No revisions yet.