diff --git a/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.test.ts b/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.test.ts new file mode 100644 index 00000000..c145140f --- /dev/null +++ b/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'vitest'; +import { convertStorageAndRateUnits } from './data-storage-unit-converter.service'; + +describe('data-storage-unit-converter', () => { + describe('convertStorageAndRateUnits', () => { + it('convert from same base units', () => { + expect(convertStorageAndRateUnits({ value: 1024 * 1024, fromUnit: 'B', toUnit: 'MiB' })).toBe('1'); + expect(convertStorageAndRateUnits({ value: 1024, fromUnit: 'KiB', toUnit: 'MiB' })).toBe('1'); + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MiB', toUnit: 'KiB' })).toBe('1,024'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'MB', toUnit: 'GB' })).toBe('1'); + expect(convertStorageAndRateUnits({ value: 1024, fromUnit: 'MB', toUnit: 'MB' })).toBe('1,024'); + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MB', toUnit: 'KB' })).toBe('1,000'); + expect(convertStorageAndRateUnits({ value: 1024, fromUnit: 'MiB', toUnit: 'GiB' })).toBe('1'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'MB', toUnit: 'GB' })).toBe('1'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'Mb', toUnit: 'Gb' })).toBe('1'); + }); + + it('convert between base units', () => { + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MB', toUnit: 'MiB' })).toBe('0.954'); + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MiB', toUnit: 'MB' })).toBe('1.049'); + expect(convertStorageAndRateUnits({ value: 1000 * 1000, fromUnit: 'B', toUnit: 'MiB' })).toBe('0.954'); + expect(convertStorageAndRateUnits({ value: 1024, fromUnit: 'KB', toUnit: 'MiB' })).toBe('0.977'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'MiB', toUnit: 'MB' })).toBe('1,048.576'); + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MB', toUnit: 'Mb' })).toBe('8'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'KB', toUnit: 'Kb' })).toBe('8,000'); + expect(convertStorageAndRateUnits({ value: 1000, fromUnit: 'KiB', toUnit: 'Kb' })).toBe('8,192'); + expect(convertStorageAndRateUnits({ value: 8, fromUnit: 'Mb', toUnit: 'MB' })).toBe('1'); + + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'Mb', toUnit: 'KB' })).toBe('125'); + expect(convertStorageAndRateUnits({ value: 125, fromUnit: 'KB', toUnit: 'Mb' })).toBe('1'); + + expect(convertStorageAndRateUnits({ value: 1, fromUnit: 'MiB', toUnit: 'Kb' })).toBe('8,388.608'); + expect(convertStorageAndRateUnits({ value: 8388.608, fromUnit: 'Kb', toUnit: 'MiB' })).toBe('1'); + }); + }); +}); diff --git a/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.ts b/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.ts new file mode 100644 index 00000000..39d836d2 --- /dev/null +++ b/src/tools/data-storage-unit-converter/data-storage-unit-converter.service.ts @@ -0,0 +1,24 @@ +export function convertStorageAndRateUnits( + { value, fromUnit, toUnit, precision = 3 }: + { value: number; fromUnit: string; toUnit: string; precision?: number }): string { + const units = [ + 'iB', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', + 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', + 'b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb', 'Zb', 'Yb', + ]; + + const fromIndex = units.indexOf(fromUnit); + const fromFactor = fromIndex / 9 > 1 ? 1000 : 1024; + const fromDivisor = fromIndex / 9 > 2 ? 8 : 1; + const toIndex = units.indexOf(toUnit); + const toFactor = toIndex / 9 > 1 ? 1000 : 1024; + const toDivisor = toIndex / 9 > 2 ? 8 : 1; + + const fromBase = (fromFactor ** (fromIndex % 9)) / fromDivisor; + const toBase = (toFactor ** (toIndex % 9)) / toDivisor; + + const result = value * fromBase / toBase; + return result.toLocaleString(undefined, { + maximumFractionDigits: precision, + }); +} diff --git a/src/tools/data-storage-unit-converter/data-storage-unit-converter.vue b/src/tools/data-storage-unit-converter/data-storage-unit-converter.vue new file mode 100644 index 00000000..ef82702f --- /dev/null +++ b/src/tools/data-storage-unit-converter/data-storage-unit-converter.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/tools/data-storage-unit-converter/index.ts b/src/tools/data-storage-unit-converter/index.ts new file mode 100644 index 00000000..b1ccc2a9 --- /dev/null +++ b/src/tools/data-storage-unit-converter/index.ts @@ -0,0 +1,16 @@ +import { ArrowsLeftRight } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Data Storage Unit converter', + path: '/data-storage-unit-converter', + description: 'Convert data storage or transfer units (bytes, bibytes, bits, kilobytes...)', + keywords: ['data', 'storage', 'unit', 'conversion', + 'bits', 'bytes', 'bibytes', 'binary', + 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', + 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', + 'b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb', 'Zb', 'Yb'], + component: () => import('./data-storage-unit-converter.vue'), + icon: ArrowsLeftRight, + createdAt: new Date('2024-08-15'), +}); diff --git a/src/tools/index.ts b/src/tools/index.ts index c9003fe8..ca7b0a87 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -2,6 +2,8 @@ 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 emailNormalizer } from './email-normalizer'; +import { tool as dataTransferRate } from './data-transfer-rate'; +import { tool as dataStorageUnitConverter } from './data-storage-unit-converter'; import { tool as asciiTextDrawer } from './ascii-text-drawer';