mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-12-10 00:48:37 -06:00
Compare commits
7 Commits
f3c5946e0d
...
7cec37b7fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cec37b7fe | ||
|
|
80662c59c6 | ||
|
|
009a0dd6ad | ||
|
|
6ad57674ea | ||
|
|
ef034f2b8b | ||
|
|
8cc7986c7f | ||
|
|
f30aeb45eb |
@ -307,5 +307,21 @@
|
||||
"shortDescription": "Quickly URL-escape a string.",
|
||||
"title": "String URL encoder"
|
||||
}
|
||||
},
|
||||
"unicode": {
|
||||
"title": "Unicode Encoder / Decoder",
|
||||
"inputTitle": "Input",
|
||||
"resultTitle": "Processed Output",
|
||||
"optionsTitle": "Mode",
|
||||
"caseOptionsTitle": "Case Options",
|
||||
"encode": "Encode",
|
||||
"decode": "Decode",
|
||||
"uppercase": "Uppercase Hex",
|
||||
"description": "Convert text to Unicode escape sequences or decode them back to readable text.",
|
||||
"shortDescription": "Encode or decode text using Unicode escape sequences.",
|
||||
"toolInfo": {
|
||||
"title": "Unicode Encoder / Decoder",
|
||||
"description": "This tool lets you convert plain text into Unicode escape sequences (e.g., \\uXXXX) and decode Unicode escape sequences back into standard text. You can also choose whether the hexadecimal output is formatted in uppercase or lowercase when encoding."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import { tool as stringCensor } from './censor/meta';
|
||||
import { tool as stringPasswordGenerator } from './password-generator/meta';
|
||||
import { tool as stringEncodeUrl } from './url-encode/meta';
|
||||
import { tool as StringDecodeUrl } from './url-decode/meta';
|
||||
import { tool as stringUnicode } from './unicode/meta';
|
||||
|
||||
export const stringTools = [
|
||||
stringSplit,
|
||||
@ -45,5 +46,6 @@ export const stringTools = [
|
||||
stringPasswordGenerator,
|
||||
stringEncodeUrl,
|
||||
StringDecodeUrl,
|
||||
stringUnicode,
|
||||
stringHiddenCharacterDetector
|
||||
];
|
||||
|
||||
123
src/pages/tools/string/unicode/index.tsx
Normal file
123
src/pages/tools/string/unicode/index.tsx
Normal file
@ -0,0 +1,123 @@
|
||||
import { Box } from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import ToolContent from '@components/ToolContent';
|
||||
import { ToolComponentProps } from '@tools/defineTool';
|
||||
import ToolTextInput from '@components/input/ToolTextInput';
|
||||
import ToolTextResult from '@components/result/ToolTextResult';
|
||||
import { GetGroupsType } from '@components/options/ToolOptions';
|
||||
import { CardExampleType } from '@components/examples/ToolExamples';
|
||||
import { unicode } from './service';
|
||||
import { InitialValuesType } from './types';
|
||||
import SimpleRadio from '@components/options/SimpleRadio';
|
||||
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const initialValues: InitialValuesType = {
|
||||
mode: 'encode',
|
||||
uppercase: false
|
||||
};
|
||||
|
||||
const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||
{
|
||||
title: 'Encode to Unicode Escape',
|
||||
description: 'Encode plain text to Unicode escape sequences.',
|
||||
sampleText: 'Hello, World!',
|
||||
sampleResult:
|
||||
'\\u0048\\u0065\\u006c\\u006c\\u006f\\u002c\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064\\u0021',
|
||||
sampleOptions: {
|
||||
mode: 'encode',
|
||||
uppercase: false
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Encode to Unicode Escape (Uppercase)',
|
||||
description: 'Encode plain text to uppercase Unicode escape sequences.',
|
||||
sampleText: 'Hello, World!',
|
||||
sampleResult:
|
||||
'\\u0048\\u0065\\u006c\\u006c\\u006f\\u002c\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064\\u0021'.toUpperCase(),
|
||||
sampleOptions: {
|
||||
mode: 'encode',
|
||||
uppercase: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Decode Unicode Escape',
|
||||
description: 'Decode Unicode escape sequences back to plain text.',
|
||||
sampleText:
|
||||
'\\u0048\\u0065\\u006c\\u006c\\u006f\\u002c\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064\\u0021',
|
||||
sampleResult: 'Hello, World!',
|
||||
sampleOptions: {
|
||||
mode: 'decode',
|
||||
uppercase: false
|
||||
}
|
||||
}
|
||||
];
|
||||
export default function Unicode({ title }: ToolComponentProps) {
|
||||
const { t } = useTranslation('string');
|
||||
const [input, setInput] = useState<string>('');
|
||||
const [result, setResult] = useState<string>('');
|
||||
|
||||
const compute = (values: InitialValuesType, input: string) => {
|
||||
setResult(unicode(input, values));
|
||||
};
|
||||
|
||||
const getGroups: GetGroupsType<InitialValuesType> = ({
|
||||
values,
|
||||
updateField
|
||||
}) => [
|
||||
{
|
||||
title: t('unicode.optionsTitle'),
|
||||
component: (
|
||||
<Box>
|
||||
<SimpleRadio
|
||||
onClick={() => updateField('mode', 'encode')}
|
||||
checked={values.mode === 'encode'}
|
||||
title={t('unicode.encode')}
|
||||
/>
|
||||
<SimpleRadio
|
||||
onClick={() => updateField('mode', 'decode')}
|
||||
checked={values.mode === 'decode'}
|
||||
title={t('unicode.decode')}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t('unicode.caseOptionsTitle'),
|
||||
component: (
|
||||
<Box>
|
||||
<CheckboxWithDesc
|
||||
checked={values.uppercase}
|
||||
onChange={(value) => updateField('uppercase', value)}
|
||||
title={t('unicode.uppercase')}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
];
|
||||
return (
|
||||
<ToolContent
|
||||
title={title}
|
||||
input={input}
|
||||
inputComponent={
|
||||
<ToolTextInput
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
title={t('unicode.inputTitle')}
|
||||
/>
|
||||
}
|
||||
resultComponent={
|
||||
<ToolTextResult value={result} title={t('unicode.resultTitle')} />
|
||||
}
|
||||
initialValues={initialValues}
|
||||
exampleCards={exampleCards}
|
||||
getGroups={getGroups}
|
||||
setInput={setInput}
|
||||
compute={compute}
|
||||
toolInfo={{
|
||||
title: t('unicode.toolInfo.title'),
|
||||
description: t('unicode.toolInfo.description')
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
14
src/pages/tools/string/unicode/meta.ts
Normal file
14
src/pages/tools/string/unicode/meta.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('string', {
|
||||
i18n: {
|
||||
name: 'string:unicode.title',
|
||||
description: 'string:unicode.description',
|
||||
shortDescription: 'string:unicode.shortDescription'
|
||||
},
|
||||
path: 'unicode',
|
||||
icon: 'mdi:unicode',
|
||||
keywords: ['unicode', 'encode', 'decode', 'escape', 'text'],
|
||||
component: lazy(() => import('./index'))
|
||||
});
|
||||
21
src/pages/tools/string/unicode/service.ts
Normal file
21
src/pages/tools/string/unicode/service.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { InitialValuesType } from './types';
|
||||
|
||||
export function unicode(input: string, options: InitialValuesType): string {
|
||||
if (!input) return '';
|
||||
if (options.mode === 'encode') {
|
||||
let result = '';
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
let hex = input.charCodeAt(i).toString(16);
|
||||
hex = ('0000' + hex).slice(-4);
|
||||
if (options.uppercase) {
|
||||
hex = hex.toUpperCase();
|
||||
}
|
||||
result += '\\u' + hex;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return input.replace(/\\u([\dA-Fa-f]{4})/g, (match, grp) => {
|
||||
return String.fromCharCode(parseInt(grp, 16));
|
||||
});
|
||||
}
|
||||
}
|
||||
4
src/pages/tools/string/unicode/types.ts
Normal file
4
src/pages/tools/string/unicode/types.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export type InitialValuesType = {
|
||||
mode: 'encode' | 'decode';
|
||||
uppercase: boolean;
|
||||
};
|
||||
178
src/pages/tools/string/unicode/unicode.service.test.ts
Normal file
178
src/pages/tools/string/unicode/unicode.service.test.ts
Normal file
@ -0,0 +1,178 @@
|
||||
import { expect, describe, it } from 'vitest';
|
||||
import { unicode } from './service';
|
||||
|
||||
describe('unicode', () => {
|
||||
it('should encode an English string to lowercase hex correctly', () => {
|
||||
const input = 'Hello, World!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe(
|
||||
'\\u0048\\u0065\\u006c\\u006c\\u006f\\u002c\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should encode an English string to uppercase hex correctly', () => {
|
||||
const input = 'Hello, World!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe(
|
||||
'\\u0048\\u0065\\u006C\\u006C\\u006F\\u002C\\u0020\\u0057\\u006F\\u0072\\u006C\\u0064\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode an English lowercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u0048\\u0065\\u006c\\u006c\\u006f\\u002c\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('Hello, World!');
|
||||
});
|
||||
|
||||
it('should decode an English uppercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u0048\\u0065\\u006C\\u006C\\u006F\\u002C\\u0020\\u0057\\u006F\\u0072\\u006C\\u0064\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('Hello, World!');
|
||||
});
|
||||
|
||||
it('should encode a Korean string to lowercase hex correctly', () => {
|
||||
const input = '안녕하세요, 세계!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe(
|
||||
'\\uc548\\ub155\\ud558\\uc138\\uc694\\u002c\\u0020\\uc138\\uacc4\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should encode a Korean string to uppercase hex correctly', () => {
|
||||
const input = '안녕하세요, 세계!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe(
|
||||
'\\uC548\\uB155\\uD558\\uC138\\uC694\\u002C\\u0020\\uC138\\uACC4\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode a Korean lowercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\uc548\\ub155\\ud558\\uc138\\uc694\\u002c\\u0020\\uc138\\uacc4\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('안녕하세요, 세계!');
|
||||
});
|
||||
|
||||
it('should decode a Korean uppercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\uC548\\uB155\\uD558\\uC138\\uC694\\u002C\\u0020\\uC138\\uACC4\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('안녕하세요, 세계!');
|
||||
});
|
||||
|
||||
it('should encode a Japanese string to lowercase hex correctly', () => {
|
||||
const input = 'こんにちは、世界!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe(
|
||||
'\\u3053\\u3093\\u306b\\u3061\\u306f\\u3001\\u4e16\\u754c\\uff01'
|
||||
);
|
||||
});
|
||||
|
||||
it('should encode a Japanese string to uppercase hex correctly', () => {
|
||||
const input = 'こんにちは、世界!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe(
|
||||
'\\u3053\\u3093\\u306B\\u3061\\u306F\\u3001\\u4E16\\u754C\\uFF01'
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode a Japanese lowercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u3053\\u3093\\u306b\\u3061\\u306f\\u3001\\u4e16\\u754c\\uff01';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('こんにちは、世界!');
|
||||
});
|
||||
|
||||
it('should decode a Japanese uppercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u3053\\u3093\\u306B\\u3061\\u306F\\u3001\\u4E16\\u754C\\uFF01';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('こんにちは、世界!');
|
||||
});
|
||||
|
||||
it('should encode a Chinese string to lowercase hex correctly', () => {
|
||||
const input = '你好,世界!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe('\\u4f60\\u597d\\uff0c\\u4e16\\u754c\\uff01');
|
||||
});
|
||||
|
||||
it('should encode a Chinese string to uppercase hex correctly', () => {
|
||||
const input = '你好,世界!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe('\\u4F60\\u597D\\uFF0C\\u4E16\\u754C\\uFF01');
|
||||
});
|
||||
|
||||
it('should decode a Chinese lowercase hex string correctly', () => {
|
||||
const input = '\\u4f60\\u597d\\uff0c\\u4e16\\u754c\\uff01';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('你好,世界!');
|
||||
});
|
||||
|
||||
it('should decode a Chinese uppercase hex string correctly', () => {
|
||||
const input = '\\u4F60\\u597D\\uFF0C\\u4E16\\u754C\\uFF01';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('你好,世界!');
|
||||
});
|
||||
|
||||
it('should encode a Russian string to lowercase hex correctly', () => {
|
||||
const input = 'Привет, мир!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe(
|
||||
'\\u041f\\u0440\\u0438\\u0432\\u0435\\u0442\\u002c\\u0020\\u043c\\u0438\\u0440\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should encode a Russian string to uppercase hex correctly', () => {
|
||||
const input = 'Привет, мир!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe(
|
||||
'\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442\\u002C\\u0020\\u043C\\u0438\\u0440\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode a Russian lowercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u041f\\u0440\\u0438\\u0432\\u0435\\u0442\\u002c\\u0020\\u043c\\u0438\\u0440\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('Привет, мир!');
|
||||
});
|
||||
|
||||
it('should decode a Russian uppercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442\\u002C\\u0020\\u043C\\u0438\\u0440\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('Привет, мир!');
|
||||
});
|
||||
|
||||
it('should encode a Spanish string to lowercase hex correctly', () => {
|
||||
const input = '¡Hola, Mundo!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: false });
|
||||
expect(result).toBe(
|
||||
'\\u00a1\\u0048\\u006f\\u006c\\u0061\\u002c\\u0020\\u004d\\u0075\\u006e\\u0064\\u006f\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should encode a Spanish string to uppercase hex correctly', () => {
|
||||
const input = '¡Hola, Mundo!';
|
||||
const result = unicode(input, { mode: 'encode', uppercase: true });
|
||||
expect(result).toBe(
|
||||
'\\u00A1\\u0048\\u006F\\u006C\\u0061\\u002C\\u0020\\u004D\\u0075\\u006E\\u0064\\u006F\\u0021'
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode a Spanish lowercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u00a1\\u0048\\u006f\\u006c\\u0061\\u002c\\u0020\\u004d\\u0075\\u006e\\u0064\\u006f\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('¡Hola, Mundo!');
|
||||
});
|
||||
|
||||
it('should decode a Spanish uppercase hex string correctly', () => {
|
||||
const input =
|
||||
'\\u00A1\\u0048\\u006F\\u006C\\u0061\\u002C\\u0020\\u004D\\u0075\\u006E\\u0064\\u006F\\u0021';
|
||||
const result = unicode(input, { mode: 'decode', uppercase: false });
|
||||
expect(result).toBe('¡Hola, Mundo!');
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user