Skip to content

Instantly share code, notes, and snippets.

@miracle2k
Last active June 27, 2020 19:15
Show Gist options
  • Save miracle2k/8141380 to your computer and use it in GitHub Desktop.
Save miracle2k/8141380 to your computer and use it in GitHub Desktop.
Validate a Ripple address in Python/JavaScript.
<!-- JavaScript is def. not batteries included. -->
<!-- From http://pastebin.com/B5r3P5Ny -->
<script src="http://crypto-js.googlecode.com/files/2.5.3-crypto-sha256.js"></script>
<script src="http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js"></script>
<script src="http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js"></script>
<!-- taken from bitcoinjs almost verbatim -->
<script>
BigInteger.valueOf = nbv;
BigInteger.prototype.toByteArrayUnsigned = function () {
var ba = this.toByteArray();
if (ba.length) {
if (ba[0] == 0)
ba = ba.slice(1);
return ba.map(function (v) {
return (v < 0) ? v + 256 : v;
});
} else
return ba;
};
var Ripple = {};
(function () {
var B58 = Ripple.Base58 = {
alphabet: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
base: BigInteger.valueOf(58),
decode: function (input, minLength) {
var bi = BigInteger.valueOf(0);
for (var i=0; i < input.length; i++) {
var alphaIndex = B58.alphabet.indexOf(input[i]);
if (alphaIndex < 0)
throw "Invalid character";
bi = bi.multiply(B58.base).add(BigInteger.valueOf(alphaIndex));
}
var bytes = bi.toByteArrayUnsigned();
while (bytes.length < minLength)
bytes.unshift(0);
return bytes;
}
};
})();
Ripple.Address = function (bytes) {
if ("string" == typeof bytes)
bytes = Ripple.Address.decodeString(bytes);
this.hash = bytes;
};
Ripple.Address.decodeString = function (string) {
var bytes = Ripple.Base58.decode(string, 25);
var hash = bytes.slice(0, 21);
var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
if (checksum[0] != bytes[21] ||
checksum[1] != bytes[22] ||
checksum[2] != bytes[23] ||
checksum[3] != bytes[24])
throw "Checksum validation failed!";
var version = hash.shift();
if (version != 0)
throw "Version " + version + " not supported!";
return hash;
};
function check_address(address) {
try {
Ripple.Address(address);
return true;
} catch (err) {
console.log(err);
return false;
}
}
</script>
def validate_ripple_address(str):
# https://ripple.com/wiki/Accounts#Validating_Addresses
# http://rosettacode.org/wiki/Bitcoin/address_validation#Python
# http://stackoverflow.com/a/16022710/15677
from hashlib import sha256
digits58 = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
def to_bytes(n, length, endianess='big'):
h = '%x' % n
s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex')
return s if endianess == 'big' else s[::-1]
def decode_base58(bc, length):
n = 0
for char in bc:
n = n * 58 + digits58.index(char)
return to_bytes(n, length, 'big')
def check_bc(bc):
try:
bcbytes = decode_base58(bc, 25)
except ValueError:
return False
return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]
return check_bc(str)
@alex-piccione
Copy link

I have this error running the validate_ripple_address from ripple.py

s = ('0'(len(h) % 2) + h).zfill(length2).decode('hex')
AttributeError: 'str' object has no attribute 'decode'

@OptimusOpus
Copy link

I have the same issue as @alex75it

@jmpworks
Copy link

jmpworks commented Dec 11, 2018

@alex75it @OptimusOpus
Changes below should fix it :)

import codecs
...

    def to_bytes(n, length, endianess='big'):
        h = '%x' % n
        s = codecs.decode(('0'*(len(h) % 2) + h).zfill(length*2), "hex_codec")
        return s if endianess == 'big' else s[::-1]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment