aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Corentin THOMASSET <corentin.thomasset74@gmail.com> 2023-10-16 00:57:47 +0200
committerGravatar GitHub <noreply@github.com> 2023-10-15 22:57:47 +0000
commitb2ad4f7a27d1feaf0ef58042689124fc51c54d1e (patch)
tree904208593bd17b20b026f996a2a1b65e6b607f8c
parentb408df82c1d8a0123e552048421b37afcf5189c6 (diff)
downloadit-tools-b2ad4f7a27d1feaf0ef58042689124fc51c54d1e.tar.gz
it-tools-b2ad4f7a27d1feaf0ef58042689124fc51c54d1e.tar.zst
it-tools-b2ad4f7a27d1feaf0ef58042689124fc51c54d1e.zip
feat(new tool): text to ascii converter (#669)
-rw-r--r--components.d.ts1
-rw-r--r--src/tools/index.ts2
-rw-r--r--src/tools/text-to-binary/index.ts12
-rw-r--r--src/tools/text-to-binary/text-to-binary.e2e.spec.ts25
-rw-r--r--src/tools/text-to-binary/text-to-binary.models.test.ts32
-rw-r--r--src/tools/text-to-binary/text-to-binary.models.ts22
-rw-r--r--src/tools/text-to-binary/text-to-binary.vue42
7 files changed, 136 insertions, 0 deletions
diff --git a/components.d.ts b/components.d.ts
index cd58c51..7e0ca92 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -182,6 +182,7 @@ declare module '@vue/runtime-core' {
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default']
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
+ TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
diff --git a/src/tools/index.ts b/src/tools/index.ts
index cc5f42e..e6df8cc 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 textToBinary } from './text-to-binary';
import { tool as ulidGenerator } from './ulid-generator';
import { tool as ibanValidatorAndParser } from './iban-validator-and-parser';
import { tool as stringObfuscator } from './string-obfuscator';
@@ -88,6 +89,7 @@ export const toolsByCategory: ToolCategory[] = [
colorConverter,
caseConverter,
textToNatoAlphabet,
+ textToBinary,
yamlToJson,
yamlToToml,
jsonToYaml,
diff --git a/src/tools/text-to-binary/index.ts b/src/tools/text-to-binary/index.ts
new file mode 100644
index 0000000..40ac93d
--- /dev/null
+++ b/src/tools/text-to-binary/index.ts
@@ -0,0 +1,12 @@
+import { Binary } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Text to ASCII binary',
+ path: '/text-to-binary',
+ description: 'Convert text to its ASCII binary representation and vice versa.',
+ keywords: ['text', 'to', 'binary', 'converter', 'encode', 'decode', 'ascii'],
+ component: () => import('./text-to-binary.vue'),
+ icon: Binary,
+ createdAt: new Date('2023-10-15'),
+});
diff --git a/src/tools/text-to-binary/text-to-binary.e2e.spec.ts b/src/tools/text-to-binary/text-to-binary.e2e.spec.ts
new file mode 100644
index 0000000..2b4e431
--- /dev/null
+++ b/src/tools/text-to-binary/text-to-binary.e2e.spec.ts
@@ -0,0 +1,25 @@
+import { expect, test } from '@playwright/test';
+
+test.describe('Tool - Text to ASCII binary', () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto('/text-to-binary');
+ });
+
+ test('Has correct title', async ({ page }) => {
+ await expect(page).toHaveTitle('Text to ASCII binary - IT Tools');
+ });
+
+ test('Text to binary conversion', async ({ page }) => {
+ await page.getByTestId('text-to-binary-input').fill('it-tools');
+ const binary = await page.getByTestId('text-to-binary-output').inputValue();
+
+ expect(binary).toEqual('01101001 01110100 00101101 01110100 01101111 01101111 01101100 01110011');
+ });
+
+ test('Binary to text conversion', async ({ page }) => {
+ await page.getByTestId('binary-to-text-input').fill('01101001 01110100 00101101 01110100 01101111 01101111 01101100 01110011');
+ const text = await page.getByTestId('binary-to-text-output').inputValue();
+
+ expect(text).toEqual('it-tools');
+ });
+});
diff --git a/src/tools/text-to-binary/text-to-binary.models.test.ts b/src/tools/text-to-binary/text-to-binary.models.test.ts
new file mode 100644
index 0000000..e4269b5
--- /dev/null
+++ b/src/tools/text-to-binary/text-to-binary.models.test.ts
@@ -0,0 +1,32 @@
+import { describe, expect, it } from 'vitest';
+import { convertAsciiBinaryToText, convertTextToAsciiBinary } from './text-to-binary.models';
+
+describe('text-to-binary', () => {
+ describe('convertTextToAsciiBinary', () => {
+ it('a text string is converted to its ascii binary representation', () => {
+ expect(convertTextToAsciiBinary('A')).toBe('01000001');
+ expect(convertTextToAsciiBinary('hello')).toBe('01101000 01100101 01101100 01101100 01101111');
+ expect(convertTextToAsciiBinary('')).toBe('');
+ });
+ it('the separator between octets can be changed', () => {
+ expect(convertTextToAsciiBinary('hello', { separator: '' })).toBe('0110100001100101011011000110110001101111');
+ });
+ });
+
+ describe('convertAsciiBinaryToText', () => {
+ it('an ascii binary string is converted to its text representation', () => {
+ expect(convertAsciiBinaryToText('01101000 01100101 01101100 01101100 01101111')).toBe('hello');
+ expect(convertAsciiBinaryToText('01000001')).toBe('A');
+ expect(convertTextToAsciiBinary('')).toBe('');
+ });
+
+ it('the given binary string is cleaned before conversion', () => {
+ expect(convertAsciiBinaryToText(' 01000 001garbage')).toBe('A');
+ });
+
+ it('throws an error if the given binary string as no complete octet', () => {
+ expect(() => convertAsciiBinaryToText('010000011')).toThrow('Invalid binary string');
+ expect(() => convertAsciiBinaryToText('1')).toThrow('Invalid binary string');
+ });
+ });
+});
diff --git a/src/tools/text-to-binary/text-to-binary.models.ts b/src/tools/text-to-binary/text-to-binary.models.ts
new file mode 100644
index 0000000..ad9699a
--- /dev/null
+++ b/src/tools/text-to-binary/text-to-binary.models.ts
@@ -0,0 +1,22 @@
+export { convertTextToAsciiBinary, convertAsciiBinaryToText };
+
+function convertTextToAsciiBinary(text: string, { separator = ' ' }: { separator?: string } = {}): string {
+ return text
+ .split('')
+ .map(char => char.charCodeAt(0).toString(2).padStart(8, '0'))
+ .join(separator);
+}
+
+function convertAsciiBinaryToText(binary: string): string {
+ const cleanBinary = binary.replace(/[^01]/g, '');
+
+ if (cleanBinary.length % 8) {
+ throw new Error('Invalid binary string');
+ }
+
+ return cleanBinary
+ .split(/(\d{8})/)
+ .filter(Boolean)
+ .map(binary => String.fromCharCode(Number.parseInt(binary, 2)))
+ .join('');
+}
diff --git a/src/tools/text-to-binary/text-to-binary.vue b/src/tools/text-to-binary/text-to-binary.vue
new file mode 100644
index 0000000..37aa9be
--- /dev/null
+++ b/src/tools/text-to-binary/text-to-binary.vue
@@ -0,0 +1,42 @@
+<script setup lang="ts">
+import { convertAsciiBinaryToText, convertTextToAsciiBinary } from './text-to-binary.models';
+import { withDefaultOnError } from '@/utils/defaults';
+import { useCopy } from '@/composable/copy';
+import { isNotThrowing } from '@/utils/boolean';
+
+const inputText = ref('');
+const binaryFromText = computed(() => convertTextToAsciiBinary(inputText.value));
+const { copy: copyBinary } = useCopy({ source: binaryFromText });
+
+const inputBinary = ref('');
+const textFromBinary = computed(() => withDefaultOnError(() => convertAsciiBinaryToText(inputBinary.value), ''));
+const inputBinaryValidationRules = [
+ {
+ validator: (value: string) => isNotThrowing(() => convertAsciiBinaryToText(value)),
+ message: 'Binary should be a valid ASCII binary string with multiples of 8 bits',
+ },
+];
+const { copy: copyText } = useCopy({ source: textFromBinary });
+</script>
+
+<template>
+ <c-card title="Text to ASCII binary">
+ <c-input-text v-model:value="inputText" multiline placeholder="e.g. 'Hello world'" label="Enter text to convert to binary" autosize autofocus raw-text test-id="text-to-binary-input" />
+ <c-input-text v-model:value="binaryFromText" label="Binary from your text" multiline raw-text readonly mt-2 placeholder="The binary representation of your text will be here" test-id="text-to-binary-output" />
+ <div mt-2 flex justify-center>
+ <c-button :disabled="!binaryFromText" @click="copyBinary()">
+ Copy binary to clipboard
+ </c-button>
+ </div>
+ </c-card>
+
+ <c-card title="ASCII binary to text">
+ <c-input-text v-model:value="inputBinary" multiline placeholder="e.g. '01001000 01100101 01101100 01101100 01101111'" label="Enter binary to convert to text" autosize raw-text :validation-rules="inputBinaryValidationRules" test-id="binary-to-text-input" />
+ <c-input-text v-model:value="textFromBinary" label="Text from your binary" multiline raw-text readonly mt-2 placeholder="The text representation of your binary will be here" test-id="binary-to-text-output" />
+ <div mt-2 flex justify-center>
+ <c-button :disabled="!textFromBinary" @click="copyText()">
+ Copy text to clipboard
+ </c-button>
+ </div>
+ </c-card>
+</template>