Files
SnowLuma/.pnpm-store/v11/files/5e/372ea829ccbfde91f3cea29d9e017bd618ec59c5b9da3a39ffd893f332f56002fb306e2998b01302721eaf437acb13fc26757adeff0cf08af79c48395cfd82
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

84 lines
3.3 KiB
Plaintext

'use strict';
var levenshtein = require('../../utils/levenshtein.cjs');
var types = require('../../types.cjs');
var mergeUserInputDictionary = require('../../utils/mergeUserInputDictionary.cjs');
class MatchDictionary extends types.MatcherBaseClass {
constructor(options, wordSequenceCheck) {
super(options);
this.wordSequenceCheck = wordSequenceCheck;
}
getRangedDictionaries(userInputsOptions) {
if (this.wordSequenceCheck) {
const rankedDictionaries = {};
const rankedDictionariesMaxWordSize = {};
Object.keys(this.options.rankedDictionaries).forEach(key => {
if (this.options.isWordSequence(key)) {
rankedDictionaries[key] = this.options.rankedDictionaries[key];
rankedDictionariesMaxWordSize[key] = this.options.rankedDictionariesMaxWordSize[key];
}
});
return {
rankedDictionaries,
rankedDictionariesMaxWordSize
};
}
return mergeUserInputDictionary(this.options.rankedDictionaries, this.options.rankedDictionariesMaxWordSize, userInputsOptions);
}
match({
password,
userInputsOptions,
useLevenshtein = true
}) {
const matches = [];
const passwordLength = password.length;
const passwordLower = password.toLowerCase();
const {
rankedDictionaries,
rankedDictionariesMaxWordSize
} = this.getRangedDictionaries(userInputsOptions);
// eslint-disable-next-line complexity,max-statements
Object.keys(rankedDictionaries).forEach(dictionaryName => {
const rankedDict = rankedDictionaries[dictionaryName];
const longestDictionaryWordSize = rankedDictionariesMaxWordSize[dictionaryName];
const searchWidth = Math.min(longestDictionaryWordSize, passwordLength);
for (let i = 0; i < passwordLength; i += 1) {
const searchEnd = Math.min(i + searchWidth, passwordLength);
for (let j = i; j < searchEnd; j += 1) {
const usedPassword = passwordLower.slice(i, j + 1 || 9e9);
const isInDictionary = usedPassword in rankedDict;
let foundLevenshteinDistance = {};
// only use levenshtein distance on full password to minimize the performance drop
// and because otherwise there would be to many false positives
const isFullPassword = i === 0 && j === passwordLength - 1;
if (this.options.useLevenshteinDistance && isFullPassword && !isInDictionary && useLevenshtein) {
foundLevenshteinDistance = levenshtein(usedPassword, rankedDict, this.options.levenshteinThreshold);
}
const isLevenshteinMatch = Object.keys(foundLevenshteinDistance).length !== 0;
if (isInDictionary || isLevenshteinMatch) {
const usedRankPassword = isLevenshteinMatch ? foundLevenshteinDistance.levenshteinDistanceEntry : usedPassword;
const rank = rankedDict[usedRankPassword];
matches.push({
pattern: 'dictionary',
i,
j,
token: password.slice(i, j + 1 || 9e9),
matchedWord: usedPassword,
rank,
dictionaryName: dictionaryName,
reversed: false,
l33t: false,
...foundLevenshteinDistance
});
}
}
}
});
return matches;
}
}
module.exports = MatchDictionary;
//# sourceMappingURL=matching.cjs.map