Skip to content

Commit ff12182

Browse files
author
devanshu
committed
Enhance URLEncoderDecoder: strong encoding, improved contrast, added hover arrow
1 parent cfd9d6f commit ff12182

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import React, { useState, useEffect } from "react";
2+
import { FaCopy, FaSyncAlt, FaTrashAlt } from "react-icons/fa";
3+
4+
// Simple XOR-based obfuscation with key (optional)
5+
const xorEncrypt = (text, key = 129) => {
6+
return text
7+
.split("")
8+
.map((c) => String.fromCharCode(c.charCodeAt(0) ^ key))
9+
.join("");
10+
};
11+
12+
const toBase64Url = (str) => {
13+
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
14+
};
15+
16+
const fromBase64Url = (str) => {
17+
str = str.replace(/-/g, "+").replace(/_/g, "/");
18+
while (str.length % 4) str += "=";
19+
return atob(str);
20+
};
21+
22+
const URLEncoderDecoder = () => {
23+
const [input, setInput] = useState("");
24+
const [output, setOutput] = useState("");
25+
const [mode, setMode] = useState("encode"); // "encode" or "decode"
26+
const [auto, setAuto] = useState(true);
27+
28+
const handleConvert = () => {
29+
try {
30+
if (mode === "encode") {
31+
const encrypted = xorEncrypt(input);
32+
setOutput(toBase64Url(encrypted));
33+
} else {
34+
const decrypted = xorEncrypt(fromBase64Url(input));
35+
setOutput(decrypted);
36+
}
37+
} catch (e) {
38+
setOutput("❌ Invalid input");
39+
}
40+
};
41+
42+
const handleCopy = () => navigator.clipboard.writeText(output);
43+
const handleClear = () => {
44+
setInput("");
45+
setOutput("");
46+
};
47+
48+
useEffect(() => {
49+
if (auto && input.trim() !== "") handleConvert();
50+
if (!input.trim()) setOutput("");
51+
}, [input, mode, auto]);
52+
53+
return (
54+
<div className="p-10 min-h-screen bg-gray-900 text-white rounded-2xl shadow-xl">
55+
<h1 className="text-3xl font-bold mb-6 text-center">
56+
🔒 Advanced URL Encoder / Decoder
57+
</h1>
58+
59+
{/* Controls */}
60+
<div className="flex flex-col md:flex-row justify-between items-center gap-4 mb-6">
61+
<div className="flex gap-3">
62+
<button
63+
className={`px-4 py-2 rounded-md font-medium transition ${
64+
mode === "encode"
65+
? "bg-green-500 text-white"
66+
: "bg-gray-700 hover:bg-gray-600 text-white"
67+
}`}
68+
onClick={() => setMode("encode")}
69+
>
70+
Encode
71+
</button>
72+
<button
73+
className={`px-4 py-2 rounded-md font-medium transition ${
74+
mode === "decode"
75+
? "bg-blue-500 text-white"
76+
: "bg-gray-700 hover:bg-gray-600 text-white"
77+
}`}
78+
onClick={() => setMode("decode")}
79+
>
80+
Decode
81+
</button>
82+
</div>
83+
84+
<div className="flex items-center gap-2">
85+
<label className="flex items-center gap-2 text-sm text-gray-300">
86+
<input
87+
type="checkbox"
88+
checked={auto}
89+
onChange={() => setAuto(!auto)}
90+
className="accent-green-500"
91+
/>
92+
Auto mode
93+
</label>
94+
<button
95+
onClick={handleConvert}
96+
className="flex items-center gap-2 px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded-md transition"
97+
>
98+
<FaSyncAlt /> Convert
99+
</button>
100+
</div>
101+
</div>
102+
103+
{/* Input */}
104+
<textarea
105+
className="w-full p-3 border border-gray-600 rounded-md bg-gray-800 text-black placeholder-green-400 focus:outline-none focus:ring-2 focus:ring-green-500 h-40 resize-none"
106+
placeholder="Enter text or URL here..."
107+
value={input}
108+
onChange={(e) => setInput(e.target.value)}
109+
/>
110+
111+
{/* Output */}
112+
<div className="mt-6 relative">
113+
<textarea
114+
className="w-full p-3 border border-gray-600 rounded-md bg-gray-700 text-black font-mono focus:outline-none h-40 resize-none"
115+
readOnly
116+
value={output}
117+
placeholder="Output will appear here..."
118+
/>
119+
<div className="absolute top-2 right-2 flex gap-2">
120+
<button
121+
onClick={handleCopy}
122+
className="p-2 bg-gray-600 hover:bg-gray-500 rounded-md transition"
123+
title="Copy"
124+
>
125+
<FaCopy />
126+
</button>
127+
<button
128+
onClick={handleClear}
129+
className="p-2 bg-gray-600 hover:bg-gray-500 rounded-md transition"
130+
title="Clear"
131+
>
132+
<FaTrashAlt />
133+
</button>
134+
</div>
135+
</div>
136+
</div>
137+
);
138+
};
139+
140+
export default URLEncoderDecoder;

0 commit comments

Comments
 (0)