feat(tool): base converter
This commit is contained in:
		
							parent
							
								
									5cd9997a84
								
							
						
					
					
						commit
						034c686896
					
				| @ -9,6 +9,7 @@ import { tool as cypher } from './encryption'; | |||||||
| import { tool as bip39 } from './bip39-generator'; | import { tool as bip39 } from './bip39-generator'; | ||||||
| import { tool as dateTimeConverter } from './date-time-converter'; | import { tool as dateTimeConverter } from './date-time-converter'; | ||||||
| import { tool as gitMemo } from './git-memo'; | import { tool as gitMemo } from './git-memo'; | ||||||
|  | import { tool as baseConverter } from './integer-base-converter'; | ||||||
| 
 | 
 | ||||||
| export const toolsByCategory: ToolCategory[] = [ | export const toolsByCategory: ToolCategory[] = [ | ||||||
|   { |   { | ||||||
| @ -19,7 +20,7 @@ export const toolsByCategory: ToolCategory[] = [ | |||||||
|   { |   { | ||||||
|     name: 'Converter', |     name: 'Converter', | ||||||
|     icon: LockOpen, |     icon: LockOpen, | ||||||
|     components: [dateTimeConverter, romanNumeralConverter], |     components: [dateTimeConverter, baseConverter, romanNumeralConverter], | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     name: 'Development', |     name: 'Development', | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								src/tools/integer-base-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/tools/integer-base-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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, | ||||||
|  | }; | ||||||
| @ -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'); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -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'; | ||||||
|  | } | ||||||
							
								
								
									
										68
									
								
								src/tools/integer-base-converter/integer-base-converter.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/tools/integer-base-converter/integer-base-converter.vue
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user