Here's a mock Java program I made that takes a public key in hex and prints it's bech32 address. Note that it doesn't do any error checking, or checks for well-formedness of user input.
/*
* THIS IS MOCK CODE, IT MAY NEED TWEAKS TO RUN
*/
import org.bouncycastle.crypto.digests.RIPEMD160Digest;
import org.bitcoinj.core.Bech32;
public class Bech32Address {
public static void main(String[] args) {
String humanReadablePart = "bc";
Scanner scanIn = new System.Scanner(System.in);
System.out.print("Input public key hex, wihout leading 0x: ");
String hexPubKey = scanIn.nextLine();
// convert public key from hex to bytes
byte[] bytesPubKey = new byte[hexPubKey.length() / 2];
for (int i = 0; i < bytesPubKey.length; i++) {
int index = i * 2;
int j = Integer.parseInt(hexPubKey.substring(index, index + 2), 16);
bytePubKey[i] = (byte) j;
}
// SHA256 hash the public key
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(bytePubKey);
// Hash with RIPEMD160
RIPEMD160Digest d = new RIPEMD160Digest();
d.update (bytePubKey, 0, bytePubKey.length);
byte[] hash160 = new byte[d.getDigestSize()];
d.doFinal (hash160, 0);
// Finally, encode in bech32
String address = Bech32.encode("bc", hash160);
System.out.print("Bech32 address: ");
System.out.println(address);
}
}
We essentially use the
encode() method of the
org.bitcoinj.core.Bech32 class and pass it the human readable part ("bc") and the bytes of the RIPEMD160 hash of your SHA256 hash. I also included the SHA256 hash generation for completeness.
It has dependencies on BouncyCastle for RIPEMD160 and BitcoinJ for Bech32.