数字钱包私钥与助记词的相互转化

参考:助记词(Mnemonics)生成种子,以及Public Key, Private key https://my.oschina.net/gavinzheng731/blog/1847838

【区块链 | ETH】Web3j创建钱包的2种方式的对比https://blog.csdn.net/qq_28505809/article/details/99857208

基本大意,根据BIP39,11位二进制数转化成一个单词,如果有不足的位数,使用私钥hash的结果来填充,于是助记词和私钥之间就可以相互转换了。

贴上代码

/**

* pk is 256 bits, the mn words will be 24

*/

@Override

public List<String> getWords(byte[] pk) throws Exception {

ArrayList<String> ret = new ArrayList<String>();

byte[] out = CreateCredentialsUtil.pk2mn("SHA-256", "", pk);

int n;

n = (out[0] & 0xff) << 3 | (out[1] & 0xff) >> 5;

ret.add(words.get(n));

n = (out[1] & 0x1f) << 6 | (out[2] & 0xff) >> 2;

ret.add(words.get(n));

n = (out[2] & 0x03) << 9 | (out[3] & 0xff) << 1 | (out[4] & 0xff) >> 7;

ret.add(words.get(n));

n = (out[4] & 0x7f) << 4 | (out[5] & 0xff) >> 4;

ret.add(words.get(n));

n = (out[5] & 0x0f) << 7 | (out[6] & 0xff) >> 1;

ret.add(words.get(n));

n = (out[6] & 0x01) << 10 | (out[7] & 0xff) << 2 | (out[8] & 0xff) >> 6;

ret.add(words.get(n));

n = (out[8] & 0x3f) << 5 | (out[9] & 0xff) >> 3;

ret.add(words.get(n));

n = (out[9] & 0x07) << 8 | (out[10] & 0xff) ;

ret.add(words.get(n));

// round 2

n = (out[11] & 0xff) << 3 | (out[12] & 0xff) >> 5;

ret.add(words.get(n));

n = (out[12] & 0x1f) << 6 | (out[13] & 0xff) >> 2;

ret.add(words.get(n));

n = (out[13] & 0x03) << 9 | (out[14] & 0xff) << 1 | (out[15] & 0xff) >> 7;

ret.add(words.get(n));

n = (out[15] & 0x7f) << 4 | (out[16] & 0xff) >> 4;

ret.add(words.get(n));

n = (out[16] & 0x0f) << 7 | (out[17] & 0xff) >> 1;

ret.add(words.get(n));

n = (out[17] & 0x01) << 10 | (out[18] & 0xff) << 2 | (out[19] & 0xff) >> 6;

ret.add(words.get(n));

n = (out[19] & 0x3f) << 5 | (out[20] & 0xff) >> 3;

ret.add(words.get(n));

n = (out[20] & 0x07) << 8 | (out[21] & 0xff) ;

ret.add(words.get(n));

// round 3

n = (out[22] & 0xff) << 3 | (out[23] & 0xff) >> 5;

ret.add(words.get(n));

n = (out[23] & 0x1f) << 6 | (out[24] & 0xff) >> 2;

ret.add(words.get(n));

n = (out[24] & 0x03) << 9 | (out[25] & 0xff) << 1 | (out[26] & 0xff) >> 7;

ret.add(words.get(n));

n = (out[26] & 0x7f) << 4 | (out[27] & 0xff) >> 4;

ret.add(words.get(n));

n = (out[27] & 0x0f) << 7 | (out[28] & 0xff) >> 1;

ret.add(words.get(n));

n = (out[28] & 0x01) << 10 | (out[29] & 0xff) << 2 | (out[30] & 0xff) >> 6;

ret.add(words.get(n));

n = (out[30] & 0x3f) << 5 | (out[31] & 0xff) >> 3;

ret.add(words.get(n));

n = (out[31] & 0x07) << 8 | (out[32] & 0xff) ;

ret.add(words.get(n));

return ret;

}

@Override

public byte[] getPk(List<String> input) {

byte[] ret = new byte[32];

int[] in = new int[24];

for (int i = 0; i < 24; ++i) {

in[i] = words.indexOf(input.get(i));

}

// round 1

ret[0] = (byte) ((in[0] & 0x7ff) >> 3);

ret[1] = (byte) ((in[0] & 0x07) << 5 | (in[1] & 0x7ff) >> 6);

ret[2] = (byte) ((in[1] & 0x3f) << 2 | (in[2] & 0x7ff) >> 9);

ret[3] = (byte) ((in[2] & 0x1ff) >> 1);

ret[4] = (byte) ((in[2] & 0x1) << 7 | (in[3] & 0x7ff) >> 4);

ret[5] = (byte) ((in[3] & 0xf) << 4 | (in[4] & 0x7ff) >> 7);

ret[6] = (byte) ((in[4] & 0x7f) << 1 | (in[5] & 0x7ff) >> 10);

ret[7] = (byte) ((in[5] & 0x3ff) >> 2);

ret[8] = (byte) ((in[5] & 0x3) << 6 | (in[6] & 0x7ff) >> 5);

ret[9] = (byte) ((in[6] & 0x1f) << 3 | (in[7] & 0x7ff) >> 8);

ret[10] = (byte) ((in[7] & 0xff));

// round 2

ret[11] = (byte) ((in[8] & 0x7ff) >> 3);

ret[12] = (byte) ((in[8] & 0x07) << 5 | (in[9] & 0x7ff) >> 6);

ret[13] = (byte) ((in[9] & 0x3f) << 2 | (in[10] & 0x7ff) >> 9);

ret[14] = (byte) ((in[10] & 0x1ff) >> 1);

ret[15] = (byte) ((in[10] & 0x1) << 7 | (in[11] & 0x7ff) >> 4);

ret[16] = (byte) ((in[11] & 0xf) << 4 | (in[12] & 0x7ff) >> 7);

ret[17] = (byte) ((in[12] & 0x7f) << 1 | (in[13] & 0x7ff) >> 10);

ret[18] = (byte) ((in[13] & 0x3ff) >> 2);

ret[19] = (byte) ((in[13] & 0x3) << 6 | (in[14] & 0x7ff) >> 5);

ret[20] = (byte) ((in[14] & 0x1f) << 3 | (in[15] & 0x7ff) >> 8);

ret[21] = (byte) ((in[15] & 0xff));

// round 3

ret[22] = (byte) ((in[16] & 0x7ff) >> 3);

ret[23] = (byte) ((in[16] & 0x07) << 5 | (in[17] & 0x7ff) >> 6);

ret[24] = (byte) ((in[17] & 0x3f) << 2 | (in[18] & 0x7ff) >> 9);

ret[25] = (byte) ((in[18] & 0x1ff) >> 1);

ret[26] = (byte) ((in[18] & 0x1) << 7 | (in[19] & 0x7ff) >> 4);

ret[27] = (byte) ((in[19] & 0xf) << 4 | (in[20] & 0x7ff) >> 7);

ret[28] = (byte) ((in[20] & 0x7f) << 1 | (in[21] & 0x7ff) >> 10);

ret[29] = (byte) ((in[21] & 0x3ff) >> 2);

ret[30] = (byte) ((in[21] & 0x3) << 6 | (in[22] & 0x7ff) >> 5);

ret[31] = (byte) ((in[22] & 0x1f) << 3 | (in[23] & 0x7ff) >> 8);

// ret[32] = (byte) ((in[23] & 0xff));

return ret;

}

单词文件,请到https://github.com/bitcoin/bips/tree/master/bip-0039自行寻找。

最后写点小收获,java的BigInteger, 转成byte[]时,如果第一个byte是负数,那么会在其前加上一个byte,值是0。这样,256位的私钥,本来应该变成32个byte,却变成了33个byte,这样处理,是因为如果用byte数组生成大整数,如果最高位为1,那么生成的整数是负的。但如果这些byte变成字串,则没关系。比如BigInteger(“FFF”,16)并不会变成一个负数。

以上方法,助记词和私钥可以相互转化,另有一种从助记词生成私钥的方法,(但反向不行)

参考 java使用bip39创建以太坊钱包https://www.jianshu.com/p/14b9d2908a66

区块链知识普及之 BIP39 助记词生成过程详解https://www.jianshu.com/p/3db04e987a6c

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容