Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
65 lines
1.7 KiB
Plaintext
65 lines
1.7 KiB
Plaintext
import utils from '../../../../scoring/utils.mjs';
|
|
|
|
const countSubstring = (string, substring) => {
|
|
let count = 0;
|
|
let pos = string.indexOf(substring);
|
|
while (pos >= 0) {
|
|
count += 1;
|
|
pos = string.indexOf(substring, pos + substring.length);
|
|
}
|
|
return count;
|
|
};
|
|
const getCounts = ({
|
|
sub,
|
|
token
|
|
}) => {
|
|
// lower-case match.token before calculating: capitalization shouldn't affect l33t calc.
|
|
const tokenLower = token.toLowerCase();
|
|
// num of subbed chars
|
|
const subbedCount = countSubstring(tokenLower, sub.substitution);
|
|
// num of unsubbed chars
|
|
const unsubbedCount = countSubstring(tokenLower, sub.letter);
|
|
return {
|
|
subbedCount,
|
|
unsubbedCount
|
|
};
|
|
};
|
|
var l33tVariant = ({
|
|
l33t,
|
|
subs,
|
|
token
|
|
}) => {
|
|
if (!l33t) {
|
|
return 1;
|
|
}
|
|
let variations = 1;
|
|
subs.forEach(sub => {
|
|
const {
|
|
subbedCount,
|
|
unsubbedCount
|
|
} = getCounts({
|
|
sub,
|
|
token
|
|
});
|
|
if (subbedCount === 0 || unsubbedCount === 0) {
|
|
// for this sub, password is either fully subbed (444) or fully unsubbed (aaa)
|
|
// treat that as doubling the space (attacker needs to try fully subbed chars in addition to
|
|
// unsubbed.)
|
|
variations *= 2;
|
|
} else {
|
|
// this case is similar to capitalization:
|
|
// with aa44a, U = 3, S = 2, attacker needs to try unsubbed + one sub + two subs
|
|
const p = Math.min(unsubbedCount, subbedCount);
|
|
let possibilities = 0;
|
|
for (let i = 1; i <= p; i += 1) {
|
|
possibilities += utils.nCk(unsubbedCount + subbedCount, i);
|
|
}
|
|
variations *= possibilities;
|
|
}
|
|
});
|
|
return variations;
|
|
};
|
|
|
|
export { l33tVariant as default };
|
|
//# sourceMappingURL=l33t.mjs.map
|