user20967: I'm working on a Bitcoin ATM. We want to detect addresses that are entered incorrectly.
There's a checksum on Bitcoin addresses - but how can we check it?

user2306: Rosetta Code has several example implementations in multiple languages.
Python 2 & 3
import codecs
from hashlib import sha256

digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def to_bytes(n, length):
    s = '%x' % n
    s = s.rjust(length*2, '0')
    s = codecs.decode(s.encode("UTF-8"), 'hex_codec')
    return s

def decode_base58(bc, length):
    n = 0
    for char in bc:
        n = n * 58 + digits58.index(char)
    return to_bytes(n, length)

def check_bc(bc):
    bcbytes = decode_base58(bc, 25)

    if bcbytes[0] not in [0x00, 0x05]:
        return False

    return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]
    
if __name__ == '__main__':
    print(check_bc('1111111111111111111114oLvT2'))


user9382: The way Bitcoin checks a public address is using what is called Base58Check. While the Bitcoin Wiki covers Base58Check, I'll outline how it works in both abstract and technical terms.

The whole idea of Base58Check is to prevent invalid addresses. This is done by adding digits to the start (00) and end of the Base58 value (4 bytes of double SHA256 hash). 

Add 00 to the start of Base58 value ie 00 + BASE58 ==> 00BASE58
Checksum = 1st 8 digits from SHA256(SHA256(00BASE58))

BASE58Check = (00)(BASE58_SHA256RIPEMD160_HEXADECIMAL_VALUE)(CHECKSUM) (parenthesis for visualisation only, all other data is correct in size, ie CHECKSUM = 8 chars)
The best way to visualize all this is with The Piachu's App

20967: <p>I'm working on a Bitcoin ATM. We want to detect addresses that are entered incorrectly.</p>

<p>There's a checksum on Bitcoin addresses - but how can we check it?</p>
 2306: <p><a href="http://rosettacode.org/wiki/Bitcoin/address_validation" rel="nofollow noreferrer">Rosetta Code</a> has several example implementations in multiple languages.</p>
<h3>Python 2 &amp; 3</h3>
<pre><code>import codecs
from hashlib import sha256

digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def to_bytes(n, length):
    s = '%x' % n
    s = s.rjust(length*2, '0')
    s = codecs.decode(s.encode(&quot;UTF-8&quot;), 'hex_codec')
    return s

def decode_base58(bc, length):
    n = 0
    for char in bc:
        n = n * 58 + digits58.index(char)
    return to_bytes(n, length)

def check_bc(bc):
    bcbytes = decode_base58(bc, 25)

    if bcbytes[0] not in [0x00, 0x05]:
        return False

    return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]
    
if __name__ == '__main__':
    print(check_bc('1111111111111111111114oLvT2'))
</code></pre>
 9382: <p>The way Bitcoin checks a public address is using what is called <strong>Base58Check</strong>. While the <a href="https://en.bitcoin.it/wiki/Base58Check_encoding#Creating_a_Base58Check_string" rel="noreferrer">Bitcoin Wiki covers Base58Check</a>, I'll outline how it works in both abstract and technical terms.</p>

<p><img src="https://i.stack.imgur.com/lhWd6.png" alt="Diagram of Base58Check"></p>

<p>The whole idea of Base58Check is to prevent invalid addresses. This is done by adding digits to the start (00) and end of the Base58 value (4 bytes of double SHA256 hash). </p>

<ol>
<li>Add <code>00</code> to the start of Base58 value ie <code>00</code> + <code>BASE58</code> ==> <code>00BASE58</code></li>
<li>Checksum = 1st 8 digits from <code>SHA256(SHA256(00BASE58))</code></li>
</ol>

<p><code>BASE58Check = (00)(BASE58_SHA256RIPEMD160_HEXADECIMAL_VALUE)(CHECKSUM)</code> (parenthesis for visualisation only, all other data is correct in size, ie CHECKSUM = 8 chars)</p>

<p>The best way to visualize all this is with <a href="https://gobittest.appspot.com/Address" rel="noreferrer">The Piachu's App</a></p>
