Add Convert Base
This commit is contained in:
parent
ae88316635
commit
467e86bb25
46
package.json
46
package.json
@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "vite-template-solid",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||
"@typescript-eslint/parser": "^6.9.0",
|
||||
"eslint": "^8.52.0",
|
||||
"solid-devtools": "^0.27.3",
|
||||
"typescript": "^5.1.3",
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@solidjs/router": "^0.8.3",
|
||||
"solid-js": "^1.7.6"
|
||||
}
|
||||
"name": "vite-template-solid",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||
"@typescript-eslint/parser": "^6.9.0",
|
||||
"eslint": "^8.52.0",
|
||||
"solid-devtools": "^0.27.3",
|
||||
"typescript": "^5.1.3",
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@solidjs/router": "^0.8.3",
|
||||
"solid-js": "^1.7.6"
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ const Navigation: Component = () => {
|
||||
<A href='/strrev'>String Reverse</A>
|
||||
<A href='/strnoise'>String Noise</A>
|
||||
<A href='/loremipsum'>Lorem Ipsum</A>
|
||||
<A href='/convertbase'>Convert Base</A>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -8,6 +8,8 @@ import StrLen from './pages/StrLen';
|
||||
import StrRev from './pages/StrRev';
|
||||
import StrNoise from './pages/StrNoise';
|
||||
import LoremIpsum from './pages/LoremIpsum';
|
||||
import Convert from './pages/ConvertBase';
|
||||
import ConvertBase from './pages/ConvertBase';
|
||||
|
||||
const root = document.getElementById('root');
|
||||
|
||||
@ -25,6 +27,7 @@ render(() => (
|
||||
<Route path="/strrev" component={StrRev} />
|
||||
<Route path="/strnoise" component={StrNoise} />
|
||||
<Route path="/loremipsum" component={LoremIpsum} />
|
||||
<Route path="/convertbase" component={ConvertBase} />
|
||||
</Routes>
|
||||
</Router>
|
||||
), root!);
|
||||
|
102
src/pages/ConvertBase.tsx
Normal file
102
src/pages/ConvertBase.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
import { Component, Setter, createEffect, createSignal, on } from 'solid-js';
|
||||
|
||||
import styles from './Page.module.css';
|
||||
import Navigation from '../Navigation';
|
||||
|
||||
function group(str: string, groupSize: number) {
|
||||
const subs = [];
|
||||
for (let i = 0; i < Math.ceil(str.length / groupSize); i++) {
|
||||
let sub = str.slice(Math.max(0, str.length - i * groupSize - groupSize), str.length - i * groupSize);
|
||||
while (sub.length < groupSize) sub = '0' + sub;
|
||||
subs.push(sub);
|
||||
}
|
||||
|
||||
return subs.reverse().join(' ');
|
||||
}
|
||||
|
||||
function parse(value: string, base: number) {
|
||||
return [...value].reduce((r, v) => r * BigInt(base) + BigInt(parseInt(v, base)), 0n);
|
||||
}
|
||||
|
||||
const ConvertBase: Component = () => {
|
||||
const [error, setError] = createSignal(' ');
|
||||
const [value, setValue] = createSignal(BigInt(0));
|
||||
const [decimal, setDecimal] = createSignal('0');
|
||||
const [binary, setBinary] = createSignal('0');
|
||||
const [binaryOctets, setBinaryOctet] = createSignal(true);
|
||||
const [octal, setOctal] = createSignal('0');
|
||||
const [octalTriplets, setOctalTriplet] = createSignal(true);
|
||||
const [hex, setHex] = createSignal('0');
|
||||
const [hexPairs, setHexPairs] = createSignal(true);
|
||||
|
||||
function updateExcept(value: string, base: number, except: Setter<string>) {
|
||||
const raw = value.replaceAll(/ /g, '');
|
||||
|
||||
setError('');
|
||||
|
||||
if (base == 2) { // TODO: common validation method
|
||||
if ([...raw].find(c => !['0', '1'].includes(c))) {
|
||||
setError('Invalid binary number');
|
||||
return;
|
||||
}
|
||||
} else if (base == 8) {
|
||||
if ([...raw].find(c => !['0', '1', '2', '3', '4', '5', '6', '7'].includes(c))) {
|
||||
setError('Invalid octal number');
|
||||
return;
|
||||
}
|
||||
} else if (base == 10) {
|
||||
if ([...raw].find(c => !['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(c))) {
|
||||
setError('Invalid decimal number');
|
||||
return;
|
||||
}
|
||||
} else if (base == 16) {
|
||||
if ([...raw].find(c => !['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'].includes(c))) {
|
||||
setError('Invalid hex number');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const num = parse(raw, base);
|
||||
|
||||
setValue(num);
|
||||
if (setDecimal != except) setDecimal(num.toString());
|
||||
if (setBinary != except) setBinary(binaryOctets() ? group(num.toString(2), 8) : num.toString(2));
|
||||
if (setOctal != except) setOctal(octalTriplets() ? group(num.toString(8), 3) : num.toString(8));
|
||||
if (setHex != except) setHex(hexPairs() ? group(num.toString(16), 2) : num.toString(16));
|
||||
}
|
||||
|
||||
createEffect(on(binaryOctets, () => setBinary(binaryOctets() ? group(value().toString(2), 8) : value().toString(2))));
|
||||
createEffect(on(octalTriplets, () => setOctal(octalTriplets() ? group(value().toString(8), 3) : value().toString(8))));
|
||||
createEffect(on(hexPairs, () => setHex(hexPairs() ? group(value().toString(16), 2) : value().toString(16))));
|
||||
|
||||
return (
|
||||
<div class={styles.page}>
|
||||
<h1>Convert</h1>
|
||||
<h2>Bases</h2>
|
||||
<span>{error()}</span>
|
||||
<h3>Decimal</h3>
|
||||
<textarea value={decimal()} oninput={e => updateExcept(e.currentTarget.value, 10, setDecimal)} />
|
||||
<h3>Binary</h3>
|
||||
<textarea value={binary()} oninput={e => updateExcept(e.currentTarget.value, 2, setBinary)} />
|
||||
<div class={styles.checkbox}>
|
||||
<input id={'octets'} type={'checkbox'} checked={binaryOctets()} onchange={e => setBinaryOctet(e.currentTarget.checked)} />
|
||||
<label for={'octets'}>Octets</label>
|
||||
</div>
|
||||
<h3>Octal</h3>
|
||||
<textarea value={octal()} oninput={e => updateExcept(e.currentTarget.value, 8, setOctal)} />
|
||||
<div class={styles.checkbox}>
|
||||
<input id={'triplets'} type={'checkbox'} checked={octalTriplets()} onchange={e => setOctalTriplet(e.currentTarget.checked)} />
|
||||
<label for={'triplets'}>Triplets</label>
|
||||
</div>
|
||||
<textarea value={hex()} oninput={e => updateExcept(e.currentTarget.value, 16, setHex)} />
|
||||
<div class={styles.checkbox}>
|
||||
<input id={'pairs'} type={'checkbox'} checked={hexPairs()} onchange={e => setHexPairs(e.currentTarget.checked)} />
|
||||
<label for={'pairs'}>Pairs</label>
|
||||
</div>
|
||||
<h2>All Tools</h2>
|
||||
<Navigation />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConvertBase;
|
Loading…
Reference in New Issue
Block a user