mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 21:37:11 -04:00
feat(Hash Text): more hashing methods
Added ADLER32, BLAKE2B, BLAKE2S, BLAKE3, CRC32, CRC32C, KECCAK, PBKDF2, SM3, WHIRLPOOL, XXHASH128, XXHASH3, XXHASH32, XXHASH64, Argon2, Argon2i, Argon2d, Argon2id Fix #728 and #641 and #362
This commit is contained in:
parent
d3b32cc14e
commit
2816ed254a
5 changed files with 225 additions and 11 deletions
|
@ -61,6 +61,7 @@
|
|||
"figlet": "^1.7.0",
|
||||
"figue": "^1.2.0",
|
||||
"fuse.js": "^6.6.2",
|
||||
"hash-wasm": "^4.11.0",
|
||||
"highlight.js": "^11.7.0",
|
||||
"iarna-toml-esm": "^3.0.5",
|
||||
"ibantools": "^4.3.3",
|
||||
|
|
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
|
@ -83,6 +83,9 @@ dependencies:
|
|||
fuse.js:
|
||||
specifier: ^6.6.2
|
||||
version: 6.6.2
|
||||
hash-wasm:
|
||||
specifier: ^4.11.0
|
||||
version: 4.11.0
|
||||
highlight.js:
|
||||
specifier: ^11.7.0
|
||||
version: 11.7.0
|
||||
|
@ -3351,7 +3354,7 @@ packages:
|
|||
dependencies:
|
||||
'@unhead/dom': 0.5.1
|
||||
'@unhead/schema': 0.5.1
|
||||
'@vueuse/shared': 10.7.2(vue@3.3.4)
|
||||
'@vueuse/shared': 10.9.0(vue@3.3.4)
|
||||
unhead: 0.5.1
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
|
@ -3993,10 +3996,10 @@ packages:
|
|||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@10.7.2(vue@3.3.4):
|
||||
resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==}
|
||||
/@vueuse/shared@10.9.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.6(vue@3.3.4)
|
||||
vue-demi: 0.14.7(vue@3.3.4)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
|
@ -5969,6 +5972,10 @@ packages:
|
|||
function-bind: 1.1.2
|
||||
dev: true
|
||||
|
||||
/hash-wasm@4.11.0:
|
||||
resolution: {integrity: sha512-HVusNXlVqHe0fzIzdQOGolnFN6mX/fqcrSAOcTBXdvzrXVHwTz11vXeKRmkR5gTuwVpvHZEIyKoePDvuAR+XwQ==}
|
||||
dev: false
|
||||
|
||||
/hasown@2.0.0:
|
||||
resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -9151,8 +9158,8 @@ packages:
|
|||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/vue-demi@0.14.6(vue@3.3.4):
|
||||
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
|
||||
/vue-demi@0.14.7(vue@3.3.4):
|
||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useRouteQuery } from '@vueuse/router';
|
||||
import { computed } from 'vue';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
|
||||
export { useQueryParam };
|
||||
export { useQueryParam, useQueryParamOrStorage };
|
||||
|
||||
const transformers = {
|
||||
number: {
|
||||
|
@ -33,3 +34,31 @@ function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue:
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
function useQueryParamOrStorage<T>({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue?: T }) {
|
||||
const type = typeof defaultValue;
|
||||
const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;
|
||||
|
||||
const storageRef = useStorage(storageName, defaultValue);
|
||||
const storageDefaultValue = storageRef.value ?? defaultValue;
|
||||
|
||||
const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never));
|
||||
|
||||
const ref = computed<T>({
|
||||
get() {
|
||||
return transformer.fromQuery(proxy.value) as unknown as T;
|
||||
},
|
||||
set(value) {
|
||||
proxy.value = transformer.toQuery(value as never);
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
ref,
|
||||
(newValue) => {
|
||||
storageRef.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,30 @@
|
|||
import type { lib } from 'crypto-js';
|
||||
import { MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA3, SHA384, SHA512, enc } from 'crypto-js';
|
||||
|
||||
import {
|
||||
adler32,
|
||||
argon2d,
|
||||
argon2i,
|
||||
argon2id,
|
||||
blake2b,
|
||||
blake2s,
|
||||
blake3,
|
||||
crc32,
|
||||
crc32c,
|
||||
createSHA256,
|
||||
keccak,
|
||||
pbkdf2,
|
||||
sm3,
|
||||
whirlpool,
|
||||
xxhash128,
|
||||
xxhash3,
|
||||
xxhash32,
|
||||
xxhash64,
|
||||
} from 'hash-wasm';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import { convertHexToBin } from './hash-text.service';
|
||||
import { useQueryParam } from '@/composable/queryParams';
|
||||
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||
|
||||
const algos = {
|
||||
MD5,
|
||||
|
@ -20,7 +41,27 @@ const algos = {
|
|||
type AlgoNames = keyof typeof algos;
|
||||
type Encoding = keyof typeof enc | 'Bin';
|
||||
const algoNames = Object.keys(algos) as AlgoNames[];
|
||||
const encoding = useQueryParam<Encoding>({ defaultValue: 'Hex', name: 'encoding' });
|
||||
|
||||
const algosWasm = {
|
||||
adler32,
|
||||
crc32,
|
||||
crc32c,
|
||||
blake2b,
|
||||
blake2s,
|
||||
blake3,
|
||||
keccak,
|
||||
xxhash32,
|
||||
xxhash64,
|
||||
xxhash3,
|
||||
xxhash128,
|
||||
sm3,
|
||||
whirlpool,
|
||||
} as const;
|
||||
|
||||
type AlgoWasmNames = keyof typeof algosWasm;
|
||||
const algoWasmNames = Object.keys(algosWasm) as AlgoWasmNames[];
|
||||
|
||||
const encoding = useQueryParamOrStorage<Encoding>({ defaultValue: 'Hex', storageName: 'hash-text:encoding', name: 'encoding' });
|
||||
const clearText = ref('');
|
||||
|
||||
function formatWithEncoding(words: lib.WordArray, encoding: Encoding) {
|
||||
|
@ -32,12 +73,91 @@ function formatWithEncoding(words: lib.WordArray, encoding: Encoding) {
|
|||
}
|
||||
|
||||
const hashText = (algo: AlgoNames, value: string) => formatWithEncoding(algos[algo](value), encoding.value);
|
||||
|
||||
const defaultHashWasmValues = {
|
||||
adler32: '',
|
||||
crc32: '',
|
||||
crc32c: '',
|
||||
blake2b: '',
|
||||
blake2s: '',
|
||||
blake3: '',
|
||||
keccak: '',
|
||||
xxhash32: '',
|
||||
xxhash64: '',
|
||||
xxhash3: '',
|
||||
xxhash128: '',
|
||||
sm3: '',
|
||||
whirlpool: '',
|
||||
};
|
||||
const hashWasmValues = computedAsync(async () => {
|
||||
const encodingValue = encoding.value;
|
||||
const clearTextValue = clearText.value;
|
||||
const ret = defaultHashWasmValues;
|
||||
for (const algo of algoWasmNames) {
|
||||
ret[algo] = formatWithEncoding(enc.Hex.parse(await algosWasm[algo](clearTextValue)), encodingValue);
|
||||
}
|
||||
return ret;
|
||||
}, defaultHashWasmValues);
|
||||
|
||||
const salt = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(salt);
|
||||
const hashWasmArgon2i = computedAsync(async () => {
|
||||
const clearTextValue = clearText.value;
|
||||
return await argon2i({
|
||||
password: clearTextValue,
|
||||
salt,
|
||||
parallelism: 1,
|
||||
memorySize: 128,
|
||||
iterations: 4,
|
||||
hashLength: 16,
|
||||
outputType: 'encoded',
|
||||
});
|
||||
});
|
||||
const hashWasmArgon2d = computedAsync(async () => {
|
||||
const clearTextValue = clearText.value;
|
||||
return await argon2d({
|
||||
password: clearTextValue,
|
||||
salt,
|
||||
parallelism: 1,
|
||||
memorySize: 128,
|
||||
iterations: 4,
|
||||
hashLength: 16,
|
||||
outputType: 'encoded',
|
||||
});
|
||||
});
|
||||
const hashWasmArgon2id = computedAsync(async () => {
|
||||
const clearTextValue = clearText.value;
|
||||
return await argon2id({
|
||||
password: clearTextValue,
|
||||
salt,
|
||||
parallelism: 1,
|
||||
memorySize: 128,
|
||||
iterations: 4,
|
||||
hashLength: 16,
|
||||
outputType: 'encoded',
|
||||
});
|
||||
});
|
||||
const hashWasmPBKDF2 = computedAsync(async () => {
|
||||
const clearTextValue = clearText.value;
|
||||
return await pbkdf2({
|
||||
password: clearTextValue,
|
||||
salt,
|
||||
iterations: 16,
|
||||
hashLength: 32,
|
||||
hashFunction: createSHA256(),
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-card>
|
||||
<c-input-text v-model:value="clearText" multiline raw-text placeholder="Your string to hash..." rows="3" autosize autofocus label="Your text to hash:" />
|
||||
<c-input-text
|
||||
v-model:value="clearText"
|
||||
multiline raw-text
|
||||
placeholder="Your string to hash..." rows="3"
|
||||
autosize autofocus label="Your text to hash:"
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
|
@ -73,6 +193,44 @@ const hashText = (algo: AlgoNames, value: string) => formatWithEncoding(algos[al
|
|||
<InputCopyable :value="hashText(algo, clearText)" readonly />
|
||||
</n-input-group>
|
||||
</div>
|
||||
|
||||
<div v-for="algo in algoWasmNames" :key="algo" style="margin: 5px 0">
|
||||
<n-input-group>
|
||||
<n-input-group-label style="flex: 0 0 120px">
|
||||
{{ algo.toUpperCase() }}
|
||||
</n-input-group-label>
|
||||
<InputCopyable :value="hashWasmValues[algo]" readonly />
|
||||
</n-input-group>
|
||||
</div>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<div style="margin: 5px 0">
|
||||
<n-input-group>
|
||||
<n-input-group-label style="flex: 0 0 120px">
|
||||
Argon2d
|
||||
</n-input-group-label>
|
||||
<InputCopyable :value="hashWasmArgon2d" readonly />
|
||||
</n-input-group>
|
||||
<n-input-group>
|
||||
<n-input-group-label style="flex: 0 0 120px">
|
||||
Argon2i
|
||||
</n-input-group-label>
|
||||
<InputCopyable :value="hashWasmArgon2i" readonly />
|
||||
</n-input-group>
|
||||
<n-input-group>
|
||||
<n-input-group-label style="flex: 0 0 120px">
|
||||
Argon2id
|
||||
</n-input-group-label>
|
||||
<InputCopyable :value="hashWasmArgon2id" readonly />
|
||||
</n-input-group>
|
||||
<n-input-group>
|
||||
<n-input-group-label style="flex: 0 0 120px">
|
||||
PBKDF2
|
||||
</n-input-group-label>
|
||||
<InputCopyable :value="hashWasmPBKDF2" readonly />
|
||||
</n-input-group>
|
||||
</div>
|
||||
</c-card>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -5,7 +5,8 @@ import { translate } from '@/plugins/i18n.plugin';
|
|||
export const tool = defineTool({
|
||||
name: translate('tools.hash-text.title'),
|
||||
path: '/hash-text',
|
||||
description: translate('tools.hash-text.description'),
|
||||
description:
|
||||
'Hash a text string using the function you need : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3, RIPEMD160, ADLER32, CRC32, CRC32C, BLAKE, KECCAK, XXHASH, SM3, WHIRLPOOL or Argon2(i/d/id)',
|
||||
keywords: [
|
||||
'hash',
|
||||
'digest',
|
||||
|
@ -20,6 +21,24 @@ export const tool = defineTool({
|
|||
'SHA384',
|
||||
'SHA3',
|
||||
'RIPEMD160',
|
||||
'ADLER32',
|
||||
'BLAKE2B',
|
||||
'BLAKE2S',
|
||||
'BLAKE3',
|
||||
'CRC32',
|
||||
'CRC32C',
|
||||
'KECCAK',
|
||||
'PBKDF2',
|
||||
'SM3',
|
||||
'WHIRLPOOL',
|
||||
'XXHASH128',
|
||||
'XXHASH3',
|
||||
'XXHASH32',
|
||||
'XXHASH64',
|
||||
'Argon2',
|
||||
'Argon2i',
|
||||
'Argon2d',
|
||||
'Argon2id',
|
||||
],
|
||||
component: () => import('./hash-text.vue'),
|
||||
icon: EyeOff,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue