比特币--通过公钥生成地址全过程
Posted justin_jia_92
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比特币--通过公钥生成地址全过程相关的知识,希望对你有一定的参考价值。
import org.ethereum.util.ByteUtil;
public class AddressUtil
public static String generateAddressFromHexPub(String hexPubKeyStr, String version)
//公钥sha256得到a
String a = SHAEncrypt.SHA256WithHex(hexPubKeyStr);
//a进行ripemd160计算后转hexString得到b
String b = ByteUtil.toHexString(Ripemd160.getHashWithHex(a));
//两次sha256, sha256(sha256(version + b))得到c
String c = SHAEncrypt.SHA256WithHex(SHAEncrypt.SHA256WithHex(version + b));
//(version + b + c的前4个字节,十六进制前八位) 得到十六进制字符串d
String d = version + b + c.substring(0, 8);
//对d进行base58编码得到地址
String address = Base58.encode(ByteUtil.hexStringToBytes(d));
return address;
public static void main(String[] args)
String version = "00";
String hexPubKeyStr = "026d9a6baec4d380091b9881400dbd99ca90bae0f61e171df121dd2ff0e2ac9517";
System.out.println(generateAddressFromHexPub(hexPubKeyStr, version));
//1Po8pvaAHE3V9twnSGXZwEXEkwctcCtWDe
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.ethereum.util.ByteUtil;
public class SHAEncrypt
public static String SHA256(final String strText)
return SHA(strText.getBytes(), "SHA-256");
public static String SHA256WithHex(final String hexStr)
return SHA(ByteUtil.hexStringToBytes(hexStr), "SHA-256");
public static String SHA512(final String strText)
return SHA(strText.getBytes(), "SHA-512");
public static String SHA512WithHex(final String hexStr)
return SHA(ByteUtil.hexStringToBytes(hexStr), "SHA-512");
private static String SHA(final byte[] text, final String strType)
String strResult = null;
if (text != null && text.length > 0)
try
MessageDigest messageDigest = MessageDigest.getInstance(strType);
messageDigest.update(text);
byte byteBuffer[] = messageDigest.digest();
StringBuffer strHexString = new StringBuffer();
for (int i = 0; i < byteBuffer.length; i++)
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1)
strHexString.append('0');
strHexString.append(hex);
strResult = strHexString.toString();
catch (NoSuchAlgorithmException e)
e.printStackTrace();
return strResult;
import static java.lang.Integer.rotateLeft;
import java.util.Arrays;
import java.util.Objects;
import org.ethereum.util.ByteUtil;
public final class Ripemd160
private static final int BLOCK_LEN = 64; // In bytes
public static byte[] getHashWithHex(String hexMsg)
return getHash(ByteUtil.hexStringToBytes(hexMsg));
public static byte[] getHash(byte[] msg)
Objects.requireNonNull(msg);
int[] state = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0;
int off = msg.length / BLOCK_LEN * BLOCK_LEN;
compress(state, msg, off);
byte[] block = new byte[BLOCK_LEN];
System.arraycopy(msg, off, block, 0, msg.length - off);
off = msg.length % block.length;
block[off] = (byte)0x80;
off++;
if (off + 8 > block.length)
compress(state, block, block.length);
Arrays.fill(block, (byte)0);
long len = (long)msg.length << 3;
for (int i = 0; i < 8; i++)
block[block.length - 8 + i] = (byte)(len >>> (i * 8));
compress(state, block, block.length);
byte[] result = new byte[state.length * 4];
for (int i = 0; i < result.length; i++)
result[i] = (byte)(state[i / 4] >>> (i % 4 * 8));
return result;
private static void compress(int[] state, byte[] blocks, int len)
if (len % BLOCK_LEN != 0)
throw new IllegalArgumentException();
for (int i = 0; i < len; i += BLOCK_LEN)
int[] schedule = new int[16];
for (int j = 0; j < BLOCK_LEN; j++)
schedule[j / 4] |= (blocks[i + j] & 0xFF) << (j % 4 * 8);
int al = state[0], ar = state[0];
int bl = state[1], br = state[1];
int cl = state[2], cr = state[2];
int dl = state[3], dr = state[3];
int el = state[4], er = state[4];
for (int j = 0; j < 80; j++)
int temp;
temp = rotateLeft(al + f(j, bl, cl, dl) + schedule[RL[j]] + KL[j / 16], SL[j]) + el;
al = el;
el = dl;
dl = rotateLeft(cl, 10);
cl = bl;
bl = temp;
temp = rotateLeft(ar + f(79 - j, br, cr, dr) + schedule[RR[j]] + KR[j / 16], SR[j]) + er;
ar = er;
er = dr;
dr = rotateLeft(cr, 10);
cr = br;
br = temp;
int temp = state[1] + cl + dr;
state[1] = state[2] + dl + er;
state[2] = state[3] + el + ar;
state[3] = state[4] + al + br;
state[4] = state[0] + bl + cr;
state[0] = temp;
private static int f(int i, int x, int y, int z)
assert 0 <= i && i < 80;
if (i < 16) return x ^ y ^ z;
if (i < 32) return (x & y) | (~x & z);
if (i < 48) return (x | ~y) ^ z;
if (i < 64) return (x & z) | (y & ~z);
return x ^ (y | ~z);
private static final int[] KL = 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E; // Round constants for left line
private static final int[] KR = 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000; // Round constants for right line
private static final int[] RL = // Message schedule for left line
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13;
private static final int[] RR = // Message schedule for right line
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11;
private static final int[] SL = // Left-rotation for left line
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6;
private static final int[] SR = // Left-rotation for right line
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11;
private Ripemd160() // Not instantiable
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;
以上是关于比特币--通过公钥生成地址全过程的主要内容,如果未能解决你的问题,请参考以下文章