BTC不同格式私钥的相互转换

BTC不同格式私钥的相互转换

前言:众所周知,比特币常见到的私钥格式有三种,分别是16进制格式的,WIF格式,以及WIF压缩格式。它们的本质是一样的,但是它们之间应该如何进行转换呢?请看正文~

这里以 精通BTC一书中的例子做转换介绍,原始数据如下:

//16进制私钥
1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
//WIF压缩格式私钥
KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
//WIF格式私钥
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn

一 16进制格式的私钥转换成WIF格式

  1. 在16进制私钥前面加上0x80版本号,如下:

    801e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
    
  2. 对第1步结果进行SHA256哈希计算,如下:

    f7d98762db7267f6f9283156058333dce856036ae0a0b4741046d25058747739
    
  3. 将第2步结果进行SHA256哈希计算,如下:

    c47e83ffafda3ba4396e1bc6a648515e5fc9aa95910af6a4429537b87fb7b474
    
  4. 取第3步结果的前4字节(c47e83ff),加到第1步结果的末尾,如下:

    801e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aeddc47e83ff
    
  5. 对第4步结果进行Base58编码,就是最后得到的WIF格式私钥了,如下:

    5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
    

java代码转换实现如下:

package com.example.blockchain.test;

import org.bitcoinj.core.Base58;
import org.bouncycastle.util.encoders.Hex;
import party.loveit.bip44forjava.core.Sha256Hash;

public class Test {

    public static void main(String[] args) {
        //16进制私钥:1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
        //WIF压缩格式私钥:KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
        //WIF非压缩格式私钥:5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn

        //1.在16进制私钥前面加上0x80版本号
        String hex = "801e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd";
        //2.对第1步结果进行SHA256哈希计算
        byte[] hash1 = Sha256Hash.hash(Hex.decode(hex));
        //3.将第2步结果进行SHA256哈希计算
        byte[] hash2 = Sha256Hash.hash(hash1);
        //4.取第3步结果的前4字节(c47e83ff),加到第1步结果的末尾
        String result = hex + Hex.toHexString(hash2).substring(0, 8);
        //5.对第4步结果进行Base58编码
        System.out.println(Base58.encode(Hex.decode(result)));
    }

}

说明:可能会有人疑惑,为什么生成的私钥是 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn 而不是 KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ 呢?那么,又该如何生成 K 开头的私钥呢,其实很简单 -> 只需在原始16进制格式私钥的后面加上01即可,加上01表示该私钥是压缩格式的。特别说明:

  • 原始格式 32 字节,256位的0或者1
  • hex格式,hex格式又分为压缩和非压缩,压缩和非压缩的区别在于 -> 压缩格式 = 非压缩格式 + 01 ,所以说压缩格式并不是真的压缩了,反而多了一个后缀01
  • WIF(wallet-import-format)格式,5开头
  • WIF-compressed(WIF压缩格式),K 或者 L 开头

二 WIF格式私钥转换成16进制格式私钥

假如你耐心看完了上面的转换,相信反过来也明白了,我就简单说明一下吧:

  1. Base58解码;
  2. 将解码结果去掉80版本号,以及去掉最后面的4字节校验位。

OK,搞定!

你可能感兴趣的:(随笔,笔记)