-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathHex-To-Text-Decoder.html
More file actions
156 lines (136 loc) · 6.44 KB
/
Hex-To-Text-Decoder.html
File metadata and controls
156 lines (136 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hex to Text Decoder</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
textarea, pre {
font-family: 'Fira Code', monospace;
}
</style>
</head>
<body class="bg-gray-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
<div class="w-full max-w-4xl bg-gray-800 rounded-xl shadow-2xl p-6 md:p-8 space-y-6">
<!-- Header -->
<div class="text-center">
<h1 class="text-3xl md:text-4xl font-bold text-white">Hex to Text Decoder</h1>
<p class="text-gray-400 mt-2">Paste a hex string, choose an encoding, and see the result.</p>
</div>
<!-- Controls -->
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<div class="flex-grow">
<label for="encoding" class="block text-sm font-medium text-gray-400 mb-1">Encoding</label>
<select id="encoding" class="w-full bg-gray-700 border border-gray-600 text-white rounded-md p-2.5 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
<option value="utf-8" selected>UTF-8</option>
<option value="utf-16le">UTF-16 (Little Endian)</option>
<option value="utf-16be">UTF-16 (Big Endian)</option>
<option value="windows-1252">Windows-1252</option>
<option value="iso-8859-1">ISO-8859-1</option>
<option value="latin1">Latin-1</option>
</select>
</div>
<div class="self-end sm:self-center">
<button id="decodeBtn" class="w-full sm:w-auto bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2.5 px-6 rounded-md transition duration-200 transform hover:scale-105">
Decode
</button>
</div>
</div>
<!-- Input and Output Panes -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Hex Input -->
<div>
<label for="hexInput" class="block text-lg font-medium text-gray-300 mb-2">Hex Input</label>
<textarea id="hexInput" rows="12" class="w-full bg-gray-900 border border-gray-600 rounded-md p-4 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition" placeholder="48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21"></textarea>
</div>
<!-- Text Output -->
<div>
<label for="textOutput" class="block text-lg font-medium text-gray-300 mb-2">Decoded Text</label>
<div class="w-full h-full bg-gray-900 border border-gray-600 rounded-md p-4 min-h-[288px]">
<pre id="textOutput" class="whitespace-pre-wrap break-words"></pre>
</div>
</div>
</div>
<!-- Error Message Area -->
<div id="errorContainer" class="bg-red-900/50 border border-red-700 text-red-300 p-4 rounded-md hidden">
<p id="errorMessage"></p>
</div>
</div>
<script>
const hexInput = document.getElementById('hexInput');
const encodingSelect = document.getElementById('encoding');
const decodeBtn = document.getElementById('decodeBtn');
const textOutput = document.getElementById('textOutput');
const errorContainer = document.getElementById('errorContainer');
const errorMessage = document.getElementById('errorMessage');
/**
* Hides the error message container.
*/
function hideError() {
errorContainer.classList.add('hidden');
errorMessage.textContent = '';
}
/**
* Shows a specific error message.
* @param {string} message - The error message to display.
*/
function showError(message) {
errorMessage.textContent = message;
errorContainer.classList.remove('hidden');
}
/**
* Main function to decode the hex string.
*/
function decodeHex() {
hideError();
textOutput.textContent = ''; // Clear previous output
// 1. Get hex string and remove all whitespace
const rawHex = hexInput.value;
if (!rawHex) return;
const cleanHex = rawHex.replace(/\s/g, '');
// 2. Validate the cleaned hex string
if (cleanHex.length % 2 !== 0) {
showError('Invalid hex string: Must have an even number of characters.');
return;
}
if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {
showError('Invalid hex string: Contains non-hexadecimal characters.');
return;
}
// 3. Convert hex string to a byte array (Uint8Array)
const bytes = new Uint8Array(cleanHex.length / 2);
for (let i = 0; i < cleanHex.length; i += 2) {
const byteValue = parseInt(cleanHex.substr(i, 2), 16);
bytes[i / 2] = byteValue;
}
// 4. Decode the byte array using the selected encoding
const encoding = encodingSelect.value;
try {
const decoder = new TextDecoder(encoding, { fatal: true });
const decodedText = decoder.decode(bytes);
textOutput.textContent = decodedText;
} catch (error) {
console.error('Decoding error:', error);
showError(`Decoding failed. The byte sequence may not be valid for the selected encoding (${encoding}).`);
}
}
// Event Listeners
decodeBtn.addEventListener('click', decodeHex);
// Also decode when the user changes the encoding, if there's input
encodingSelect.addEventListener('change', () => {
if (hexInput.value) {
decodeHex();
}
});
// Clear error when user starts typing again
hexInput.addEventListener('input', hideError);
</script>
</body>
</html>