@jjlmoya/utils-developer 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +64 -0
- package/src/category/i18n/en.ts +34 -0
- package/src/category/i18n/es.ts +34 -0
- package/src/category/i18n/fr.ts +34 -0
- package/src/category/index.ts +31 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +78 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/css_specificity_logic.test.ts +39 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +22 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/aspectRatio/bibliography.astro +14 -0
- package/src/tool/aspectRatio/component.astro +468 -0
- package/src/tool/aspectRatio/i18n/en.ts +177 -0
- package/src/tool/aspectRatio/i18n/es.ts +177 -0
- package/src/tool/aspectRatio/i18n/fr.ts +177 -0
- package/src/tool/aspectRatio/index.ts +34 -0
- package/src/tool/aspectRatio/seo.astro +14 -0
- package/src/tool/aspectRatio/ui.ts +12 -0
- package/src/tool/calculadoraTiempoDatos/bibliography.astro +14 -0
- package/src/tool/calculadoraTiempoDatos/component.astro +829 -0
- package/src/tool/calculadoraTiempoDatos/i18n/en.ts +150 -0
- package/src/tool/calculadoraTiempoDatos/i18n/es.ts +163 -0
- package/src/tool/calculadoraTiempoDatos/i18n/fr.ts +150 -0
- package/src/tool/calculadoraTiempoDatos/index.ts +33 -0
- package/src/tool/calculadoraTiempoDatos/seo.astro +14 -0
- package/src/tool/calculadoraTiempoDatos/ui.ts +24 -0
- package/src/tool/colorConverter/bibliography.astro +14 -0
- package/src/tool/colorConverter/component.astro +504 -0
- package/src/tool/colorConverter/i18n/en.ts +126 -0
- package/src/tool/colorConverter/i18n/es.ts +126 -0
- package/src/tool/colorConverter/i18n/fr.ts +126 -0
- package/src/tool/colorConverter/index.ts +33 -0
- package/src/tool/colorConverter/seo.astro +14 -0
- package/src/tool/colorConverter/ui.ts +16 -0
- package/src/tool/conversorExcelCsvHtml/bibliography.astro +14 -0
- package/src/tool/conversorExcelCsvHtml/component.astro +595 -0
- package/src/tool/conversorExcelCsvHtml/i18n/en.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/i18n/es.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/i18n/fr.ts +129 -0
- package/src/tool/conversorExcelCsvHtml/index.ts +33 -0
- package/src/tool/conversorExcelCsvHtml/seo.astro +14 -0
- package/src/tool/conversorExcelCsvHtml/ui.ts +14 -0
- package/src/tool/cronGenerator/bibliography.astro +14 -0
- package/src/tool/cronGenerator/component.astro +667 -0
- package/src/tool/cronGenerator/i18n/en.ts +191 -0
- package/src/tool/cronGenerator/i18n/es.ts +191 -0
- package/src/tool/cronGenerator/i18n/fr.ts +191 -0
- package/src/tool/cronGenerator/index.ts +34 -0
- package/src/tool/cronGenerator/seo.astro +14 -0
- package/src/tool/cronGenerator/ui.ts +45 -0
- package/src/tool/cssSpecificityCalculator/bibliography.astro +14 -0
- package/src/tool/cssSpecificityCalculator/component.astro +292 -0
- package/src/tool/cssSpecificityCalculator/i18n/en.ts +168 -0
- package/src/tool/cssSpecificityCalculator/i18n/es.ts +168 -0
- package/src/tool/cssSpecificityCalculator/i18n/fr.ts +168 -0
- package/src/tool/cssSpecificityCalculator/index.ts +34 -0
- package/src/tool/cssSpecificityCalculator/logic.ts +100 -0
- package/src/tool/cssSpecificityCalculator/seo.astro +14 -0
- package/src/tool/cssSpecificityCalculator/ui-controller.ts +57 -0
- package/src/tool/cssSpecificityCalculator/ui.ts +11 -0
- package/src/tool/cssToInlineConverter/bibliography.astro +14 -0
- package/src/tool/cssToInlineConverter/component.astro +308 -0
- package/src/tool/cssToInlineConverter/i18n/en.ts +160 -0
- package/src/tool/cssToInlineConverter/i18n/es.ts +160 -0
- package/src/tool/cssToInlineConverter/i18n/fr.ts +160 -0
- package/src/tool/cssToInlineConverter/index.ts +34 -0
- package/src/tool/cssToInlineConverter/seo.astro +14 -0
- package/src/tool/cssToInlineConverter/ui.ts +12 -0
- package/src/tool/duplicateCssRemover/bibliography.astro +14 -0
- package/src/tool/duplicateCssRemover/component.astro +353 -0
- package/src/tool/duplicateCssRemover/i18n/en.ts +167 -0
- package/src/tool/duplicateCssRemover/i18n/es.ts +167 -0
- package/src/tool/duplicateCssRemover/i18n/fr.ts +167 -0
- package/src/tool/duplicateCssRemover/index.ts +34 -0
- package/src/tool/duplicateCssRemover/seo.astro +14 -0
- package/src/tool/duplicateCssRemover/ui.ts +12 -0
- package/src/tool/generadorSecurityTxt/bibliography.astro +14 -0
- package/src/tool/generadorSecurityTxt/component.astro +473 -0
- package/src/tool/generadorSecurityTxt/i18n/en.ts +173 -0
- package/src/tool/generadorSecurityTxt/i18n/es.ts +173 -0
- package/src/tool/generadorSecurityTxt/i18n/fr.ts +173 -0
- package/src/tool/generadorSecurityTxt/index.ts +33 -0
- package/src/tool/generadorSecurityTxt/seo.astro +14 -0
- package/src/tool/generadorSecurityTxt/ui.ts +27 -0
- package/src/tool/hashGenerator/bibliography.astro +14 -0
- package/src/tool/hashGenerator/component.astro +367 -0
- package/src/tool/hashGenerator/i18n/en.ts +118 -0
- package/src/tool/hashGenerator/i18n/es.ts +118 -0
- package/src/tool/hashGenerator/i18n/fr.ts +118 -0
- package/src/tool/hashGenerator/index.ts +33 -0
- package/src/tool/hashGenerator/md5.ts +138 -0
- package/src/tool/hashGenerator/seo.astro +14 -0
- package/src/tool/hashGenerator/ui.ts +11 -0
- package/src/tool/inspectorCertificadosSsl/bibliography.astro +14 -0
- package/src/tool/inspectorCertificadosSsl/component.astro +580 -0
- package/src/tool/inspectorCertificadosSsl/i18n/en.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/i18n/es.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/i18n/fr.ts +214 -0
- package/src/tool/inspectorCertificadosSsl/index.ts +33 -0
- package/src/tool/inspectorCertificadosSsl/seo.astro +14 -0
- package/src/tool/inspectorCertificadosSsl/ui.ts +29 -0
- package/src/tool/jsonFormatter/bibliography.astro +14 -0
- package/src/tool/jsonFormatter/component.astro +590 -0
- package/src/tool/jsonFormatter/i18n/en.ts +156 -0
- package/src/tool/jsonFormatter/i18n/es.ts +156 -0
- package/src/tool/jsonFormatter/i18n/fr.ts +156 -0
- package/src/tool/jsonFormatter/index.ts +34 -0
- package/src/tool/jsonFormatter/seo.astro +14 -0
- package/src/tool/jsonFormatter/ui.ts +15 -0
- package/src/tool/keycode/bibliography.astro +14 -0
- package/src/tool/keycode/component.astro +540 -0
- package/src/tool/keycode/i18n/en.ts +160 -0
- package/src/tool/keycode/i18n/es.ts +160 -0
- package/src/tool/keycode/i18n/fr.ts +160 -0
- package/src/tool/keycode/index.ts +34 -0
- package/src/tool/keycode/seo.astro +14 -0
- package/src/tool/keycode/ui.ts +10 -0
- package/src/tool/llmCostCalculator/bibliography.astro +14 -0
- package/src/tool/llmCostCalculator/component.astro +488 -0
- package/src/tool/llmCostCalculator/data.ts +99 -0
- package/src/tool/llmCostCalculator/i18n/en.ts +165 -0
- package/src/tool/llmCostCalculator/i18n/es.ts +165 -0
- package/src/tool/llmCostCalculator/i18n/fr.ts +165 -0
- package/src/tool/llmCostCalculator/index.ts +34 -0
- package/src/tool/llmCostCalculator/seo.astro +14 -0
- package/src/tool/llmCostCalculator/ui.ts +11 -0
- package/src/tool/mobileMockupGenerator/app.ts +614 -0
- package/src/tool/mobileMockupGenerator/bibliography.astro +14 -0
- package/src/tool/mobileMockupGenerator/component.astro +1044 -0
- package/src/tool/mobileMockupGenerator/constants.ts +48 -0
- package/src/tool/mobileMockupGenerator/i18n/en.ts +121 -0
- package/src/tool/mobileMockupGenerator/i18n/es.ts +121 -0
- package/src/tool/mobileMockupGenerator/i18n/fr.ts +121 -0
- package/src/tool/mobileMockupGenerator/index.ts +33 -0
- package/src/tool/mobileMockupGenerator/rendering.ts +189 -0
- package/src/tool/mobileMockupGenerator/seo.astro +14 -0
- package/src/tool/mobileMockupGenerator/store.ts +145 -0
- package/src/tool/mobileMockupGenerator/types.ts +41 -0
- package/src/tool/mobileMockupGenerator/ui.ts +48 -0
- package/src/tool/musicalTypography/bibliography.astro +14 -0
- package/src/tool/musicalTypography/component.astro +480 -0
- package/src/tool/musicalTypography/i18n/en.ts +179 -0
- package/src/tool/musicalTypography/i18n/es.ts +179 -0
- package/src/tool/musicalTypography/i18n/fr.ts +179 -0
- package/src/tool/musicalTypography/index.ts +33 -0
- package/src/tool/musicalTypography/seo.astro +14 -0
- package/src/tool/musicalTypography/ui.ts +25 -0
- package/src/tool/placeholderGenerator/bibliography.astro +14 -0
- package/src/tool/placeholderGenerator/component.astro +499 -0
- package/src/tool/placeholderGenerator/i18n/en.ts +176 -0
- package/src/tool/placeholderGenerator/i18n/es.ts +176 -0
- package/src/tool/placeholderGenerator/i18n/fr.ts +176 -0
- package/src/tool/placeholderGenerator/index.ts +34 -0
- package/src/tool/placeholderGenerator/seo.astro +14 -0
- package/src/tool/placeholderGenerator/ui.ts +14 -0
- package/src/tool/promptLibrary/bibliography.astro +14 -0
- package/src/tool/promptLibrary/component.astro +1131 -0
- package/src/tool/promptLibrary/controller.ts +49 -0
- package/src/tool/promptLibrary/i18n/en.ts +131 -0
- package/src/tool/promptLibrary/i18n/es.ts +131 -0
- package/src/tool/promptLibrary/i18n/fr.ts +126 -0
- package/src/tool/promptLibrary/index.ts +33 -0
- package/src/tool/promptLibrary/seo.astro +14 -0
- package/src/tool/promptLibrary/ui.ts +29 -0
- package/src/tool/readabilityCalculator/bibliography.astro +14 -0
- package/src/tool/readabilityCalculator/component.astro +534 -0
- package/src/tool/readabilityCalculator/i18n/en.ts +133 -0
- package/src/tool/readabilityCalculator/i18n/es.ts +133 -0
- package/src/tool/readabilityCalculator/i18n/fr.ts +133 -0
- package/src/tool/readabilityCalculator/index.ts +33 -0
- package/src/tool/readabilityCalculator/seo.astro +14 -0
- package/src/tool/readabilityCalculator/ui.ts +27 -0
- package/src/tool/svgSanitizer/bibliography.astro +14 -0
- package/src/tool/svgSanitizer/component.astro +554 -0
- package/src/tool/svgSanitizer/i18n/en.ts +125 -0
- package/src/tool/svgSanitizer/i18n/es.ts +125 -0
- package/src/tool/svgSanitizer/i18n/fr.ts +125 -0
- package/src/tool/svgSanitizer/index.ts +33 -0
- package/src/tool/svgSanitizer/seo.astro +14 -0
- package/src/tool/svgSanitizer/ui.ts +18 -0
- package/src/tool/svgToCss/bibliography.astro +14 -0
- package/src/tool/svgToCss/component.astro +381 -0
- package/src/tool/svgToCss/i18n/en.ts +174 -0
- package/src/tool/svgToCss/i18n/es.ts +174 -0
- package/src/tool/svgToCss/i18n/fr.ts +174 -0
- package/src/tool/svgToCss/index.ts +34 -0
- package/src/tool/svgToCss/seo.astro +14 -0
- package/src/tool/svgToCss/ui.ts +13 -0
- package/src/tool/urlCleaner/bibliography.astro +14 -0
- package/src/tool/urlCleaner/component.astro +458 -0
- package/src/tool/urlCleaner/i18n/en.ts +116 -0
- package/src/tool/urlCleaner/i18n/es.ts +116 -0
- package/src/tool/urlCleaner/i18n/fr.ts +116 -0
- package/src/tool/urlCleaner/index.ts +33 -0
- package/src/tool/urlCleaner/seo.astro +14 -0
- package/src/tool/urlCleaner/ui.ts +12 -0
- package/src/tool/urlEncoderDecoder/bibliography.astro +14 -0
- package/src/tool/urlEncoderDecoder/component.astro +291 -0
- package/src/tool/urlEncoderDecoder/i18n/en.ts +162 -0
- package/src/tool/urlEncoderDecoder/i18n/es.ts +162 -0
- package/src/tool/urlEncoderDecoder/i18n/fr.ts +162 -0
- package/src/tool/urlEncoderDecoder/index.ts +34 -0
- package/src/tool/urlEncoderDecoder/seo.astro +14 -0
- package/src/tool/urlEncoderDecoder/ui.ts +11 -0
- package/src/tool/utmGenerator/bibliography.astro +14 -0
- package/src/tool/utmGenerator/component.astro +270 -0
- package/src/tool/utmGenerator/i18n/en.ts +117 -0
- package/src/tool/utmGenerator/i18n/es.ts +117 -0
- package/src/tool/utmGenerator/i18n/fr.ts +117 -0
- package/src/tool/utmGenerator/index.ts +33 -0
- package/src/tool/utmGenerator/seo.astro +14 -0
- package/src/tool/utmGenerator/ui.ts +13 -0
- package/src/tools.ts +27 -0
- package/src/types.ts +72 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
import type { KnownLocale } from '../../types';
|
|
4
|
+
import type { HashGeneratorUI } from './ui';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
ui?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { ui } = Astro.props;
|
|
12
|
+
const t = (ui ?? {}) as HashGeneratorUI;
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<div id="hg-root" data-i18n={JSON.stringify(t)} class="hg-root">
|
|
16
|
+
<div class="hg-card">
|
|
17
|
+
<div class="hg-input-block">
|
|
18
|
+
<div class="hg-field">
|
|
19
|
+
<label for="hg-input" class="hg-label">
|
|
20
|
+
<Icon name="mdi:text-box-outline" class="hg-label-icon" />
|
|
21
|
+
{t.labelInput}
|
|
22
|
+
</label>
|
|
23
|
+
<textarea id="hg-input" class="hg-textarea" spellcheck="false" placeholder={t.placeholderInput}></textarea>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="hg-options-row">
|
|
26
|
+
<div class="hg-option">
|
|
27
|
+
<label for="hg-salt" class="hg-option-label">{t.labelSalt}</label>
|
|
28
|
+
<input type="text" id="hg-salt" class="hg-option-input" placeholder={t.placeholderSalt} />
|
|
29
|
+
</div>
|
|
30
|
+
<div class="hg-option">
|
|
31
|
+
<label for="hg-rounds" class="hg-option-label">{t.labelRounds}</label>
|
|
32
|
+
<input type="number" id="hg-rounds" class="hg-option-input" value="1" min="1" max="1000" />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="hg-divider"></div>
|
|
38
|
+
|
|
39
|
+
<div class="hg-results-block">
|
|
40
|
+
<div class="hg-row">
|
|
41
|
+
<span class="hg-badge">MD5</span>
|
|
42
|
+
<span id="hg-out-md5" class="hg-hash">...</span>
|
|
43
|
+
<button class="hg-copy-btn" data-target="hg-out-md5" title={t.copyMd5}>
|
|
44
|
+
<Icon name="mdi:content-copy" class="hg-copy-icon" />
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="hg-row">
|
|
48
|
+
<span class="hg-badge">SHA-1</span>
|
|
49
|
+
<span id="hg-out-sha1" class="hg-hash">...</span>
|
|
50
|
+
<button class="hg-copy-btn" data-target="hg-out-sha1" title={t.copySha1}>
|
|
51
|
+
<Icon name="mdi:content-copy" class="hg-copy-icon" />
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="hg-row">
|
|
55
|
+
<span class="hg-badge">SHA-256</span>
|
|
56
|
+
<span id="hg-out-sha256" class="hg-hash">...</span>
|
|
57
|
+
<button class="hg-copy-btn" data-target="hg-out-sha256" title={t.copySha256}>
|
|
58
|
+
<Icon name="mdi:content-copy" class="hg-copy-icon" />
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="hg-row">
|
|
62
|
+
<span class="hg-badge">SHA-512</span>
|
|
63
|
+
<span id="hg-out-sha512" class="hg-hash">...</span>
|
|
64
|
+
<button class="hg-copy-btn" data-target="hg-out-sha512" title={t.copySha512}>
|
|
65
|
+
<Icon name="mdi:content-copy" class="hg-copy-icon" />
|
|
66
|
+
</button>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<script>
|
|
73
|
+
import { md5 } from './md5';
|
|
74
|
+
|
|
75
|
+
const input = document.getElementById('hg-input') as HTMLTextAreaElement;
|
|
76
|
+
const saltInput = document.getElementById('hg-salt') as HTMLInputElement;
|
|
77
|
+
const roundsInput = document.getElementById('hg-rounds') as HTMLInputElement;
|
|
78
|
+
|
|
79
|
+
const outputs: Record<string, HTMLElement | null> = {
|
|
80
|
+
md5: document.getElementById('hg-out-md5'),
|
|
81
|
+
sha1: document.getElementById('hg-out-sha1'),
|
|
82
|
+
sha256: document.getElementById('hg-out-sha256'),
|
|
83
|
+
sha512: document.getElementById('hg-out-sha512'),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
async function hashSHA(text: string, algo: 'SHA-1' | 'SHA-256' | 'SHA-512'): Promise<string> {
|
|
87
|
+
const buf = await crypto.subtle.digest(algo, new TextEncoder().encode(text));
|
|
88
|
+
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function clearOutputs() {
|
|
92
|
+
Object.values(outputs).forEach((el) => { if (el) el.textContent = '...'; });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function computeMd5(text: string, rounds: number) {
|
|
96
|
+
let val = text;
|
|
97
|
+
for (let i = 0; i < rounds; i++) val = md5(val);
|
|
98
|
+
return val;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function computeSha(text: string, algo: 'SHA-1' | 'SHA-256' | 'SHA-512', rounds: number) {
|
|
102
|
+
let val = text;
|
|
103
|
+
for (let i = 0; i < rounds; i++) val = await hashSHA(val, algo);
|
|
104
|
+
return val;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function updateHashes() {
|
|
108
|
+
const raw = input.value;
|
|
109
|
+
const salt = saltInput.value;
|
|
110
|
+
const rounds = parseInt(roundsInput.value) || 1;
|
|
111
|
+
if (!raw) { clearOutputs(); return; }
|
|
112
|
+
const text = raw + salt;
|
|
113
|
+
const el = outputs;
|
|
114
|
+
if (el.md5) el.md5.textContent = await computeMd5(text, rounds);
|
|
115
|
+
if (el.sha1) el.sha1.textContent = await computeSha(text, 'SHA-1', rounds);
|
|
116
|
+
if (el.sha256) el.sha256.textContent = await computeSha(text, 'SHA-256', rounds);
|
|
117
|
+
if (el.sha512) el.sha512.textContent = await computeSha(text, 'SHA-512', rounds);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
input.addEventListener('input', updateHashes);
|
|
121
|
+
saltInput.addEventListener('input', updateHashes);
|
|
122
|
+
roundsInput.addEventListener('input', updateHashes);
|
|
123
|
+
|
|
124
|
+
const svgCheck = '<svg width="16" height="16" fill="none" stroke="rgb(34,197,94)" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/></svg>';
|
|
125
|
+
|
|
126
|
+
document.querySelectorAll('.hg-copy-btn').forEach((btn) => {
|
|
127
|
+
btn.addEventListener('click', () => {
|
|
128
|
+
const targetId = (btn as HTMLElement).dataset.target;
|
|
129
|
+
const target = document.getElementById(targetId ?? '');
|
|
130
|
+
if (!target || !target.textContent || target.textContent === '...') return;
|
|
131
|
+
navigator.clipboard.writeText(target.textContent);
|
|
132
|
+
const orig = btn.innerHTML;
|
|
133
|
+
btn.innerHTML = svgCheck;
|
|
134
|
+
setTimeout(() => { btn.innerHTML = orig; }, 2000);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<style>
|
|
140
|
+
.hg-root {
|
|
141
|
+
width: 100%;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.hg-card {
|
|
145
|
+
background: #fff;
|
|
146
|
+
border: 1px solid rgb(226, 232, 240);
|
|
147
|
+
border-radius: 1.5rem;
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:global(.theme-dark) .hg-card {
|
|
152
|
+
background: rgb(15, 23, 42);
|
|
153
|
+
border-color: rgb(30, 41, 59);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.hg-input-block {
|
|
157
|
+
padding: 1.5rem;
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
gap: 1rem;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.hg-field {
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
gap: 0.5rem;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.hg-label {
|
|
170
|
+
display: flex;
|
|
171
|
+
align-items: center;
|
|
172
|
+
gap: 0.5rem;
|
|
173
|
+
font-size: 0.875rem;
|
|
174
|
+
font-weight: 600;
|
|
175
|
+
color: rgb(15, 23, 42);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
:global(.theme-dark) .hg-label {
|
|
179
|
+
color: rgb(226, 232, 240);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.hg-label-icon {
|
|
183
|
+
width: 1rem;
|
|
184
|
+
height: 1rem;
|
|
185
|
+
color: rgb(99, 102, 241);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.hg-textarea {
|
|
189
|
+
width: 100%;
|
|
190
|
+
min-height: 100px;
|
|
191
|
+
padding: 0.75rem 1rem;
|
|
192
|
+
font-size: 0.875rem;
|
|
193
|
+
color: rgb(15, 23, 42);
|
|
194
|
+
background: rgb(248, 250, 252);
|
|
195
|
+
border: 1px solid rgb(226, 232, 240);
|
|
196
|
+
border-radius: 0.75rem;
|
|
197
|
+
resize: vertical;
|
|
198
|
+
transition: border-color 0.2s;
|
|
199
|
+
box-sizing: border-box;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.hg-textarea:focus {
|
|
203
|
+
outline: none;
|
|
204
|
+
border-color: rgb(99, 102, 241);
|
|
205
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
:global(.theme-dark) .hg-textarea {
|
|
209
|
+
background: rgb(30, 41, 59);
|
|
210
|
+
border-color: rgb(51, 65, 85);
|
|
211
|
+
color: rgb(226, 232, 240);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.hg-options-row {
|
|
215
|
+
display: grid;
|
|
216
|
+
grid-template-columns: 1fr 1fr;
|
|
217
|
+
gap: 0.75rem;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.hg-option {
|
|
221
|
+
display: flex;
|
|
222
|
+
flex-direction: column;
|
|
223
|
+
gap: 0.25rem;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.hg-option-label {
|
|
227
|
+
font-size: 0.75rem;
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
color: rgb(100, 116, 139);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.hg-option-input {
|
|
233
|
+
width: 100%;
|
|
234
|
+
padding: 0.5rem 0.75rem;
|
|
235
|
+
font-size: 0.8125rem;
|
|
236
|
+
color: rgb(15, 23, 42);
|
|
237
|
+
background: rgb(248, 250, 252);
|
|
238
|
+
border: 1px solid rgb(226, 232, 240);
|
|
239
|
+
border-radius: 0.5rem;
|
|
240
|
+
transition: border-color 0.2s;
|
|
241
|
+
box-sizing: border-box;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.hg-option-input:focus {
|
|
245
|
+
outline: none;
|
|
246
|
+
border-color: rgb(99, 102, 241);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
:global(.theme-dark) .hg-option-input {
|
|
250
|
+
background: rgb(30, 41, 59);
|
|
251
|
+
border-color: rgb(51, 65, 85);
|
|
252
|
+
color: rgb(226, 232, 240);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.hg-divider {
|
|
256
|
+
height: 1px;
|
|
257
|
+
background: rgb(226, 232, 240);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
:global(.theme-dark) .hg-divider {
|
|
261
|
+
background: rgb(30, 41, 59);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.hg-results-block {
|
|
265
|
+
display: flex;
|
|
266
|
+
flex-direction: column;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.hg-row {
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
gap: 0.75rem;
|
|
273
|
+
padding: 0.75rem 1.5rem;
|
|
274
|
+
border-bottom: 1px solid rgb(241, 245, 249);
|
|
275
|
+
transition: background 0.15s;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.hg-row:last-child {
|
|
279
|
+
border-bottom: none;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.hg-row:hover {
|
|
283
|
+
background: rgb(248, 250, 252);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
:global(.theme-dark) .hg-row {
|
|
287
|
+
border-bottom-color: rgb(30, 41, 59);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
:global(.theme-dark) .hg-row:hover {
|
|
291
|
+
background: rgb(30, 41, 59);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.hg-badge {
|
|
295
|
+
flex-shrink: 0;
|
|
296
|
+
width: 4.5rem;
|
|
297
|
+
text-align: center;
|
|
298
|
+
padding: 0.125rem 0;
|
|
299
|
+
font-size: 0.6875rem;
|
|
300
|
+
font-weight: 700;
|
|
301
|
+
color: rgb(99, 102, 241);
|
|
302
|
+
background: rgba(99, 102, 241, 0.1);
|
|
303
|
+
border-radius: 9999px;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.hg-hash {
|
|
307
|
+
flex: 1;
|
|
308
|
+
font-size: 0.75rem;
|
|
309
|
+
color: rgb(71, 85, 105);
|
|
310
|
+
word-break: break-all;
|
|
311
|
+
line-height: 1.4;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
:global(.theme-dark) .hg-hash {
|
|
315
|
+
color: rgb(148, 163, 184);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.hg-copy-btn {
|
|
319
|
+
flex-shrink: 0;
|
|
320
|
+
display: flex;
|
|
321
|
+
align-items: center;
|
|
322
|
+
justify-content: center;
|
|
323
|
+
width: 1.75rem;
|
|
324
|
+
height: 1.75rem;
|
|
325
|
+
background: transparent;
|
|
326
|
+
border: 1px solid rgb(226, 232, 240);
|
|
327
|
+
border-radius: 0.375rem;
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
color: rgb(148, 163, 184);
|
|
330
|
+
transition: all 0.15s;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.hg-copy-btn:hover {
|
|
334
|
+
background: rgb(241, 245, 249);
|
|
335
|
+
color: rgb(99, 102, 241);
|
|
336
|
+
border-color: rgb(99, 102, 241);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.hg-copy-btn:active {
|
|
340
|
+
transform: scale(0.92);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
:global(.theme-dark) .hg-copy-btn {
|
|
344
|
+
border-color: rgb(51, 65, 85);
|
|
345
|
+
color: rgb(100, 116, 139);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
:global(.theme-dark) .hg-copy-btn:hover {
|
|
349
|
+
background: rgb(51, 65, 85);
|
|
350
|
+
color: rgb(99, 102, 241);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.hg-copy-icon {
|
|
354
|
+
width: 0.875rem;
|
|
355
|
+
height: 0.875rem;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
@media (max-width: 480px) {
|
|
359
|
+
.hg-options-row {
|
|
360
|
+
grid-template-columns: 1fr;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.hg-row {
|
|
364
|
+
padding: 0.625rem 1rem;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
</style>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { HashGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'hash-generator';
|
|
6
|
+
const title = 'Online Security Hash Generator';
|
|
7
|
+
const description = 'Calculate MD5, SHA-1, SHA-256 and SHA-512 hashes instantly. Free, private and ultra-fast security tool for developers. 100% Client-Side.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: 'What is a hash and what is it used for?',
|
|
12
|
+
answer: 'A hash is a unique digital fingerprint of a text or file. It is used to verify that data has not been tampered with and to store passwords securely.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Is it safe to use this online generator?',
|
|
16
|
+
answer: 'Yes, it is completely safe. Unlike other sites, we process the hash directly in your browser. Your data is never sent to any server.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Which hash algorithm should I choose?',
|
|
20
|
+
answer: 'For modern security and key storage, we recommend SHA-256 or SHA-512. MD5 and SHA-1 should only be used for compatibility with legacy systems.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
question: "What does adding a 'Salt' mean?",
|
|
24
|
+
answer: 'A Salt is an extra string mixed with your text to make the hash unique and much harder to crack through dictionary attacks.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const howToData = [
|
|
29
|
+
{ name: 'Enter Text', text: 'Type or paste the text you want to hash into the input box.' },
|
|
30
|
+
{ name: 'Configure Security', text: 'Add an optional Salt or increase processing rounds for greater robustness.' },
|
|
31
|
+
{ name: 'Get Results', text: 'The different hashes (MD5, SHA etc.) are calculated in real time as you type.' },
|
|
32
|
+
{ name: 'Copy the Hash', text: 'Click the copy icon next to each algorithm to save it to your clipboard.' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
36
|
+
'@context': 'https://schema.org',
|
|
37
|
+
'@type': 'FAQPage',
|
|
38
|
+
mainEntity: faqData.map((item) => ({
|
|
39
|
+
'@type': 'Question',
|
|
40
|
+
name: item.question,
|
|
41
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
42
|
+
})),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
46
|
+
'@context': 'https://schema.org',
|
|
47
|
+
'@type': 'HowTo',
|
|
48
|
+
name: title,
|
|
49
|
+
description,
|
|
50
|
+
step: howToData.map((s, i) => ({ '@type': 'HowToStep', position: i + 1, name: s.name, text: s.text })),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'SoftwareApplication',
|
|
56
|
+
name: title,
|
|
57
|
+
description,
|
|
58
|
+
applicationCategory: 'UtilityApplication',
|
|
59
|
+
operatingSystem: 'All',
|
|
60
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
61
|
+
inLanguage: 'en',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const ui: HashGeneratorUI = {
|
|
65
|
+
labelInput: 'Input text',
|
|
66
|
+
placeholderInput: 'Type or paste text here to calculate its hashes...',
|
|
67
|
+
labelSalt: 'Salt (Optional)',
|
|
68
|
+
placeholderSalt: 'Security seed...',
|
|
69
|
+
labelRounds: 'Rounds (Stretch)',
|
|
70
|
+
copyMd5: 'Copy MD5',
|
|
71
|
+
copySha1: 'Copy SHA-1',
|
|
72
|
+
copySha256: 'Copy SHA-256',
|
|
73
|
+
copySha512: 'Copy SHA-512',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const content: ToolLocaleContent<HashGeneratorUI> = {
|
|
77
|
+
slug,
|
|
78
|
+
title,
|
|
79
|
+
description,
|
|
80
|
+
ui,
|
|
81
|
+
faqTitle: 'Frequently Asked Questions',
|
|
82
|
+
faq: faqData,
|
|
83
|
+
bibliographyTitle: 'Technical Resources on Hashing',
|
|
84
|
+
bibliography: [
|
|
85
|
+
{ name: 'MDN Web Docs: SubtleCrypto.digest() API', url: 'https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest' },
|
|
86
|
+
{ name: 'NIST: FIPS 180-4 Secure Hash Standard (SHA)', url: 'https://csrc.nist.gov/publications/detail/fips/180/4/final' },
|
|
87
|
+
{ name: 'IETF: The MD5 Message-Digest Algorithm (RFC 1321)', url: 'https://datatracker.ietf.org/doc/html/rfc1321' },
|
|
88
|
+
],
|
|
89
|
+
howTo: howToData,
|
|
90
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
91
|
+
seo: [
|
|
92
|
+
{ type: 'title', text: 'What is a Cryptographic Hash?', level: 2 },
|
|
93
|
+
{
|
|
94
|
+
type: 'paragraph',
|
|
95
|
+
html: 'A <strong>cryptographic hash</strong> is a mathematical function that transforms any amount of data into a fixed-length string. The same input always produces the same output, but any minimal change in the input generates a completely different hash.',
|
|
96
|
+
},
|
|
97
|
+
{ type: 'title', text: 'Available algorithms', level: 3 },
|
|
98
|
+
{
|
|
99
|
+
type: 'list',
|
|
100
|
+
items: [
|
|
101
|
+
'<strong>MD5 (128 bits):</strong> Fast and widely supported. Considered insecure for passwords but useful for file integrity checks in non-critical environments.',
|
|
102
|
+
'<strong>SHA-1 (160 bits):</strong> Deprecated for critical security uses since 2017. Still present in legacy systems.',
|
|
103
|
+
'<strong>SHA-256 (256 bits):</strong> The current standard for most applications. Used in Bitcoin, TLS and code signing.',
|
|
104
|
+
'<strong>SHA-512 (512 bits):</strong> Longer variant of SHA-2, ideal when maximum collision resistance is required.',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{ type: 'title', text: 'Salt and Key Stretching', level: 3 },
|
|
108
|
+
{
|
|
109
|
+
type: 'paragraph',
|
|
110
|
+
html: 'The <strong>Salt</strong> is a random string added to the text before hashing, ensuring that two identical inputs produce different hashes. <strong>Key Stretching</strong> (rounds) applies the hash function multiple times to harden against brute-force attacks.',
|
|
111
|
+
},
|
|
112
|
+
{ type: 'title', text: 'Total privacy: 100% Client-Side', level: 3 },
|
|
113
|
+
{
|
|
114
|
+
type: 'paragraph',
|
|
115
|
+
html: 'This tool uses the browser\'s <strong>Web Crypto API</strong> for SHA and a pure TypeScript implementation for MD5. All processing happens locally: your data never leaves your device.',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { HashGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'generador-hashes-seguridad';
|
|
6
|
+
const title = 'Generador de Hashes de Seguridad Online';
|
|
7
|
+
const description = 'Calcula hashes MD5, SHA-1, SHA-256 y SHA-512 al instante. Herramienta de seguridad gratuita, privada y ultra rápida para desarrolladores. 100% Client-Side.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: '\u00bfQu\u00e9 es un hash y para qu\u00e9 sirve?',
|
|
12
|
+
answer: 'Un hash es una huella digital \u00fanica de un texto o archivo. Sirve para verificar que los datos no han sido alterados y para almacenar contrase\u00f1as de forma segura.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: '\u00bfEs seguro usar este generador online?',
|
|
16
|
+
answer: 'S\u00ed, es totalmente seguro. A diferencia de otras webs, procesamos el hash directamente en tu navegador. Tus datos nunca se env\u00edan a ning\u00fan servidor.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: '\u00bfQu\u00e9 algoritmo de hash deber\u00eda elegir?',
|
|
20
|
+
answer: 'Para seguridad moderna y almacenamiento de claves, te recomendamos SHA-256 o SHA-512. MD5 y SHA-1 solo deben usarse por compatibilidad con sistemas antiguos.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
question: '\u00bfQu\u00e9 significa a\u00f1adir un Salt?',
|
|
24
|
+
answer: 'Un Salt es una cadena extra que se mezcla con tu texto para hacer que el hash sea \u00fanico y mucho m\u00e1s dif\u00edcil de descifrar mediante ataques de diccionario.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const howToData = [
|
|
29
|
+
{ name: 'Introducir Texto', text: 'Escribe o pega el texto que quieres cifrar en el cuadro de entrada.' },
|
|
30
|
+
{ name: 'Configurar Seguridad', text: 'A\u00f1ade un Salt opcional o aumenta las rondas de procesamiento para mayor robustez.' },
|
|
31
|
+
{ name: 'Obtener Resultados', text: 'Los diferentes hashes (MD5, SHA etc.) se calculan en tiempo real mientras escribes.' },
|
|
32
|
+
{ name: 'Copiar el Hash', text: 'Haz clic en el icono de copiar situado junto a cada algoritmo para guardarlo en tu portapapeles.' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
36
|
+
'@context': 'https://schema.org',
|
|
37
|
+
'@type': 'FAQPage',
|
|
38
|
+
mainEntity: faqData.map((item) => ({
|
|
39
|
+
'@type': 'Question',
|
|
40
|
+
name: item.question,
|
|
41
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
42
|
+
})),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const howToSchema: WithContext<HowToThing> = {
|
|
46
|
+
'@context': 'https://schema.org',
|
|
47
|
+
'@type': 'HowTo',
|
|
48
|
+
name: title,
|
|
49
|
+
description,
|
|
50
|
+
step: howToData.map((s, i) => ({ '@type': 'HowToStep', position: i + 1, name: s.name, text: s.text })),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'SoftwareApplication',
|
|
56
|
+
name: title,
|
|
57
|
+
description,
|
|
58
|
+
applicationCategory: 'UtilityApplication',
|
|
59
|
+
operatingSystem: 'All',
|
|
60
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
61
|
+
inLanguage: 'es',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const ui: HashGeneratorUI = {
|
|
65
|
+
labelInput: 'Texto de entrada',
|
|
66
|
+
placeholderInput: 'Escribe o pega aqu\u00ed el texto para calcular sus hashes...',
|
|
67
|
+
labelSalt: 'Salt (Opcional)',
|
|
68
|
+
placeholderSalt: 'Semilla de seguridad...',
|
|
69
|
+
labelRounds: 'Rondas (Stretch)',
|
|
70
|
+
copyMd5: 'Copiar MD5',
|
|
71
|
+
copySha1: 'Copiar SHA-1',
|
|
72
|
+
copySha256: 'Copiar SHA-256',
|
|
73
|
+
copySha512: 'Copiar SHA-512',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const content: ToolLocaleContent<HashGeneratorUI> = {
|
|
77
|
+
slug,
|
|
78
|
+
title,
|
|
79
|
+
description,
|
|
80
|
+
ui,
|
|
81
|
+
faqTitle: 'Preguntas Frecuentes',
|
|
82
|
+
faq: faqData,
|
|
83
|
+
bibliographyTitle: 'Recursos T\u00e9cnicos sobre Hashing',
|
|
84
|
+
bibliography: [
|
|
85
|
+
{ name: 'MDN Web Docs: SubtleCrypto.digest() API', url: 'https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest' },
|
|
86
|
+
{ name: 'NIST: FIPS 180-4 Secure Hash Standard (SHA)', url: 'https://csrc.nist.gov/publications/detail/fips/180/4/final' },
|
|
87
|
+
{ name: 'IETF: The MD5 Message-Digest Algorithm (RFC 1321)', url: 'https://datatracker.ietf.org/doc/html/rfc1321' },
|
|
88
|
+
],
|
|
89
|
+
howTo: howToData,
|
|
90
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
91
|
+
seo: [
|
|
92
|
+
{ type: 'title', text: '\u00bfQu\u00e9 es un Hash Criptogr\u00e1fico?', level: 2 },
|
|
93
|
+
{
|
|
94
|
+
type: 'paragraph',
|
|
95
|
+
html: 'Un <strong>hash criptogr\u00e1fico</strong> es una funci\u00f3n matem\u00e1tica que transforma cualquier cantidad de datos en una cadena de longitud fija. La misma entrada siempre produce el mismo resultado, pero cualquier m\u00ednimo cambio en la entrada genera un hash completamente diferente.',
|
|
96
|
+
},
|
|
97
|
+
{ type: 'title', text: 'Algoritmos disponibles', level: 3 },
|
|
98
|
+
{
|
|
99
|
+
type: 'list',
|
|
100
|
+
items: [
|
|
101
|
+
'<strong>MD5 (128 bits):</strong> R\u00e1pido y ampliamente soportado. Considerado inseguro para contrase\u00f1as pero \u00fatil para verificar integridad de archivos en entornos no cr\u00edticos.',
|
|
102
|
+
'<strong>SHA-1 (160 bits):</strong> Deprecado para usos cr\u00edticos de seguridad desde 2017. A\u00fan presente en sistemas heredados.',
|
|
103
|
+
'<strong>SHA-256 (256 bits):</strong> El est\u00e1ndar actual para la mayor\u00eda de aplicaciones. Usado en Bitcoin, TLS y firmado de c\u00f3digo.',
|
|
104
|
+
'<strong>SHA-512 (512 bits):</strong> Variante de mayor longitud de SHA-2, ideal cuando se requiere m\u00e1xima resistencia a colisiones.',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{ type: 'title', text: 'Salt y Key Stretching', level: 3 },
|
|
108
|
+
{
|
|
109
|
+
type: 'paragraph',
|
|
110
|
+
html: 'El <strong>Salt</strong> es una cadena aleatoria que se a\u00f1ade al texto antes de calcular el hash, garantizando que dos entradas id\u00e9nticas produzcan hashes distintos. El <strong>Key Stretching</strong> (rondas) aplica la funci\u00f3n hash m\u00faltiples veces para dificultar los ataques de fuerza bruta.',
|
|
111
|
+
},
|
|
112
|
+
{ type: 'title', text: 'Privacidad total: 100% Client-Side', level: 3 },
|
|
113
|
+
{
|
|
114
|
+
type: 'paragraph',
|
|
115
|
+
html: 'Esta herramienta utiliza la <strong>Web Crypto API</strong> del navegador para SHA y una implementaci\u00f3n pura de TypeScript para MD5. Todo el procesamiento ocurre localmente: tus datos nunca abandonan tu dispositivo.',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|