JavaScript实现枚举含3个未知位置缺失词的BIP39助记词组合
BIP39助记词3个缺失词全量枚举JS实现
- 适配场景:找回丢失3个词的BIP39标准英文助记词,已知助记词总长度、除3个缺失词外的其余已知词、助记词最后一个词固定,支持枚举所有可能的位置组合+词组合
- 实现逻辑选占位符模板方案:先生成所有合法的缺失位置模板,再通过三层循环遍历BIP39词表替换占位符,逻辑直观易调试,不会出现多层循环嵌套写错位置的问题
前置约束
- 助记词最后一个词必须为已知正确值,不参与缺失位枚举
- 仅支持恰好3个词完全未知的场景,缺失位置可自动枚举所有可能
- BIP39英文标准词表固定为2048个词,枚举时严格从该词表取值
循环实现代码
/** * 取可选位置中选3个缺失位的所有不重复组合(固定3个缺失位直接用三层循环实现,性能优于递归) * @param {number} totalFrontCount 尾词前的位置总数 * @returns {Array<number[]>} 缺失位置索引组合列表 */ function getMissingPosCombos(totalFrontCount) { const combos = [] for (let i = 0; i < totalFrontCount - 2; i++) { for (let j = i + 1; j < totalFrontCount - 1; j++) { for (let l = j + 1; l < totalFrontCount; l++) { combos.push([i, j, l]) } } } return combos } /** * 核心枚举循环函数 * @param {string[]} knownFrontWords 用户已知的前置助记词(即除最后一个尾词、3个缺失词之外的所有词,按记忆顺序排列) * @param {string} lastWord 已知的助记词最后一个词 * @param {number} totalWordLength 助记词总长度,合法值为12/15/18/21/24 * @param {string[]} bip39Wordlist BIP39英文标准词表(长度2048的有序数组) * @param {(mnemonic: string[]) => boolean} onGenerate 每生成一个完整助记词的回调,返回true可提前终止枚举 */ function loop(knownFrontWords, lastWord, totalWordLength, bip39Wordlist, onGenerate) { // 基础参数校验 if (bip39Wordlist.length !== 2048) throw new Error('请传入标准BIP39英文2048词表') const frontPosCount = totalWordLength - 1 const knownFrontCount = knownFrontWords.length if (knownFrontCount !== frontPosCount - 3) throw new Error('已知前置词数量不符合3个缺失词的要求') // 生成所有可能的3个缺失位置组合(仅从前置位选,尾词位置固定不参与枚举) const missingPosCombos = getMissingPosCombos(frontPosCount) // 遍历所有位置模板 for (const posCombo of missingPosCombos) { // 构建当前位置模板:缺失位填null,其余位置按顺序填入已知前置词 const template = new Array(frontPosCount).fill(null) let knownPtr = 0 for (let idx = 0; idx < frontPosCount; idx++) { if (!posCombo.includes(idx)) { template[idx] = knownFrontWords[knownPtr++] } } const [p1, p2, p3] = posCombo // 三层循环遍历BIP39词表,替换占位符生成完整助记词 for (let i = 0; i < 2048; i++) { const w1 = bip39Wordlist[i] for (let j = 0; j < 2048; j++) { const w2 = bip39Wordlist[j] for (let k = 0; k < 2048; k++) { const w3 = bip39Wordlist[k] const fullMnemonic = [...template] fullMnemonic[p1] = w1 fullMnemonic[p2] = w2 fullMnemonic[p3] = w3 fullMnemonic.push(lastWord) // 拼接固定尾词 // 触发回调,回调返回true直接终止所有循环 if (onGenerate(fullMnemonic)) return } } } } }
使用说明
- 禁止把所有生成的助记词存到数组里,总组合量过大会直接占满内存,在
onGenerate回调里写校验逻辑即可,调用示例:const BIP39_WORDLIST = [] // 提前载入标准BIP39英文2048词表 loop( ['abandon', 'ability'], // 替换为你记得的所有前置词 'zoo', // 替换为你确定的最后一个助记词 12, // 替换为你的助记词总长度 BIP39_WORDLIST, (mnemonic) => { // 在这里写校验逻辑:优先做BIP39校验位过滤,再推导地址对比目标地址 // 找到匹配的助记词返回true即可终止枚举 console.log('当前枚举:', mnemonic.join(' ')) return false } ) - 性能优化提示:
- 优先在回调里加BIP39校验位过滤,12词助记词可直接过滤掉15/16的无效组合,24词助记词可过滤掉255/256的无效组合,能大幅减少后续计算量
- 枚举前先校验所有已知词都在BIP39词表内,避免传入错词做无用功
内容的提问来源于stack exchange,提问作者bewved
相关产品推荐
相关产品推荐

