feat: scan

This commit is contained in:
hashbro
2026-09-13 00:31:54 +08:00
parent 558912864d
commit 4fa162c72c
5 changed files with 70 additions and 54 deletions
+42 -24
View File
@@ -11,6 +11,10 @@ class MnemonicDetector
public const MIN_SUSPECTED = 8;
public const MIN_GAPPED_HITS = 9;
public const MAX_GAPS = 2;
public const MIN_CONFIRMED = 12;
public const MIN_UNIQUE = 8;
@@ -180,31 +184,45 @@ class MnemonicDetector
{
$n = count($tokens);
$best = null;
$maxLen = min(24, $n);
for ($len = self::MIN_SUSPECTED; $len <= $maxLen; $len++) {
for ($i = 0; $i <= $n - $len; $i++) {
$window = array_slice($tokens, $i, $len);
$hits = 0;
foreach ($window as $word) {
if ($word !== '' && isset($wordlist[$word])) {
$hits++;
}
}
if ($hits < self::MIN_SUSPECTED) {
continue;
}
$score = ($hits * 10) - (($len - $hits) * 2);
if ($best !== null && ($hits < $best['word_count'] || ($hits === $best['word_count'] && $score <= $best['score']))) {
continue;
}
$best = [
'candidate' => implode(' ', $window),
'word_count' => $hits,
'score' => $score,
'language' => 'en',
'confirmed' => false,
];
for ($i = 0; $i < $n; $i++) {
if ($tokens[$i] === '' || ! isset($wordlist[$tokens[$i]])) {
continue;
}
$hits = 0;
$gaps = 0;
$end = $i;
for ($j = $i; $j < $n; $j++) {
$word = $tokens[$j];
if ($word !== '' && isset($wordlist[$word])) {
$hits++;
$end = $j;
continue;
}
$next = $tokens[$j + 1] ?? null;
if ($gaps < self::MAX_GAPS && $next !== null && $next !== '' && isset($wordlist[$next])) {
$gaps++;
continue;
}
break;
}
$minHits = $gaps === 0 ? self::MIN_SUSPECTED : self::MIN_GAPPED_HITS;
if ($hits < $minHits) {
continue;
}
$window = array_slice($tokens, $i, $end - $i + 1);
$score = ($hits * 10) - ($gaps * 4);
if ($best !== null && ($hits < $best['word_count'] || ($hits === $best['word_count'] && $score <= $best['score']))) {
continue;
}
$best = [
'candidate' => implode(' ', $window),
'word_count' => $hits,
'score' => $score,
'language' => 'en',
'confirmed' => false,
];
}
return $best;