diff options
author | 2023-08-16 23:43:45 +0200 | |
---|---|---|
committer | 2023-08-16 21:43:45 +0000 | |
commit | c58d6e34232e199406b39cb258e8106dc6b2f9c1 (patch) | |
tree | 3a21bcc5de88be2e260a852bf7d99acdd7b42da1 /src | |
parent | f235dcd6c1aeaf92ad2e1e7125aac76367e85345 (diff) | |
download | it-tools-c58d6e34232e199406b39cb258e8106dc6b2f9c1.tar.gz it-tools-c58d6e34232e199406b39cb258e8106dc6b2f9c1.tar.zst it-tools-c58d6e34232e199406b39cb258e8106dc6b2f9c1.zip |
feat(new tool): string obfuscator (#575)
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/index.ts | 3 | ||||
-rw-r--r-- | src/tools/string-obfuscator/index.ts | 12 | ||||
-rw-r--r-- | src/tools/string-obfuscator/string-obfuscator.model.test.ts | 20 | ||||
-rw-r--r-- | src/tools/string-obfuscator/string-obfuscator.model.ts | 35 | ||||
-rw-r--r-- | src/tools/string-obfuscator/string-obfuscator.vue | 47 |
5 files changed, 116 insertions, 1 deletions
diff --git a/src/tools/index.ts b/src/tools/index.ts index 0cfc173..c5686a4 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,6 +1,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; +import { tool as stringObfuscator } from './string-obfuscator'; import { tool as emojiPicker } from './emoji-picker'; import { tool as passwordStrengthAnalyser } from './password-strength-analyser'; import { tool as yamlToToml } from './yaml-to-toml'; @@ -145,7 +146,7 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Text', - components: [loremIpsumGenerator, textStatistics, emojiPicker], + components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator], }, { name: 'Data', diff --git a/src/tools/string-obfuscator/index.ts b/src/tools/string-obfuscator/index.ts new file mode 100644 index 0000000..d5b4531 --- /dev/null +++ b/src/tools/string-obfuscator/index.ts @@ -0,0 +1,12 @@ +import { EyeOff } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'String obfuscator', + path: '/string-obfuscator', + description: 'Obfuscate a string (like a secret, an IBAN, or a token) to make it shareable and identifiable without revealing its content.', + keywords: ['string', 'obfuscator', 'secret', 'token', 'hide', 'obscure', 'mask', 'masking'], + component: () => import('./string-obfuscator.vue'), + icon: EyeOff, + createdAt: new Date('2023-08-16'), +}); diff --git a/src/tools/string-obfuscator/string-obfuscator.model.test.ts b/src/tools/string-obfuscator/string-obfuscator.model.test.ts new file mode 100644 index 0000000..08d3fc2 --- /dev/null +++ b/src/tools/string-obfuscator/string-obfuscator.model.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; +import { obfuscateString } from './string-obfuscator.model'; + +describe('string-obfuscator model', () => { + describe('obfuscateString', () => { + it('the characters in the middle of the string are replaced by the replacement character', () => { + expect(obfuscateString('1234567890')).toBe('1234******'); + expect(obfuscateString('1234567890', { replacementChar: 'x' })).toBe('1234xxxxxx'); + expect(obfuscateString('1234567890', { keepFirst: 5 })).toBe('12345*****'); + expect(obfuscateString('1234567890', { keepFirst: 0, keepLast: 5 })).toBe('*****67890'); + expect(obfuscateString('1234567890', { keepFirst: 5, keepLast: 5 })).toBe('1234567890'); + expect(obfuscateString('1234567890', { keepFirst: 2, keepLast: 2, replacementChar: 'x' })).toBe('12xxxxxx90'); + }); + + it('by default, the spaces are kept, they can be removed with the keepSpace option', () => { + expect(obfuscateString('12345 67890')).toBe('1234* *****'); + expect(obfuscateString('12345 67890', { keepSpace: false })).toBe('1234*******'); + }); + }); +}); diff --git a/src/tools/string-obfuscator/string-obfuscator.model.ts b/src/tools/string-obfuscator/string-obfuscator.model.ts new file mode 100644 index 0000000..7f56dd1 --- /dev/null +++ b/src/tools/string-obfuscator/string-obfuscator.model.ts @@ -0,0 +1,35 @@ +import { get } from '@vueuse/core'; +import { type MaybeRef, computed } from 'vue'; + +export { obfuscateString, useObfuscateString }; + +function obfuscateString( + str: string, + { replacementChar = '*', keepFirst = 4, keepLast = 0, keepSpace = true }: { replacementChar?: string; keepFirst?: number; keepLast?: number; keepSpace?: boolean } = {}): string { + return str + .split('') + .map((char, index, array) => { + if (keepSpace && char === ' ') { + return char; + } + + return (index < keepFirst || index >= array.length - keepLast) ? char : replacementChar; + }) + .join(''); +} + +function useObfuscateString( + str: MaybeRef<string>, + config: { replacementChar?: MaybeRef<string>; keepFirst?: MaybeRef<number>; keepLast?: MaybeRef<number>; keepSpace?: MaybeRef<boolean> } = {}, + +) { + return computed(() => obfuscateString( + get(str), + { + replacementChar: get(config.replacementChar), + keepFirst: get(config.keepFirst), + keepLast: get(config.keepLast), + keepSpace: get(config.keepSpace), + }, + )); +} diff --git a/src/tools/string-obfuscator/string-obfuscator.vue b/src/tools/string-obfuscator/string-obfuscator.vue new file mode 100644 index 0000000..0f11fca --- /dev/null +++ b/src/tools/string-obfuscator/string-obfuscator.vue @@ -0,0 +1,47 @@ +<script setup lang="ts"> +import { useObfuscateString } from './string-obfuscator.model'; +import { useCopy } from '@/composable/copy'; + +const str = ref('Lorem ipsum dolor sit amet'); +const keepFirst = ref(4); +const keepLast = ref(4); +const keepSpace = ref(true); + +const obfuscatedString = useObfuscateString(str, { keepFirst, keepLast, keepSpace }); +const { copy } = useCopy({ source: obfuscatedString }); +</script> + +<template> + <div> + <c-input-text v-model:value="str" raw-text placeholder="Enter string to obfuscate" label="String to obfuscate:" clearable multiline /> + + <div mt-4 flex gap-10px> + <div> + <div>Keep first:</div> + <n-input-number v-model:value="keepFirst" min="0" /> + </div> + + <div> + <div>Keep last:</div> + <n-input-number v-model:value="keepLast" min="0" /> + </div> + + <div> + <div mb-5px> + Keep spaces: + </div> + <n-switch v-model:value="keepSpace" /> + </div> + </div> + + <c-card v-if="obfuscatedString" mt-60px max-w-600px flex items-center gap-5px font-mono> + <div break-anywhere text-wrap> + {{ obfuscatedString }} + </div> + + <c-button @click="copy"> + <icon-mdi:content-copy /> + </c-button> + </c-card> + </div> +</template> |