User: Rust is the product (option a). tools/edge-bench-rs moves to edge/
(crate edge; binaries edge-node, the worker, and edge-bench, the replay).
CI's new job edge runs cargo test and edge/check-fixtures.sh: both
RangeIndexers on three committed captures (edge/fixtures, 25k overview
lines each of a.b.models, a.b.ath and a.b.boneless in 5 chunks, 3.5 MB),
compared field by field with check.ts; deploy waits for it. The
TypeScript RangeIndexer stays as check.ts's reference. README: what it
is now; the benchmark findings as history.
Random names: looksRandom missed long tokens of capitals and digits
("51294P1CUKR2R35X", release 74539068, readable and a Newznab title).
12+ capitals and digits switching 6+ times between them are random
(COD4MW2REMASTERED switches 4 times, BEATLES1964REMASTER twice); both
implementations, identical on the fixtures.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
42 lines
2.1 KiB
TypeScript
42 lines
2.1 KiB
TypeScript
import { isGenericName } from './identity.js'
|
|
|
|
/**
|
|
* Obfuscated names: one long token of mixed letters and digits, no
|
|
* separators, and the other generated shapes seen on Usenet (LOG.md
|
|
* 2026-10-01 (3)). Kept in step with SQL's is_readable_name().
|
|
*/
|
|
/** How often a token goes from a letter to a digit or back. */
|
|
function letterDigitSwitches(token: string): number {
|
|
let switches = 0
|
|
for (let i = 1; i < token.length; i++) {
|
|
const a = token.charCodeAt(i - 1) <= 57
|
|
const b = token.charCodeAt(i) <= 57
|
|
if (a !== b) switches++
|
|
}
|
|
return switches
|
|
}
|
|
|
|
export function looksRandom(name: string): boolean {
|
|
// An unknown short extension (e.g. ".bin") says nothing about the name.
|
|
name = name.replace(/\.[A-Za-z0-9]{1,4}$/, '')
|
|
// VIDEO_TS, Sample, CD1: real words, but no name.
|
|
if (isGenericName(name)) return true
|
|
if (/^[0-9a-f]{16,}$/i.test(name)) return true
|
|
// 6327d9fa2d6acf3e9a61fb053359d5e7.1790574045 (hex and a Unix time)
|
|
if (/^[0-9a-f]{16,}\.\d{9,}$/i.test(name)) return true
|
|
// UUIDs
|
|
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(name)) return true
|
|
// 1650777167 (yEncBin), "83111763 n" (rclone uploads)
|
|
if (/^\d{6,}( n)?$/.test(name)) return true
|
|
// prvjr7hapd0i1ny14pz4, and rclone's long base32 names
|
|
if (/^[a-z0-9]{12,}$/.test(name) && (name.match(/\d/g)?.length ?? 0) >= 2 && (name.match(/[a-z]/g)?.length ?? 0) >= 4) return true
|
|
// wHJ7s71sAGE: short, but capitals all over the token, not only at word starts
|
|
if (/^[A-Za-z0-9]{8,15}$/.test(name) && /\d/.test(name) && /[a-z]/.test(name) && (name.slice(1).match(/[A-Z]/g)?.length ?? 0) >= 3) return true
|
|
// 51294P1CUKR2R35X: capitals and digits only, switching between them all over the token
|
|
// (COD4MW2REMASTERED switches 4 times, BEATLES1964REMASTER twice).
|
|
if (/^[A-Z0-9]{12,}$/.test(name) && letterDigitSwitches(name) >= 6) return true
|
|
if (!/^[A-Za-z0-9]{16,}$/.test(name) || !/[a-z]/.test(name) || !/[A-Z]/.test(name)) return false
|
|
// Digits, or many capitals without separators (e.g. RmISakytFwXSCEzjVEpaKk).
|
|
return /\d/.test(name) || (name.match(/[A-Z]/g) ?? []).length >= 6
|
|
}
|