Hex to binary

Here's a hex to binary converter with a bold, retro-terminal aesthetic: import { useState, useCallback } from "react"; const HEX_CHARS = "0123456789ABCDEFabcdef"; function hexToBinary(hex) { const clean = hex.replace(/\s+/g, "").replace(/^0x/i, ""); if (!clean) return { binary: "", groups: [] }; const groups = []; for (const char of clean.toUpperCase()) { if (!HEX_CHARS.includes(char)) return { error: `Invalid hex character: '${char}'` }; const bin = parseInt(char, 16).toString(2).padStart(4, "0"); groups.push({ hex: char, bin }); } const binary = groups.map(g => g.bin).join(" "); return { binary, groups, clean }; } function binaryToHex(bin) { const clean = bin.replace(/\s+/g, ""); if (!clean) return { hex: "", groups: [] }; if (!/^[01]+$/.test(clean)) return { error: "Invalid binary: only 0s and 1s allowed" }; const padded = clean.padStart(Math.ceil(clean.length / 4) * 4, "0"); const groups = []; for (let i = 0; i < padded.length; i += 4) { const nibble = padded.slice(i, i + 4); const hexChar = parseInt(nibble, 2).toString(16).toUpperCase(); groups.push({ hex: hexChar, bin: nibble }); } return { hex: groups.map(g => g.hex).join(""), groups }; } export default function App() { const [hexInput, setHexInput] = useState(""); const [binInput, setBinInput] = useState(""); const [hexResult, setHexResult] = useState(null); const [binResult, setBinResult] = useState(null); const [copied, setCopied] = useState(null); const [activeTab, setActiveTab] = useState("hex"); const handleHexChange = useCallback((val) => { setHexInput(val); setHexResult(val.trim() ? hexToBinary(val) : null); }, []); const handleBinChange = useCallback((val) => { setBinInput(val); setBinResult(val.trim() ? binaryToHex(val) : null); }, []); const copy = (text, id) => { navigator.clipboard.writeText(text); setCopied(id); setTimeout(() => setCopied(null), 1500); }; const styles = { page: { minHeight: "100vh", background: "#0a0a0a", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", fontFamily: "'Courier New', monospace", padding: "24px", position: "relative", overflow: "hidden", }, scanlines: { position: "fixed", inset: 0, pointerEvents: "none", zIndex: 0, background: "repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,255,100,0.015) 2px, rgba(0,255,100,0.015) 4px)", }, card: { position: "relative", zIndex: 1, width: "100%", maxWidth: 680, border: "1px solid #1a3a1a", borderRadius: 4, background: "#0d0d0d", boxShadow: "0 0 40px rgba(0,255,80,0.08), inset 0 0 60px rgba(0,0,0,0.5)", }, header: { borderBottom: "1px solid #1a3a1a", padding: "16px 24px", display: "flex", alignItems: "center", gap: 12, }, dot: (color) => ({ width: 10, height: 10, borderRadius: "50%", background: color }), title: { color: "#00ff55", fontSize: 13, letterSpacing: "0.2em", textTransform: "uppercase", marginLeft: 8, textShadow: "0 0 10px rgba(0,255,85,0.5)", }, tabs: { display: "flex", borderBottom: "1px solid #1a3a1a", }, tab: (active) => ({ flex: 1, padding: "12px 0", background: "transparent", border: "none", color: active ? "#00ff55" : "#2a4a2a", fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase", cursor: "pointer", fontFamily: "inherit", borderBottom: active ? "2px solid #00ff55" : "2px solid transparent", transition: "all 0.2s", textShadow: active ? "0 0 8px rgba(0,255,85,0.4)" : "none", }), body: { padding: 24 }, label: { color: "#2a6a2a", fontSize: 10, letterSpacing: "0.25em", textTransform: "uppercase", marginBottom: 8, display: "block", }, input: { width: "100%", background: "#050505", border: "1px solid #1a3a1a", borderRadius: 3, color: "#00ff55", fontFamily: "inherit", fontSize: 16, padding: "14px 16px", outline: "none", boxSizing: "border-box", caretColor: "#00ff55", letterSpacing: "0.05em", transition: "border-color 0.2s, box-shadow 0.2s", }, arrow: { display: "flex", justifyContent: "center", alignItems: "center", padding: "12px 0", color: "#1a5a1a", fontSize: 20, }, resultBox: (hasError) => ({ background: "#050505", border: `1px solid ${hasError ? "#3a1a1a" : "#1a3a1a"}`, borderRadius: 3, padding: "14px 16px", minHeight: 52, display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12, }), resultText: (hasError) => ({ color: hasError ? "#ff4444" : "#00ff55", fontSize: 13, letterSpacing: "0.12em", lineHeight: 1.8, flex: 1, wordBreak: "break-all", textShadow: hasError ? "none" : "0 0 8px rgba(0,255,85,0.3)", }), copyBtn: (done) => ({ background: "transparent", border: `1px solid ${done ? "#00ff55" : "#1a3a1a"}`, borderRadius: 2, color: done ? "#00ff55" : "#2a5a2a", fontSize: 9, letterSpacing: "0.15em", textTransform: "uppercase", padding: "4px 8px", cursor: "pointer", fontFamily: "inherit", flexShrink: 0, transition: "all 0.2s", }), nibbles: { display: "flex", flexWrap: "wrap", gap: 8, marginTop: 14, }, nibble: { background: "#050505", border: "1px solid #152515", borderRadius: 2, padding: "6px 10px", textAlign: "center", }, nibbleHex: { color: "#00cc44", fontSize: 14, letterSpacing: "0.1em", display: "block", marginBottom: 4, }, nibbleBin: { color: "#005522", fontSize: 10, letterSpacing: "0.1em", }, examples: { marginTop: 20, paddingTop: 16, borderTop: "1px solid #0f2a0f", display: "flex", gap: 8, flexWrap: "wrap", }, exLabel: { color: "#1a4a1a", fontSize: 9, letterSpacing: "0.2em", width: "100%", textTransform: "uppercase", marginBottom: 4, }, exBtn: { background: "transparent", border: "1px solid #152515", borderRadius: 2, color: "#2a6a2a", fontSize: 10, letterSpacing: "0.1em", padding: "4px 10px", cursor: "pointer", fontFamily: "inherit", transition: "all 0.15s", }, }; const hexExamples = ["FF", "A5", "DEAD", "0xFF", "C0DE"]; const binExamples = ["1010", "11001100", "11111111", "10101010"]; return (
hex ↔ binary converter
{activeTab === "hex" ? ( <> handleHexChange(e.target.value)} placeholder="e.g. FF or 0xDEAD" spellCheck={false} autoComplete="off" />
{hexResult?.error ? (
⚠ {hexResult.error}
) : (
{hexResult?.binary || awaiting input...} {hexResult?.binary && ( )}
)} {hexResult?.groups?.length > 0 && (
{hexResult.groups.map((g, i) => (
{g.hex} {g.bin}
))}
)}
try an example {hexExamples.map(ex => ( ))}
) : ( <> handleBinChange(e.target.value)} placeholder="e.g. 11001010" spellCheck={false} autoComplete="off" />
{binResult?.error ? (
⚠ {binResult.error}
) : (
{binResult?.hex ? `0x${binResult.hex}` : awaiting input...} {binResult?.hex && ( )}
)} {binResult?.groups?.length > 0 && (
{binResult.groups.map((g, i) => (
{g.hex} {g.bin}
))}
)}
try an example {binExamples.map(ex => ( ))}
)}
); } Features: Hex → Binary and Binary → Hex conversion via tabs Nibble-by-nibble breakdown showing each hex digit mapped to its 4-bit group Handles 0x prefixes and spaces gracefully Inline error messages for invalid characters One-click copy button for results Quick-fill example buttons to try common values

Comments

Popular posts from this blog

SDG 2 - 0 hunger not achived

рдорд░ाрдаी рднाрд╖ा рджिрди рдЪिрд░ाрдпू рд╣ोрд╡ो- 2