Is there a self contained C/C++ code snippet out there to validate a Bitcoin public address?

3

I tried looking through the Satoshi Client to grab the necessary code. It ended up being too difficult for me as my expertise is not in C or C variants. And the fact that the code use boost made it that much more difficult. Is their a code snippet out there that does not rely on any external libraries except for maybe the SHA256 hash function?

user299648

Posted 2013-04-15T01:59:04.270

Reputation: 401

And just to clarify, this isn't validating that an address is one generated by any bitcoin client just that it is an address that could be a valid Bitcoin address derived from a public key. There are Bitcoin addresses that pass this test for which there is no private key and/or no public key.Stephen Gornick 2013-04-15T08:56:23.477

You can't validate that a private key exists for a public key. Therefore, complete validation of an address shouldn't be possible.Charles Hoskinson 2013-04-18T07:52:24.330

Answers

1

This isn't precisely what you asked for, but it should be a good starting point.

https://bitcointalk.org/index.php?topic=1026.0

import re
import math
from Crypto.Hash import SHA256

def validate_bitcoin_address(self, value):
  value = value.strip()
  if re.match(r"[a-zA-Z1-9]{27,35}$", value) is None:
    raise ValueError("Contains illegal characters")
  version = get_bcaddress_version(value)
  if version != 0:
    raise ValueError("Not a standard bitcoin address")
  return value


__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)

def b58encode(v):
  """ encode v, which is a string of bytes, to base58.                                                                                                               
  """

  long_value = 0L
  for (i, c) in enumerate(v[::-1]):
    long_value += (256**i) * ord(c)

  result = ''
  while long_value >= __b58base:
    div, mod = divmod(long_value, __b58base)
    result = __b58chars[mod] + result
    long_value = div
  result = __b58chars[long_value] + result

  # Bitcoin does a little leading-zero-compression:                                                                                                                  
  # leading 0-bytes in the input become leading-1s                                                                                                                   
  nPad = 0
  for c in v:
    if c == '\0': nPad += 1
    else: break

  return (__b58chars[0]*nPad) + result

def b58decode(v, length):
  """ decode v into a string of len bytes                                                                                                                            
  """
  long_value = 0L
  for (i, c) in enumerate(v[::-1]):
    long_value += __b58chars.find(c) * (__b58base**i)

  result = ''
  while long_value >= 256:
    div, mod = divmod(long_value, 256)
    result = chr(mod) + result
    long_value = div
  result = chr(long_value) + result

  nPad = 0
  for c in v:
    if c == __b58chars[0]: nPad += 1
    else: break

  result = chr(0)*nPad + result
  if length is not None and len(result) != length:
    return None

  return result

def get_bcaddress_version(strAddress):
  """ Returns None if strAddress is invalid.  Otherwise returns integer version of address. """
  addr = b58decode(strAddress,25)
  if addr is None: return None
  version = addr[0]
  checksum = addr[-4:]
  vh160 = addr[:-4] # Version plus hash160 is what is checksummed                                                                                                    
  h3=SHA256.new(SHA256.new(vh160).digest()).digest()
  if h3[0:4] == checksum:
    return ord(version)
  else:
    raise ValueError("Bad checksum")

Nick ODell

Posted 2013-04-15T01:59:04.270

Reputation: 26 536

0

How I do it in php -

A) decode base58 to hex and pad with 0's on the left so it is 50 characterts long. B) The right most 8 characters is the checksum, the left most 42 are the extended ripemd160 (and should start with 00)

C) sha256(sha256(extended ripemd160)) - the first 8 characters of that should match the checksum from step B.

Not code, sorry, but that's how you do it.

Alice Wonder

Posted 2013-04-15T01:59:04.270

Reputation: 101