diff --git a/core/src/main/java/org/bitcoinj/core/Base58.java b/core/src/main/java/org/bitcoinj/core/Base58.java index dc07b023..e8052a4f 100644 --- a/core/src/main/java/org/bitcoinj/core/Base58.java +++ b/core/src/main/java/org/bitcoinj/core/Base58.java @@ -1,5 +1,6 @@ /* * Copyright 2011 Google Inc. + * Copyright 2018 Andreas Schildbach * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,6 +91,27 @@ public class Base58 { return new String(encoded, outputStart, encoded.length - outputStart); } + /** + * Encodes the given version and bytes as a base58 string. A checksum is appended. + * + * @param version the version to encode + * @param payload the bytes to encode, e.g. pubkey hash + * @return the base58-encoded string + */ + public static String encodeChecked(int version, byte[] payload) { + if (version < 0 || version > 255) + throw new IllegalArgumentException("Version not in range."); + + // A stringified buffer is: + // 1 byte version + data bytes + 4 bytes check code (a truncated hash) + byte[] addressBytes = new byte[1 + payload.length + 4]; + addressBytes[0] = (byte) version; + System.arraycopy(payload, 0, addressBytes, 1, payload.length); + byte[] checksum = Sha256Hash.hashTwice(addressBytes, 0, payload.length + 1); + System.arraycopy(checksum, 0, addressBytes, payload.length + 1, 4); + return Base58.encode(addressBytes); + } + /** * Decodes the given base58 string into the original data bytes. * @@ -180,5 +202,4 @@ public class Base58 { } return (byte) remainder; } - } diff --git a/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java b/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java index 38141490..cbc325b9 100644 --- a/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java +++ b/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java @@ -56,14 +56,7 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa * object, including version and checksum bytes. */ public final String toBase58() { - // A stringified buffer is: - // 1 byte version + data bytes + 4 bytes check code (a truncated hash) - byte[] addressBytes = new byte[1 + bytes.length + 4]; - addressBytes[0] = (byte) version; - System.arraycopy(bytes, 0, addressBytes, 1, bytes.length); - byte[] checksum = Sha256Hash.hashTwice(addressBytes, 0, bytes.length + 1); - System.arraycopy(checksum, 0, addressBytes, bytes.length + 1, 4); - return Base58.encode(addressBytes); + return Base58.encodeChecked(version, bytes); } @Override diff --git a/core/src/test/java/org/bitcoinj/core/Base58Test.java b/core/src/test/java/org/bitcoinj/core/Base58Test.java index 4004abe4..037f7115 100644 --- a/core/src/test/java/org/bitcoinj/core/Base58Test.java +++ b/core/src/test/java/org/bitcoinj/core/Base58Test.java @@ -44,6 +44,18 @@ public class Base58Test { assertEquals("", Base58.encode(new byte[0])); } + @Test + public void testEncodeChecked_address() throws Exception { + String encoded = Base58.encodeChecked(111, new byte[Address.LENGTH]); + assertEquals("mfWxJ45yp2SFn7UciZyNpvDKrzbhyfKrY8", encoded); + } + + @Test + public void testEncodeChecked_privateKey() throws Exception { + String encoded = Base58.encodeChecked(128, new byte[32]); + assertEquals("5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU", encoded); + } + @Test public void testDecode() throws Exception { byte[] testbytes = "Hello World".getBytes();