diff options
author | 2022-04-12 14:27:52 +0200 | |
---|---|---|
committer | 2022-04-12 14:27:52 +0200 | |
commit | 034c686896d0443ea587cd152535b2227234c011 (patch) | |
tree | a2b62db8213fd8c7012216f4ee6088011e717816 /src/tools/integer-base-converter | |
parent | 5cd9997a845f6d5f82d3ae74d3ec12603224517d (diff) | |
download | it-tools-034c686896d0443ea587cd152535b2227234c011.tar.gz it-tools-034c686896d0443ea587cd152535b2227234c011.tar.zst it-tools-034c686896d0443ea587cd152535b2227234c011.zip |
feat(tool): base converter
Diffstat (limited to 'src/tools/integer-base-converter')
4 files changed, 116 insertions, 0 deletions
diff --git a/src/tools/integer-base-converter/index.ts b/src/tools/integer-base-converter/index.ts new file mode 100644 index 0000000..cca640a --- /dev/null +++ b/src/tools/integer-base-converter/index.ts @@ -0,0 +1,11 @@ +import { ArrowsLeftRight } from '@vicons/tabler'; +import type { ITool } from '../Tool'; + +export const tool: ITool = { + name: 'Integer base converter', + path: '/base-converter', + description: 'Convert numver between different bases (decimal, hexadecimal, binary, octale, base64, ...)', + keywords: ['integer', 'number', 'base', 'convertion', 'decimal', 'hexadecimal', 'binary', 'octale', 'base64'], + component: () => import('./integer-base-converter.vue'), + icon: ArrowsLeftRight, +}; diff --git a/src/tools/integer-base-converter/integer-base-converter.model.test.ts b/src/tools/integer-base-converter/integer-base-converter.model.test.ts new file mode 100644 index 0000000..e9d91f6 --- /dev/null +++ b/src/tools/integer-base-converter/integer-base-converter.model.test.ts @@ -0,0 +1,17 @@ +import { expect, describe, it } from 'vitest'; +import { convertBase } from './integer-base-converter.model'; + +describe('integer-base-converter', () => { + describe('convertBase', () => { + describe('when the input and target bases are between 2 and 64', () => { + it('should convert integer between different bases', () => { + expect(convertBase({ value: '0', fromBase: 2, toBase: 11 })).toEqual('0'); + expect(convertBase({ value: '0', fromBase: 5, toBase: 2 })).toEqual('0'); + expect(convertBase({ value: '0', fromBase: 10, toBase: 16 })).toEqual('0'); + expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5'); + expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216'); + expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275'); + }); + }); + }); +}); diff --git a/src/tools/integer-base-converter/integer-base-converter.model.ts b/src/tools/integer-base-converter/integer-base-converter.model.ts new file mode 100644 index 0000000..c3ed66d --- /dev/null +++ b/src/tools/integer-base-converter/integer-base-converter.model.ts @@ -0,0 +1,20 @@ +export function convertBase({ value, fromBase, toBase }: { value: string; fromBase: number; toBase: number }) { + const range = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'.split(''); + const fromRange = range.slice(0, fromBase); + const toRange = range.slice(0, toBase); + let decValue = value + .split('') + .reverse() + .reduce((carry: number, digit: string, index: number) => { + if (!fromRange.includes(digit)) { + throw new Error('Invalid digit `' + digit + '` for base ' + fromBase + '.'); + } + return (carry += fromRange.indexOf(digit) * Math.pow(fromBase, index)); + }, 0); + let newValue = ''; + while (decValue > 0) { + newValue = toRange[decValue % toBase] + newValue; + decValue = (decValue - (decValue % toBase)) / toBase; + } + return newValue || '0'; +} diff --git a/src/tools/integer-base-converter/integer-base-converter.vue b/src/tools/integer-base-converter/integer-base-converter.vue new file mode 100644 index 0000000..5508b42 --- /dev/null +++ b/src/tools/integer-base-converter/integer-base-converter.vue @@ -0,0 +1,68 @@ +<template> + <div> + <n-card> + <n-input-group> + <n-input-group-label style="width: 200px;">Input number:</n-input-group-label> + <n-input-number v-model:value="inputNumber" min="0" /> + + <n-input-group-label style="width: 200px;">Input base:</n-input-group-label> + <n-input-number v-model:value="inputBase" max="64" min="2" style="width: 100px;" /> + </n-input-group> + <n-divider></n-divider> + + + + <n-input-group> + <n-input-group-label style="width: 200px;">Binary (2):</n-input-group-label> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 2 })" + readonly /> + </n-input-group> + + <n-input-group> + <n-input-group-label style="width: 200px;">Octale (8):</n-input-group-label> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 8 })" + readonly /> + </n-input-group> + + <n-input-group> + <n-input-group-label style="width: 200px;">Decimal (10):</n-input-group-label> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 10 })" + readonly /> + </n-input-group> + + <n-input-group> + <n-input-group-label style="width: 200px;">Hexadecimal (16):</n-input-group-label> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 16 })" + readonly /> + </n-input-group> + + <n-input-group> + <n-input-group-label style="width: 200px;">Base64 (64):</n-input-group-label> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 64 })" + readonly /> + </n-input-group> + <n-input-group> + <n-input-group-label style="width: 90px;">Custom:</n-input-group-label> + <n-input-number style="width: 110px;" v-model:value="outputBase" max="64" min="2" /> + <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: outputBase })" + readonly /> + </n-input-group> + </n-card> + </div> +</template> + +<script setup lang="ts"> +import { ref } from 'vue' +import { convertBase } from './integer-base-converter.model' + +const inputNumber = ref(42) +const inputBase = ref(10) +const outputBase = ref(42) + +</script> + +<style lang="less" scoped> +.n-input-group:not(:first-child) { + margin-top: 5px; +} +</style>
\ No newline at end of file |