mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 22:07:10 -04:00
186 lines
7.2 KiB
JavaScript
186 lines
7.2 KiB
JavaScript
import { a as __unplugin_components_1 } from './chunk-8109fd17.js';
|
|
import { _ as __unplugin_components_3 } from './chunk-4e7a6a8d.js';
|
|
import { defineComponent, ref, computed, mergeProps, unref, isRef, withCtx, createVNode, toDisplayString, openBlock, createBlock, Fragment, renderList, useSSRContext } from 'vue';
|
|
import { ssrRenderAttrs, ssrRenderComponent, ssrInterpolate, ssrRenderList } from 'vue/server-renderer';
|
|
import _ from 'lodash';
|
|
import './chunk-6003391e.js';
|
|
import '@vueuse/core';
|
|
import 'pinia';
|
|
import './chunk-11f44f81.js';
|
|
import './chunk-35c3d701.js';
|
|
|
|
function prettifyExponentialNotation(exponentialNotation) {
|
|
const [base, exponent] = exponentialNotation.toString().split("e");
|
|
const baseAsNumber = Number.parseFloat(base);
|
|
const prettyBase = baseAsNumber % 1 === 0 ? baseAsNumber.toLocaleString() : baseAsNumber.toFixed(2);
|
|
return exponent ? `${prettyBase}e${exponent}` : prettyBase;
|
|
}
|
|
function getHumanFriendlyDuration({ seconds }) {
|
|
if (seconds <= 1e-3) {
|
|
return "Instantly";
|
|
}
|
|
if (seconds <= 1) {
|
|
return "Less than a second";
|
|
}
|
|
const timeUnits = [
|
|
{ unit: "millenium", secondsInUnit: 31536e6, format: prettifyExponentialNotation, plural: "millennia" },
|
|
{ unit: "century", secondsInUnit: 31536e5, plural: "centuries" },
|
|
{ unit: "decade", secondsInUnit: 31536e4, plural: "decades" },
|
|
{ unit: "year", secondsInUnit: 31536e3, plural: "years" },
|
|
{ unit: "month", secondsInUnit: 2592e3, plural: "months" },
|
|
{ unit: "week", secondsInUnit: 604800, plural: "weeks" },
|
|
{ unit: "day", secondsInUnit: 86400, plural: "days" },
|
|
{ unit: "hour", secondsInUnit: 3600, plural: "hours" },
|
|
{ unit: "minute", secondsInUnit: 60, plural: "minutes" },
|
|
{ unit: "second", secondsInUnit: 1, plural: "seconds" }
|
|
];
|
|
return _.chain(timeUnits).map(({ unit, secondsInUnit, plural, format = _.identity }) => {
|
|
const quantity = Math.floor(seconds / secondsInUnit);
|
|
seconds %= secondsInUnit;
|
|
if (quantity <= 0) {
|
|
return void 0;
|
|
}
|
|
const formattedQuantity = format(quantity);
|
|
return `${formattedQuantity} ${quantity > 1 ? plural : unit}`;
|
|
}).compact().take(2).join(", ").value();
|
|
}
|
|
function getPasswordCrackTimeEstimation({ password, guessesPerSecond = 1e9 }) {
|
|
const charsetLength = getCharsetLength({ password });
|
|
const passwordLength = password.length;
|
|
const entropy = password === "" ? 0 : Math.log2(charsetLength) * passwordLength;
|
|
const secondsToCrack = 2 ** entropy / guessesPerSecond;
|
|
const crackDurationFormatted = getHumanFriendlyDuration({ seconds: secondsToCrack });
|
|
const score = Math.min(entropy / 128, 1);
|
|
return {
|
|
entropy,
|
|
charsetLength,
|
|
passwordLength,
|
|
crackDurationFormatted,
|
|
secondsToCrack,
|
|
score
|
|
};
|
|
}
|
|
function getCharsetLength({ password }) {
|
|
const hasLowercase = /[a-z]/.test(password);
|
|
const hasUppercase = /[A-Z]/.test(password);
|
|
const hasDigits = /\d/.test(password);
|
|
const hasSpecialChars = /\W|_/.test(password);
|
|
let charsetLength = 0;
|
|
if (hasLowercase) {
|
|
charsetLength += 26;
|
|
}
|
|
if (hasUppercase) {
|
|
charsetLength += 26;
|
|
}
|
|
if (hasDigits) {
|
|
charsetLength += 10;
|
|
}
|
|
if (hasSpecialChars) {
|
|
charsetLength += 32;
|
|
}
|
|
return charsetLength;
|
|
}
|
|
|
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
__name: "password-strength-analyser",
|
|
__ssrInlineRender: true,
|
|
setup(__props) {
|
|
const password = ref("");
|
|
const crackTimeEstimation = computed(() => getPasswordCrackTimeEstimation({ password: password.value }));
|
|
const details = computed(() => [
|
|
{
|
|
label: "Password length:",
|
|
value: crackTimeEstimation.value.passwordLength
|
|
},
|
|
{
|
|
label: "Entropy:",
|
|
value: Math.round(crackTimeEstimation.value.entropy * 100) / 100
|
|
},
|
|
{
|
|
label: "Character set size:",
|
|
value: crackTimeEstimation.value.charsetLength
|
|
},
|
|
{
|
|
label: "Score:",
|
|
value: `${Math.round(crackTimeEstimation.value.score * 100)} / 100`
|
|
}
|
|
]);
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
const _component_c_input_text = __unplugin_components_3;
|
|
const _component_c_card = __unplugin_components_1;
|
|
_push(`<div${ssrRenderAttrs(mergeProps({
|
|
flex: "",
|
|
"flex-col": "",
|
|
"gap-3": ""
|
|
}, _attrs))}>`);
|
|
_push(ssrRenderComponent(_component_c_input_text, {
|
|
value: unref(password),
|
|
"onUpdate:value": ($event) => isRef(password) ? password.value = $event : null,
|
|
type: "password",
|
|
placeholder: "Enter a password...",
|
|
clearable: "",
|
|
autofocus: "",
|
|
"raw-text": "",
|
|
"test-id": "password-input"
|
|
}, null, _parent));
|
|
_push(ssrRenderComponent(_component_c_card, { "text-center": "" }, {
|
|
default: withCtx((_, _push2, _parent2, _scopeId) => {
|
|
if (_push2) {
|
|
_push2(`<div op-60${_scopeId}> Duration to crack this password with brute force </div><div text-2xl data-test-id="crack-duration"${_scopeId}>${ssrInterpolate(unref(crackTimeEstimation).crackDurationFormatted)}</div>`);
|
|
} else {
|
|
return [
|
|
createVNode("div", { "op-60": "" }, " Duration to crack this password with brute force "),
|
|
createVNode("div", {
|
|
"text-2xl": "",
|
|
"data-test-id": "crack-duration"
|
|
}, toDisplayString(unref(crackTimeEstimation).crackDurationFormatted), 1)
|
|
];
|
|
}
|
|
}),
|
|
_: 1
|
|
}, _parent));
|
|
_push(ssrRenderComponent(_component_c_card, null, {
|
|
default: withCtx((_, _push2, _parent2, _scopeId) => {
|
|
if (_push2) {
|
|
_push2(`<!--[-->`);
|
|
ssrRenderList(unref(details), ({ label, value }) => {
|
|
_push2(`<div flex gap-3${_scopeId}><div flex-1 text-right op-60${_scopeId}>${ssrInterpolate(label)}</div><div flex-1 text-left${_scopeId}>${ssrInterpolate(value)}</div></div>`);
|
|
});
|
|
_push2(`<!--]-->`);
|
|
} else {
|
|
return [
|
|
(openBlock(true), createBlock(Fragment, null, renderList(unref(details), ({ label, value }) => {
|
|
return openBlock(), createBlock("div", {
|
|
key: label,
|
|
flex: "",
|
|
"gap-3": ""
|
|
}, [
|
|
createVNode("div", {
|
|
"flex-1": "",
|
|
"text-right": "",
|
|
"op-60": ""
|
|
}, toDisplayString(label), 1),
|
|
createVNode("div", {
|
|
"flex-1": "",
|
|
"text-left": ""
|
|
}, toDisplayString(value), 1)
|
|
]);
|
|
}), 128))
|
|
];
|
|
}
|
|
}),
|
|
_: 1
|
|
}, _parent));
|
|
_push(`<div op-70><span font-bold>Note: </span> The computed strength is based on the time it would take to crack the password using a brute force approach, it does not take into account the possibility of a dictionary attack. </div></div>`);
|
|
};
|
|
}
|
|
});
|
|
|
|
const _sfc_setup = _sfc_main.setup;
|
|
_sfc_main.setup = (props, ctx) => {
|
|
const ssrContext = useSSRContext();
|
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/tools/password-strength-analyser/password-strength-analyser.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
|
|
export { _sfc_main as default };
|