diff --git a/index.html b/index.html index 133415b..d434626 100644 --- a/index.html +++ b/index.html @@ -104,13 +104,22 @@

根据 GPU 性能和占用率调节这两个值。

你会得到一个生效时间距离现在 {{ (backTime > 2592000) ? `${Math.ceil(backTime / 2592000)} 个月` : `${Math.ceil(backTime / 86400)} 天` }}之内(最早为 {{ (new Date(Date.now() - backTime * 1000)).toISOString() }})的密钥。

- + 将格式应用到子密钥而不是主密钥上

40 个十六进制数字,不区分大小写。空格会被忽略,X 表示只要这些位相同即可,其他 [\dA-FX] 以外的字符表示对该位数字没有要求。

最后 个数字为 快速设置

预计需要计算 {{ estimatedHashCount }} 次 hash,实际的计算次数可能是这个值的几分之一或几倍,也许需要一点运气……

+
+ 直接使用 GLSL 代码! +
+ +
+

你可以自行编写更复杂的判断密钥指纹是否符合格式的 GLSL 代码,这些代码将以 `#define FILTER(h) (code)` 的形式出现在算号使用的着色器中。

+

换行会被替换成空格,留空则会使用“密钥指纹格式”的设定,输入错误的代码将无法得到任何密钥。

+

在着色器中,计算的密钥指纹(实际上是 80 bytes 的 SHA-1 hash)以大端序保存为 `uint[5]`,并使用上面的 `FILTER` 来检查是否符合格式。

+
把不同密钥的“靓号”合并到一起!
diff --git a/package.json b/package.json index 9ca78c5..c61097d 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,10 @@ "preview": "vite preview" }, "devDependencies": { - "@types/node": "^22.2.0", + "@types/node": "^22.7.4", "rollup-plugin-visualizer": "^5.12.0", - "typescript": "^5.5.4", - "vite": "^5.4.0", + "typescript": "^5.6.2", + "vite": "^5.4.8", "vite-plugin-html": "^3.2.2" }, "dependencies": { diff --git a/src/main.ts b/src/main.ts index 9a200c9..3f5177d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,7 +5,7 @@ import { SecretSubkeyPacket, } from 'openpgp/lightweight'; import { TarWriter } from '@gera2ld/tarjs'; -import { createVanityKey } from './vanity-key.ts'; +import { patternToFilter, createVanityKey } from './vanity-key.ts'; import tadaData from './tada.ogg?inline'; import silenceData from './near-silence.ogg?inline'; import { @@ -35,6 +35,7 @@ const app: { pattern: string, patternNumber: string, patternLength: number, + filter: string, vanitySubkey: boolean, notification: { sfx: boolean, @@ -59,6 +60,7 @@ const app: { mounted: () => void, addUserID: () => void, patternHelper: () => void, + showAutoFilter: () => void, toggleKeygen: () => Promise, bulkDownload: () => Promise, subkeyCombine: () => Promise, @@ -74,6 +76,7 @@ const app: { pattern: '', patternNumber: '0123456789ABCDEFXXXX'[Math.floor(Math.random() * 20)], patternLength: 6 + Math.floor(Math.random() * 3), + filter: '', vanitySubkey: false, notification: { sfx: false, @@ -126,6 +129,10 @@ const app: { this.pattern = this.formatFingerprint(('*'.repeat(40 - this.patternLength) + this.patternNumber.repeat(this.patternLength))); }, + showAutoFilter() { + alert(patternToFilter(this.pattern)); + }, + async bulkDownload() { if (!this.generatedKeyHistory.length) return; const tar = new TarWriter; @@ -178,7 +185,7 @@ const app: { do { const generatedKey = await createVanityKey( options, - this.pattern, + this.filter.replaceAll('\n', ' ') || patternToFilter(this.pattern), this.thread, this.iteration, (h, t) => { diff --git a/src/vanity-key.ts b/src/vanity-key.ts index 97b9ea2..d400183 100644 --- a/src/vanity-key.ts +++ b/src/vanity-key.ts @@ -42,18 +42,10 @@ const swap32 = (x: number) => ( ((x >> 24) & 0xFF) ) >>> 0; -export const createVanityKey = async ( - config: GenerateKeyOptions, - pattern: string, - thread: number, - iteration: number, - progressCallback: (hash: number, time: DOMHighResTimeStamp) => void = () => {}, - checkAbort: (hash: number, time: DOMHighResTimeStamp) => boolean = () => false, - vanitySubkey: boolean = false, -): Promise => { +export const patternToFilter = (pattern: string) => { pattern = pattern.replaceAll(' ', ''); if (pattern.length != 40) throw new Error('Invalid pattern'); - const filter = [ + return [ ...[0, 8, 16, 24, 32].map((e, i) => { const s = pattern.substring(e, e + 8); let mask = ''; @@ -86,8 +78,17 @@ export const createVanityKey = async ( return acc; }, [] as string[]), ].filter(Boolean).join(' && ') || 'true'; - // console.log(filter); +} +export const createVanityKey = async ( + config: GenerateKeyOptions, + filter: string, + thread: number, + iteration: number, + progressCallback: (hash: number, time: DOMHighResTimeStamp) => void = () => {}, + checkAbort: (hash: number, time: DOMHighResTimeStamp) => boolean = () => false, + vanitySubkey: boolean = false, +): Promise => { const size = Math.round(Math.sqrt(thread)); const canvas = new OffscreenCanvas(size, size); const gl = canvas.getContext('webgl2')!;