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

<p><a href="https://bitcointalk.org/index.php?topic=1026.0" rel="nofollow">https://bitcointalk.org/index.php?topic=1026.0</a></p>

<pre><code>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 &gt;= __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 &gt;= 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")
</code></pre>

CC BY-SA 3.0
2013-04-15T02:15:43.117Z
2013-04-15T02:33:29.323Z
2013-04-15T02:33:29.323Z
Nick ODell
<p>How I do it in php -</p>

<p>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 <strong>should start with 00</strong>)</p>

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

<p>Not code, sorry, but that's how you do it.</p>

CC BY-SA 3.0
2013-06-26T11:05:52.497Z
2013-06-26T11:05:52.497Z
Alice Wonder
<p>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?</p>

CC BY-SA 3.0
2013-04-15T08:56:23.477Z
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
CC BY-SA 3.0
2013-04-18T07:52:24.330Z
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
<development><address>
Is there a self contained C/C++ code snippet out there to validate a Bitcoin public address?
user299648
# Is there a self contained C/C++ code snippet out there to validate a Bitcoin public address?

(Asked by: username_0 on 2013-04-15)

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?

**Tags:** development, address

> **Comments:**
> **username_1**: 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.  
> **username_2**: You can't validate that a private key exists for a public key. Therefore, complete validation of an address shouldn't be possible.  

---

## 2 answers

### Answer by username_3 on 2013-04-15. Score: 1 | Accepted answer

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")

```


---

### Answer by username_4 on 2013-06-26. Score: 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.


---

