mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 05:47:10 -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",
|
"figlet": "^1.7.0",
|
||||||
"figue": "^1.2.0",
|
"figue": "^1.2.0",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
|
"hash-wasm": "^4.11.0",
|
||||||
"highlight.js": "^11.7.0",
|
"highlight.js": "^11.7.0",
|
||||||
"iarna-toml-esm": "^3.0.5",
|
"iarna-toml-esm": "^3.0.5",
|
||||||
"ibantools": "^4.3.3",
|
"ibantools": "^4.3.3",
|
||||||
|
|
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
|
@ -83,6 +83,9 @@ dependencies:
|
||||||
fuse.js:
|
fuse.js:
|
||||||
specifier: ^6.6.2
|
specifier: ^6.6.2
|
||||||
version: 6.6.2
|
version: 6.6.2
|
||||||
|
hash-wasm:
|
||||||
|
specifier: ^4.11.0
|
||||||
|
version: 4.11.0
|
||||||
highlight.js:
|
highlight.js:
|
||||||
specifier: ^11.7.0
|
specifier: ^11.7.0
|
||||||
version: 11.7.0
|
version: 11.7.0
|
||||||
|
@ -3351,7 +3354,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/dom': 0.5.1
|
'@unhead/dom': 0.5.1
|
||||||
'@unhead/schema': 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
|
unhead: 0.5.1
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -3993,10 +3996,10 @@ packages:
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared@10.7.2(vue@3.3.4):
|
/@vueuse/shared@10.9.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==}
|
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.14.6(vue@3.3.4)
|
vue-demi: 0.14.7(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
@ -5969,6 +5972,10 @@ packages:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/hash-wasm@4.11.0:
|
||||||
|
resolution: {integrity: sha512-HVusNXlVqHe0fzIzdQOGolnFN6mX/fqcrSAOcTBXdvzrXVHwTz11vXeKRmkR5gTuwVpvHZEIyKoePDvuAR+XwQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/hasown@2.0.0:
|
/hasown@2.0.0:
|
||||||
resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
|
resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
@ -9151,8 +9158,8 @@ packages:
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vue-demi@0.14.6(vue@3.3.4):
|
/vue-demi@0.14.7(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
|
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useRouteQuery } from '@vueuse/router';
|
import { useRouteQuery } from '@vueuse/router';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import { useStorage } from '@vueuse/core';
|
||||||
|
|
||||||
export { useQueryParam };
|
export { useQueryParam, useQueryParamOrStorage };
|
||||||
|
|
||||||
const transformers = {
|
const transformers = {
|
||||||
number: {
|
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 type { lib } from 'crypto-js';
|
||||||
import { MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA3, SHA384, SHA512, enc } 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 InputCopyable from '../../components/InputCopyable.vue';
|
||||||
import { convertHexToBin } from './hash-text.service';
|
import { convertHexToBin } from './hash-text.service';
|
||||||
import { useQueryParam } from '@/composable/queryParams';
|
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||||
|
|
||||||
const algos = {
|
const algos = {
|
||||||
MD5,
|
MD5,
|
||||||
|
@ -20,7 +41,27 @@ const algos = {
|
||||||
type AlgoNames = keyof typeof algos;
|
type AlgoNames = keyof typeof algos;
|
||||||
type Encoding = keyof typeof enc | 'Bin';
|
type Encoding = keyof typeof enc | 'Bin';
|
||||||
const algoNames = Object.keys(algos) as AlgoNames[];
|
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('');
|
const clearText = ref('');
|
||||||
|
|
||||||
function formatWithEncoding(words: lib.WordArray, encoding: Encoding) {
|
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 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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<c-card>
|
<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 />
|
<n-divider />
|
||||||
|
|
||||||
|
@ -73,6 +193,44 @@ const hashText = (algo: AlgoNames, value: string) => formatWithEncoding(algos[al
|
||||||
<InputCopyable :value="hashText(algo, clearText)" readonly />
|
<InputCopyable :value="hashText(algo, clearText)" readonly />
|
||||||
</n-input-group>
|
</n-input-group>
|
||||||
</div>
|
</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>
|
</c-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,7 +5,8 @@ import { translate } from '@/plugins/i18n.plugin';
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: translate('tools.hash-text.title'),
|
name: translate('tools.hash-text.title'),
|
||||||
path: '/hash-text',
|
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: [
|
keywords: [
|
||||||
'hash',
|
'hash',
|
||||||
'digest',
|
'digest',
|
||||||
|
@ -20,6 +21,24 @@ export const tool = defineTool({
|
||||||
'SHA384',
|
'SHA384',
|
||||||
'SHA3',
|
'SHA3',
|
||||||
'RIPEMD160',
|
'RIPEMD160',
|
||||||
|
'ADLER32',
|
||||||
|
'BLAKE2B',
|
||||||
|
'BLAKE2S',
|
||||||
|
'BLAKE3',
|
||||||
|
'CRC32',
|
||||||
|
'CRC32C',
|
||||||
|
'KECCAK',
|
||||||
|
'PBKDF2',
|
||||||
|
'SM3',
|
||||||
|
'WHIRLPOOL',
|
||||||
|
'XXHASH128',
|
||||||
|
'XXHASH3',
|
||||||
|
'XXHASH32',
|
||||||
|
'XXHASH64',
|
||||||
|
'Argon2',
|
||||||
|
'Argon2i',
|
||||||
|
'Argon2d',
|
||||||
|
'Argon2id',
|
||||||
],
|
],
|
||||||
component: () => import('./hash-text.vue'),
|
component: () => import('./hash-text.vue'),
|
||||||
icon: EyeOff,
|
icon: EyeOff,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue