比特币--通过公钥生成地址全过程-java

<dependency>
    <groupId>org.bouncycastle</groupId>
	<artifactId>bcprov-jdk15on</artifactId>
	<version>1.60</version>
</dependency>
import java.security.MessageDigest;
import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

public class AddressUtil {
	static {
		Security.addProvider(new BouncyCastleProvider());
	}
	
	public static String generateAddress1FromHexPub(String hexPubKeyStr, String version) throws Exception {
		//公钥sha256得到byte数组a
		byte[] pubKey = ByteUtils.fromHexString(hexPubKeyStr);
		MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
		byte[] a = sha256.digest(pubKey);
		//a进行ripemd160计算后得到byte数组b
		MessageDigest ripeMD160 = MessageDigest.getInstance("RipeMD160");
		byte[] b = ripeMD160.digest(a);
		//两次sha256, sha256(sha256(version + b))得到byte数组c
		byte[] c = sha256.digest(sha256.digest(ByteUtils.fromHexString(version + ByteUtils.toHexString(b))));
		//(version + b + c的前4个字节,十六进制前八位) 得到十六进制字符串d
		String d = version + ByteUtils.toHexString(b) + ByteUtils.toHexString(c).substring(0, 8);
		//对d进行base58编码得到地址
		String address = Base58.encode(ByteUtils.fromHexString(d));
		return address;
	}
	public static String generateAddress3FromHexPub(String hexPubKeyStr, String version) throws Exception {
		//公钥sha256得到byte数组a
		byte[] pubKey = ByteUtils.fromHexString(hexPubKeyStr);
		MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
		byte[] a = sha256.digest(pubKey);
		//a进行ripemd160计算后得到byte数组b
		MessageDigest ripeMD160 = MessageDigest.getInstance("RipeMD160");
		byte[] b = ripeMD160.digest(a);
		//前缀0014 + b得到c
		String c = "0014" + ByteUtils.toHexString(b);
		//c重复第一二步操作得到byte数组d
		byte[] d = ripeMD160.digest(sha256.digest(ByteUtils.fromHexString(c)));
		//两次sha256, sha256(sha256(version + d))得到byte数组e
		byte[] e = sha256.digest(sha256.digest(ByteUtils.fromHexString(version + ByteUtils.toHexString(d))));
		//(version + d + e的前4个字节,十六进制前八位) 得到十六进制字符串f
		String f = version + ByteUtils.toHexString(d) + ByteUtils.toHexString(e).substring(0, 8);
		//对e进行base58编码得到地址
		String address = Base58.encode(ByteUtils.fromHexString(f));
		return address;
	}
	public static void main(String[] args) throws Exception {
		System.out.println(generateAddress1FromHexPub("026d9a6baec4d380091b9881400dbd99ca90bae0f61e171df121dd2ff0e2ac9517", "00"));
		//1Po8pvaAHE3V9twnSGXZwEXEkwctcCtWDe
		System.out.println(generateAddress3FromHexPub("02aba2d7173172af7c7f5303af835ad4541787e18fc742d8ea65e4a75f7f3d821c", "05"));
		//3LMMGrvh1YLsSTmAG6ebq4Yy4E6WhyQUah
	}
}
import java.math.BigInteger;
import java.util.Arrays;

public class Base58 {
	public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
	private static final char ENCODED_ZERO = ALPHABET[0];
	private static final int[] INDEXES = new int[128];
	static {
		Arrays.fill(INDEXES, -1);
		for (int i = 0; i < ALPHABET.length; i++) {
			INDEXES[ALPHABET[i]] = i;
		}
	}

	public static String encode(byte[] input) {
		if (input.length == 0) {
			return "";
		}
		int zeros = 0;
		while (zeros < input.length && input[zeros] == 0) {
			++zeros;
		}
		input = Arrays.copyOf(input, input.length); // since we modify it in-place
		char[] encoded = new char[input.length * 2]; // upper bound
		int outputStart = encoded.length;
		for (int inputStart = zeros; inputStart < input.length; ) {
			encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)];
			if (input[inputStart] == 0) {
				++inputStart; // optimization - skip leading zeros
			}
		}
		while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) {
			++outputStart;
		}
		while (--zeros >= 0) {
			encoded[--outputStart] = ENCODED_ZERO;
		}
		return new String(encoded, outputStart, encoded.length - outputStart);
	}

	public static byte[] decode(String input) {
		if (input.length() == 0) {
			return new byte[0];
		}
		byte[] input58 = new byte[input.length()];
		for (int i = 0; i < input.length(); ++i) {
			char c = input.charAt(i);
			int digit = c < 128 ? INDEXES[c] : -1;
			if (digit < 0) {
				throw new IllegalStateException("InvalidCharacter in base 58");
			}
			input58[i] = (byte) digit;
		}
		int zeros = 0;
		while (zeros < input58.length && input58[zeros] == 0) {
			++zeros;
		}
		byte[] decoded = new byte[input.length()];
		int outputStart = decoded.length;
		for (int inputStart = zeros; inputStart < input58.length; ) {
			decoded[--outputStart] = divmod(input58, inputStart, 58, 256);
			if (input58[inputStart] == 0) {
				++inputStart; // optimization - skip leading zeros
			}
		}
		while (outputStart < decoded.length && decoded[outputStart] == 0) {
			++outputStart;
		}
		return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length);
	}

	public static BigInteger decodeToBigInteger(String input) {
		return new BigInteger(1, decode(input));
	}

	private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {
		int remainder = 0;
		for (int i = firstDigit; i < number.length; i++) {
			int digit = (int) number[i] & 0xFF;
			int temp = remainder * base + digit;
			number[i] = (byte) (temp / divisor);
			remainder = temp % divisor;
		}
		return (byte) remainder;
	}
}

代码提供到这,有兴趣的小伙伴来一起学习,一起进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值