tools: obf_runs and obf_kinds, measuring the obfuscated subjects
obf_runs: how obfuscated articles come in runs (strict, and per poster and tool with a time gap). obf_kinds: what they are (unquoted subjects with a counter, random tokens equal to the message-id, other random tokens, ...), with examples. LOG.md 2026-10-11 (5). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5109481d67
commit
18b9ffdca3
2 files changed
+133
No files matched your search
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* What the obfuscated lines of a capture are (LOG.md 2026-10-11 (5)):
|
||||
* unquoted subjects with a counter ("Name.exe (1/2)", parseable without
|
||||
* quotes), random tokens equal to the message-id's local part (ngPost-style
|
||||
* private uploads), other random tokens, and the rest; with examples.
|
||||
*
|
||||
* node --import=@poppinss/ts-exec tools/obf_kinds.ts <capture dir>...
|
||||
*/
|
||||
import { readFile, readdir } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { unzipSync } from 'node:zlib'
|
||||
import { SegmentScanner, scanOverviewText } from '#lib/edge/scan'
|
||||
|
||||
for (const dir of process.argv.slice(2)) {
|
||||
const { group } = JSON.parse(await readFile(join(dir, 'range.json'), 'utf8'))
|
||||
const scanner = new SegmentScanner()
|
||||
const kinds = new Map<string, { n: number; examples: string[] }>()
|
||||
let obfuscated = 0
|
||||
const add = (kind: string, subject: string) => {
|
||||
const k = kinds.get(kind) ?? { n: 0, examples: [] }
|
||||
k.n++
|
||||
if (k.examples.length < 3) k.examples.push(subject.slice(0, 90))
|
||||
kinds.set(kind, k)
|
||||
}
|
||||
for (const file of (await readdir(dir)).filter((f) => f.endsWith('.gz')).sort()) {
|
||||
scanOverviewText(unzipSync(await readFile(join(dir, file))).toString('utf8'), (n, subject, from, date, messageId, bytes, xref) => {
|
||||
if (xref && scanner.owner(xref, group, { [group]: 1 }) !== group) return
|
||||
if (scanner.segment(n, subject, from, date, messageId, bytes, xref, group)) return
|
||||
obfuscated++
|
||||
const local = messageId.replace(/^</, '').split('@')[0]
|
||||
const s = subject.trim()
|
||||
if (/\(\d+\/\d+\)\s*$/.test(s) || /\[\d+\/\d+\]\s*$/.test(s)) add(/"/.test(s) ? 'counter, quoted name not parsed' : 'counter, unquoted name', s)
|
||||
else if (s === local) add('random = message-id', s)
|
||||
else if (/^[A-Za-z0-9]{16,}$/.test(s)) add('random token', s)
|
||||
else if (/yEnc/i.test(s)) add('yEnc, no counter', s)
|
||||
else add('other', s)
|
||||
})
|
||||
}
|
||||
console.log(`== ${dir}: ${obfuscated} obfuscated`)
|
||||
for (const [kind, k] of [...kinds].sort((a, b) => b[1].n - a[1].n)) {
|
||||
console.log(` ${kind}: ${k.n} (${((100 * k.n) / obfuscated).toFixed(1)}%) e.g. ${k.examples.map((e) => JSON.stringify(e)).join(' | ')}`)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user