Skip to content

Commit 615f4ab

Browse files
authored
Merge pull request #11 from DMVMarcio/10-hash-generator
feat: Add Hash Generator tool with multiple hashing algorithms support
2 parents 49528c1 + 274f39d commit 615f4ab

File tree

10 files changed

+235
-13
lines changed

10 files changed

+235
-13
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<script lang="ts" setup>
2+
import type { WorkerArgs } from '@zyrohub/toolkit';
3+
import { z } from 'zod';
4+
5+
const { t } = useI18n();
6+
7+
const task = useTask({ worker_id: 'hash_generator' });
8+
9+
const outputContent = computed(() => task.task.value?.data?.hash);
10+
11+
const form = useForm(
12+
{
13+
text: '',
14+
algorithm: 'md5' as WorkerArgs<'hash_generator'>['algorithm']
15+
},
16+
z.object({
17+
text: z.string().min(1).max(2048)
18+
})
19+
);
20+
21+
const algorithmOptions = [
22+
{ label: 'MD4', value: 'md4' },
23+
{ label: 'MD5', value: 'md5' },
24+
25+
{ label: 'SHA-1', value: 'sha1' },
26+
{ label: 'SHA-224', value: 'sha224' },
27+
{ label: 'SHA-256', value: 'sha256' },
28+
{ label: 'SHA-384', value: 'sha384' },
29+
{ label: 'SHA-512', value: 'sha512' },
30+
31+
{ label: 'SHA-512/224', value: 'sha512-224' },
32+
{ label: 'SHA-512/256', value: 'sha512-256' },
33+
34+
{ label: 'SHA3-224', value: 'sha3-224' },
35+
{ label: 'SHA3-256', value: 'sha3-256' },
36+
{ label: 'SHA3-384', value: 'sha3-384' },
37+
{ label: 'SHA3-512', value: 'sha3-512' }
38+
];
39+
40+
const isSubmittable = computed(() => form.isValid.value && task.isSubmittable.value);
41+
42+
const handleExecute = async () => {
43+
await task.start({
44+
text: form.values.value.text,
45+
algorithm: form.values.value.algorithm
46+
});
47+
};
48+
</script>
49+
50+
<template>
51+
<div class="flex flex-col gap-4">
52+
<InputsProvider :form="form">
53+
<div class="flex flex-col gap-4">
54+
<InputsText
55+
name="text"
56+
:label="t('components.tools.hash_generator.text.label')"
57+
:placeholder="t('components.tools.hash_generator.text.placeholder')" />
58+
59+
<div class="flex items-end gap-4">
60+
<InputsSelect
61+
name="algorithm"
62+
:label="t('components.tools.hash_generator.algorithm')"
63+
class="max-w-32"
64+
:options="algorithmOptions" />
65+
66+
<Button @click="handleExecute" theme="primary" :disabled="!isSubmittable">
67+
{{ t('components.tools.hash_generator.generate') }}
68+
</Button>
69+
</div>
70+
</div>
71+
</InputsProvider>
72+
73+
<ToolkitToolProgress :task="task.task.value" />
74+
75+
<InputsText
76+
v-model="outputContent"
77+
:label="t('components.tools.hash_generator.output.label')"
78+
:placeholder="t('components.tools.hash_generator.output.placeholder')"
79+
readonly
80+
showCopy />
81+
</div>
82+
</template>

apps/client/components/tools/UuidGenerator.vue

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ import { v1, v3, v4, v5, v6, v7 } from 'uuid';
44
const { t } = useI18n();
55
66
const form = useForm({
7-
version: '1',
7+
version: '4',
88
name: '',
99
1010
output: ''
1111
});
1212
13+
const uuidOptions = [
14+
{ label: 'UUID v1', value: '1' },
15+
{ label: 'UUID v3', value: '3' },
16+
{ label: 'UUID v4', value: '4' },
17+
{ label: 'UUID v5', value: '5' },
18+
{ label: 'UUID v6', value: '6' },
19+
{ label: 'UUID v7', value: '7' }
20+
];
21+
1322
const handleGenerate = async () => {
1423
switch (form.values.value.version) {
1524
case '1':
@@ -42,14 +51,7 @@ const handleGenerate = async () => {
4251
name="version"
4352
:label="t('components.tools.uuid_generator.version')"
4453
class="max-w-32"
45-
:options="[
46-
{ label: 'UUID v1', value: '1' },
47-
{ label: 'UUID v3', value: '3' },
48-
{ label: 'UUID v4', value: '4' },
49-
{ label: 'UUID v5', value: '5' },
50-
{ label: 'UUID v6', value: '6' },
51-
{ label: 'UUID v7', value: '7' }
52-
]" />
54+
:options="uuidOptions" />
5355

5456
<InputsText
5557
v-if="['3', '5'].includes(form.values.value.version)"

apps/client/composables/useForm.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ export const useForm = <T>(initialValues: T, validateSchema?: z.Schema) => {
1414
if (result.success) {
1515
errors.value = {};
1616
} else {
17-
errors.value = result.error.errors.reduce((acc, error) => {
18-
acc[error.path[0] as keyof T] = error.message;
19-
return acc;
20-
}, {} as Record<keyof T, string>);
17+
errors.value = result.error.errors.reduce(
18+
(acc, error) => {
19+
acc[error.path[0] as keyof T] = error.message;
20+
return acc;
21+
},
22+
{} as Record<keyof T, string>
23+
);
2124
}
2225

2326
return result.success;

apps/client/i18n/locales/en-US.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ export default {
129129
invalid: 'INVALID MATCH'
130130
}
131131
},
132+
hash_generator: {
133+
input: {
134+
label: 'Text',
135+
placeholder: 'Type your text here...'
136+
},
137+
algorithm: 'Algorithm',
138+
generate: 'Generate Hash',
139+
output: {
140+
label: 'Hash Text',
141+
placeholder: 'Text generated hash...'
142+
}
143+
},
132144
image_converter: {
133145
upload: 'Select a File',
134146
bulk: {
@@ -267,6 +279,11 @@ We hope this is clear, and as mentioned earlier, if there is something that you
267279
name: 'Bcrypt Checker',
268280
description: 'Check if a password matches a bcrypt hash.'
269281
},
282+
hash_generator: {
283+
name: 'Hash Generator',
284+
description:
285+
'Generate text hashes using different hashing algorithms. (MD5, SHA1, SHA256, SHA512, and others...)'
286+
},
270287
image_converter: {
271288
name: 'Image Converter',
272289
description: 'Convert images to different formats. (WebP, PNG, JPG and JPEG)'

apps/client/i18n/locales/es-ES.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ export default {
130130
invalid: 'NO COINCIDE'
131131
}
132132
},
133+
hash_generator: {
134+
input: {
135+
label: 'Texto',
136+
placeholder: 'Escriba su texto aquí...'
137+
},
138+
algorithm: 'Algoritmo',
139+
generate: 'Generar Hash',
140+
output: {
141+
label: 'Hash Generado',
142+
placeholder: 'Hash generado...'
143+
}
144+
},
133145
image_converter: {
134146
upload: 'Seleccione un Archivo',
135147
bulk: {
@@ -268,6 +280,11 @@ Esperamos que esto sea claro, y como se mencionó anteriormente, si hay algo de
268280
name: 'Verificador Bcrypt',
269281
description: 'Verificar si una contraseña coincide con un hash bcrypt.'
270282
},
283+
hash_generator: {
284+
name: 'Generador de Hash',
285+
description:
286+
'Generar hashes de textos utilizando diferentes algoritmos de hash. (MD5, SHA1, SHA256, SHA512, entre otros...)'
287+
},
271288
image_converter: {
272289
name: 'Convertidor de Imágenes',
273290
description: 'Convertir imágenes a diferentes formatos. (WebP, PNG, JPG y JPEG)'

apps/client/i18n/locales/pt-BR.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ export default {
130130
invalid: 'NÃO CORRESPONDEM'
131131
}
132132
},
133+
hash_generator: {
134+
text: {
135+
label: 'Texto',
136+
placeholder: 'Digite seu texto aqui...'
137+
},
138+
algorithm: 'Algoritmo',
139+
generate: 'Gerar Hash',
140+
output: {
141+
label: 'Hash Gerado',
142+
placeholder: 'Hash gerado...'
143+
}
144+
},
133145
image_converter: {
134146
upload: 'Selecione um Arquivo',
135147
bulk: {
@@ -268,6 +280,11 @@ Esperemos que esteja esclarecido e, como mencionado anteriormente, se houver alg
268280
name: 'Verificador Bcrypt',
269281
description: 'Verifique se uma senha corresponde a um hash bcrypt.'
270282
},
283+
hash_generator: {
284+
name: 'Gerador de Hash',
285+
description:
286+
'Gere hash de textos utilizando diferentes algoritmos de hash. (MD5, SHA1, SHA256, SHA512, entre outros...)'
287+
},
271288
image_converter: {
272289
name: 'Conversor de Imagens',
273290
description: 'Converta imagens para diferentes formatos diferentes. (WebP, PNG, JPG e JPEG)'

apps/client/shared/tools.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ export const getToolList = (): ITool[] => {
2828
tags: [ToolTagEnum.DEV, ToolTagEnum.CRYPTO, ToolTagEnum.VALIDATOR, ToolTagEnum.PASSWORD, ToolTagEnum.HASH],
2929
needs_connection: true
3030
},
31+
{
32+
id: 'hash_generator',
33+
icon: 'mynaui:hash-square-solid',
34+
related: [],
35+
tags: [
36+
ToolTagEnum.DEV,
37+
ToolTagEnum.TEXT,
38+
ToolTagEnum.CRYPTO,
39+
ToolTagEnum.GENERATOR,
40+
ToolTagEnum.HASH,
41+
ToolTagEnum.CONVERTER,
42+
ToolTagEnum.ENCODER
43+
],
44+
needs_connection: true
45+
},
3146
{
3247
id: 'image_converter',
3348
icon: 'mdi:image',
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { WorkerArgs, WorkerResponse } from '@zyrohub/toolkit';
2+
3+
import { BaseWorker, BaseWorkerProgress } from './Base.js';
4+
5+
export class HashGeneratorWorker extends BaseWorker {
6+
static async execute<T extends 'hash_generator'>(
7+
data: WorkerArgs<T>,
8+
update_progress: BaseWorkerProgress
9+
): Promise<WorkerResponse<T>> {
10+
const text = data.text;
11+
const algorithm = data.algorithm;
12+
13+
if (
14+
[
15+
'md4',
16+
'md5',
17+
'sha1',
18+
'sha224',
19+
'sha256',
20+
'sha384',
21+
'sha512',
22+
'sha512-224',
23+
'sha512-256',
24+
'sha3-224',
25+
'sha3-256',
26+
'sha3-384',
27+
'sha3-512'
28+
].includes(algorithm)
29+
) {
30+
const hasher = new Bun.CryptoHasher(algorithm);
31+
hasher.update(text);
32+
33+
const hash = hasher.digest('hex');
34+
return { hash };
35+
}
36+
37+
return { hash: '' };
38+
}
39+
}

apps/workers/src/workers/workers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import { BaseWorker } from './Base.js';
44

55
import { BcryptGeneratorWorker } from './BcryptGenerator.js';
66
import { BcryptCheckerWorker } from './BcryptChecker.js';
7+
8+
import { HashGeneratorWorker } from './HashGenerator.js';
9+
710
import { ImageConverterWorker } from './ImageConverter.js';
811

912
export const workers: Record<WorkerId, typeof BaseWorker> = {
1013
bcrypt_generator: BcryptGeneratorWorker,
1114
bcrypt_checker: BcryptCheckerWorker,
15+
hash_generator: HashGeneratorWorker,
1216
image_converter: ImageConverterWorker
1317
};

packages/toolkit/src/schemas/workers.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,32 @@ export const workersSchemas = {
2323
storage: z.object({}),
2424
errors: [] as string[]
2525
},
26+
hash_generator: {
27+
args: z.object({
28+
text: z.string().min(1).max(2048),
29+
algorithm: z.enum([
30+
'md4',
31+
'md5',
32+
33+
'sha1',
34+
'sha224',
35+
'sha256',
36+
'sha384',
37+
'sha512',
38+
'sha512-224',
39+
'sha512-256',
40+
'sha3-224',
41+
'sha3-256',
42+
'sha3-384',
43+
'sha3-512'
44+
])
45+
}),
46+
response: z.object({
47+
hash: z.string()
48+
}),
49+
storage: z.object({}),
50+
errors: [] as string[]
51+
},
2652
image_converter: {
2753
args: z.object({
2854
image: z.string(),

0 commit comments

Comments
 (0)