# 如何用随机打乱顺序的12个助记词生成指定钱包私钥|NodeJS

By [dapaopao](https://paragraph.com/@dapaopao) · 2022-11-05

---

前段时间参加了一个游戏活动，给出12个助记词但是打乱顺序，钱包里有1个Eth，FCFS。

在没有任何提示的情况下会有12!（479001600）种可能。

这不就是全排列吗！

一、准备工作
------

创建一个目录然后初始化项目

    npm init
    

安装yarn

    npm install -g yarn
    

安装依赖模块

    yarn add bip39 ethereum-hdwallet
    

二、代码部分
------

创建index.js文件

导入模块

    var fs = require("fs")
    const bip39 = require('bip39')
    const HDWallet = require('ethereum-hdwallet');
    

配置参数

    //计数器
    var count = 0;
    //已知的12个助记词
    var arrtemp = ['cluster', 'violin', 'cart', 'steel', 'crouch', 'olive', 'water', 'pass', 'lab', 'father', 'until', 'exercise'];
    //需要对比的钱包地址
    var create_address = '0x1c5ea7f3a722ea2606cfbd4d6b3aaec488906553'.toLowerCase();
    

实现部分

    //全排列 非递归 求模算法
    async function perm(arr) {  
        var result = new Array(arr.length);  
        var fac = 1;  
        for (var i = 2; i <= arr.length; i++)  
            fac *= i;  
        for (index = 0; index < fac; index++) {  
            var t = index;  
            for (i = 1; i <= arr.length; i++) {  
                var w = t % i;  
                for (j = i - 1; j > w; j--)  
                    result[j] = result[j - 1];  
                result[w] = arr[i - 1];  
                t = Math.floor(t / i);  
            }  
    
            //console.log(result); 
            var returnFlag = await getAddress(result);
            if(returnFlag)
            {
                            //创建文件保存正确的助记词顺序
                fs.writeFile('keyword.txt', result.toString(), function(err, fd) {});
                console.log("Find Key:"+result.toString());
                console.log("total", count);
                process.exit(1);
            }
        }  
        console.log("total", count);
    }  
    
    //用打乱生成的助记词生成公私钥、地址
    async function getAddress(inputarr) {
        var flag = false;
        var temp = inputarr;
        var str = '';
        for (var i = 0; i < temp.length; i++) {
          str += temp[i] + ' ';
        }
        mnemonic = str;
    
        var seed = await bip39.mnemonicToSeed(mnemonic); //生成种子
        //console.log(seed)
        var hdwallet = HDWallet.fromSeed(seed);
        for (var i = 0; i < 1; i++) { // 用同一个种子生成多个地址
          count++;
    
          //console.log('=============地址' + (i + 1) + '=================')
    
          var key = hdwallet.derive("m/44'/60'/0'/0/" + i); // 地址路径的最后一位设置为循环变量
          //console.log(create_address);
          var EthAddress = '0x' + key.getAddress().toString('hex'); //地址
          if (EthAddress == create_address) {
            console.log("PrivateKey = " + key.getPrivateKey().toString('hex')); // 私钥
            console.log("PublicKey = " + key.getPublicKey().toString('hex')); // 公钥
            console.log('ETH Address = ' + EthAddress);
            flag = true;
          }
          else {
            console.log('=============address count:' + (count) + ' =================');
            console.log('=============address:' + EthAddress + ' =================');
            flag = false;
          }
    
        }
        
        return flag;
    
    }
    
    perm(arrtemp);
    

最后执行

    node index.js
    

效果如下

![](https://storage.googleapis.com/papyrus_images/1b788f5b0bab5dfba492f64f8e9cffdd42d5280b0d730c5b4f1ad3ae76bd8c5a.png)

如果匹配到结果会在当前文件夹下生成keyword.txt文件来保存结果。

三、总结
----

这代码可以改进的还有很多，比如用多线程来执行，会快很多。

最后一提当我还在运行的时候，已经被某个人拿走了那1ETH。。

如有任何问题欢迎来沟通交流，关注推特不定期更新。

[https://twitter.com/dapaopao\_eth](https://twitter.com/dapaopao_eth)

---

*Originally published on [dapaopao](https://paragraph.com/@dapaopao/12-nodejs)*
