11<!DOCTYPE html>
22< html lang ="en ">
3+
34< head >
45 < meta charset ="UTF-8 ">
56 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6- < title > 64 Magic</ title >
77 <!-- Bootstrap CSS -->
88 < link href ="
https://cdn.jsdelivr.net/npm/[email protected] /dist/css/bootstrap.min.css "
rel ="
stylesheet "
> 99 < link rel ="
stylesheet "
href ="
https://cdn.jsdelivr.net/npm/[email protected] /font/bootstrap-icons.min.css "
> 10+ <!-- Basic Meta Tags -->
11+ < meta charset ="UTF-8 ">
12+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
13+ < meta http-equiv ="X-UA-Compatible " content ="ie=edge ">
14+ < link rel ="icon " type ="image/x-icon " href ="./key-fill.svg ">
15+ <!-- Title Tag (SEO) -->
16+ < title > 64 Magic - Convert and Compress Strings to Base64</ title >
17+
18+ <!-- Meta Description (SEO) -->
19+ < meta name ="description "
20+ content ="64 Magic is a tool that allows you to convert normal strings to Base64 encoding and compress them for efficient storage or transmission. ">
21+
22+ <!-- Meta Tags for SEO -->
23+ < meta name ="keywords "
24+ content ="Base64, Compression, String Encoder, Base64 Converter, Data Compression, Text Converter ">
25+
26+ <!-- Open Graph Meta Tags (For Facebook and LinkedIn sharing) -->
27+ < meta property ="og:title " content ="64 Magic - Convert and Compress Strings to Base64 ">
28+ < meta property ="og:description "
29+ content ="64 Magic is a tool that lets you convert any string to Base64 encoding and compress it for more efficient storage. Perfect for handling long strings with ease. ">
30+ < meta property ="og:image " content ="URL_TO_YOUR_IMAGE_THUMBNAIL ">
31+ < meta property ="og:url " content ="https://your-site-url.com ">
32+ < meta property ="og:type " content ="website ">
33+
34+ <!-- Twitter Meta Tags (For Twitter Card) -->
35+ < meta name ="twitter:card " content ="summary_large_image ">
36+ < meta name ="twitter:title " content ="64 Magic - Convert and Compress Strings to Base64 ">
37+ < meta name ="twitter:description "
38+ content ="64 Magic allows you to convert any text to Base64 encoding and compress it for efficient transmission. ">
39+ < meta name ="twitter:image " content ="URL_TO_YOUR_IMAGE_THUMBNAIL ">
40+ < meta name ="twitter:url " content ="https://your-site-url.com ">
41+
42+ <!-- Author Meta Tag -->
43+ < meta name ="author " content ="Utshab Luitel ">
44+
45+ <!-- Robots Meta Tag -->
46+ < meta name ="robots " content ="index, follow ">
47+
1048 < style >
1149 body {
1250 font-family : Arial, sans-serif;
1351 padding : 20px ;
1452 background-color : # dedede7a ;
1553 }
54+
1655 .container {
1756 max-width : 900px ;
1857 margin : 0 auto;
1958 }
59+
2060 .row {
2161 display : flex;
2262 gap : 20px ;
2363 }
64+
2465 .copy-btn {
2566 cursor : pointer;
2667 padding : 8px 16px ;
2970 border : none;
3071 border-radius : 4px ;
3172 }
73+
3274 .copy-btn : hover {
3375 background-color : # 0056b3 ;
3476 }
77+
3578 .action-btn {
3679 background-color : # 28a745 ;
3780 color : white;
3881 }
82+
3983 .action-btn : hover {
4084 background-color : # 218838 ;
4185 }
86+
4287 textarea {
4388 width : 100% ;
4489 min-height : 100vh ;
4590 }
91+
4692 .col-md-6 {
4793 flex : 1 ;
4894 }
4995 </ style >
5096</ head >
97+
5198< body >
5299 < div class ="container-fluid ">
53100 < div class ="row ">
54- <!-- Left Side: Input Textarea -->
55-
101+ < div class ="col-12 justify-align-center justify-item-center ">
102+ < h1 class ="text-center "> < i class ="bi bi-key-fill text-primary " style ="font-size: 56px; "> </ i > </ h1 >
103+ < p class ="text-center "> < strong > 64 Magic</ strong > </ br > is a simple yet powerful tool that converts
104+ regular strings into Base64 encoding and applies compression for more efficient storage or
105+ transmission. It ensures that large or sensitive text data can be safely encoded and reduced in
106+ size, making it ideal for transferring or storing long strings in a compact format.</ p >
107+ </ div >
108+
56109 < div class ="col-md-6 ">
57110 < div class ="d-flex flex-row-reverse gap-2 ">
58111 < div >
59- < button class ="btn btn-success " id ="encryptBtn "> < i class ="bi bi-arrow-right "> </ i > </ button >
112+ < button class ="btn btn-success btn-block " id ="encryptBtn "> < i
113+ class ="bi bi-arrow-right "> </ i > </ button >
60114 </ div >
61115 < div >
62- < button class ="btn btn-light " onclick ="copyToClipboard('inputText') "> < i class ="bi bi-copy "> </ i > </ button >
116+ < button class ="btn btn-light " onclick ="copyToClipboard('inputText') "> < i
117+ class ="bi bi-copy "> </ i > </ button >
63118 </ div >
64- </ div >
119+ </ div >
65120 < div class ="mt-2 ">
66- < textarea id ="inputText " rows ="25 " class ="form-control w-100 " placeholder ="Enter string here "> </ textarea >
121+ < textarea id ="inputText " rows ="25 " class ="form-control w-100 "
122+ placeholder ="Enter string here "> </ textarea >
67123 < p id ="inputSize "> 0 bytes</ p >
124+ < small class ="text-denger " id ="inputError "> </ small >
68125 </ div >
69-
70-
126+
127+
71128 </ div >
72129 <!-- Right Side: Output Textarea -->
73130 < div class ="col-md-6 ">
74131 < div class ="d-flex flex-row-reverse gap-2 ">
75132 < div class ="me-2 ">
76- < button class ="btn btn-success " id ="decryptBtn "> < i class ="bi bi-arrow-left "> </ i > </ button >
133+ < button class ="btn btn-success btn-block " id ="decryptBtn "> < i
134+ class ="bi bi-arrow-left "> </ i > </ button >
77135 </ div >
78136 < div >
79- < button class ="btn btn-light " onclick ="copyToClipboard('outputText') "> < i class ="bi bi-copy "> </ i > </ button >
137+ < button class ="btn btn-light " onclick ="copyToClipboard('outputText') "> < i
138+ class ="bi bi-copy "> </ i > </ button >
80139 </ div >
81- </ div >
82- < div class ="mt-2 ">
83- < textarea id ="outputText " rows ="25 " class ="form-control w-100 " placeholder ="64 Magic will appear here "> </ textarea >
84- < p id ="outputSize "> 0 bytes</ p >
85- </ div >
140+ </ div >
141+ < div class ="mt-2 ">
142+ < textarea id ="outputText " rows ="25 " class ="form-control w-100 "
143+ placeholder ="64 Magic string will appear here, or you can put string get your string "> </ textarea >
144+ < p id ="outputSize "> 0 bytes</ p >
145+ < small class ="text-danger " id ="outputError "> </ small >
146+ </ div >
86147 </ div >
87148 </ div >
88149
89-
150+ < p class ="text-center "> Build in an hour and made with < i class ="bi bi-heart-fill text-danger "> </ i > by < span
151+ class ="text-secondary "> Utshab Luitel </ span > < a href ="https://github.com/utdevnp "
152+ target ="_blank "> @utdevnp </ a > </ p >
90153 </ div >
91154
92155 <!-- Bootstrap JS and dependencies (optional) -->
93156 < script src ="
https://cdn.jsdelivr.net/npm/@popperjs/[email protected] /dist/umd/popper.min.js "
> </ script > 94157 < script src ="
https://cdn.jsdelivr.net/npm/[email protected] /dist/js/bootstrap.min.js "
> </ script > 158+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js "> </ script >
159+
95160
96161 < script >
97162
98163 // Handle Encryption (Encoding)
99- document . getElementById ( 'encryptBtn' ) . addEventListener ( 'click' , ( ) => {
164+ document . getElementById ( 'encryptBtn' ) . addEventListener ( 'click' , async ( ) => {
100165 const inputText = document . getElementById ( 'inputText' ) . value . trim ( ) ;
101166 getSize ( "outputText" , "outputSize" ) ;
102167 // If the input is a regular string, encode it to Base64
103- if ( inputText && ! isBase64 ( inputText ) ) {
104- const encodedText = btoa ( inputText ) ;
105- document . getElementById ( 'outputText' ) . value = encodedText ;
106- } else {
107- alert ( 'Please enter a valid .env string for encoding.' ) ;
168+ try {
169+ document . getElementById ( 'outputText' ) . value = await base64Encrypt ( inputText ) ;
170+ } catch ( error ) {
171+ document . getElementById ( "inputError" ) . innerText = "Unable to validate string ..." ;
108172 }
109173 } ) ;
110174
111175 // Handle Decryption (Decoding)
112- document . getElementById ( 'decryptBtn' ) . addEventListener ( 'click' , ( ) => {
176+ document . getElementById ( 'decryptBtn' ) . addEventListener ( 'click' , async ( ) => {
113177 const inputText = document . getElementById ( 'outputText' ) . value . trim ( ) ;
114178 getSize ( "inputText" , "inputSize" ) ;
115- getSize ( "outputText" , "outputSize" ) ;
116- // If the input is Base64, decode it
117- if ( isBase64 ( inputText ) ) {
118- try {
119- const decodedText = atob ( inputText ) ;
120- document . getElementById ( 'inputText' ) . value = decodedText ;
121- } catch ( error ) {
122- alert ( 'Invalid Base64 string.' ) ;
123- }
124- } else {
125- alert ( 'Please enter a valid Base64 string to decode.' ) ;
179+
180+ try {
181+ document . getElementById ( 'inputText' ) . value = await base64Decrypt ( inputText ) ;
182+ } catch ( error ) {
183+ document . getElementById ( "outputError" ) . innerText = "Invalid Base64 string. Please enter valid base64 and try again..." ;
126184 }
127185 } ) ;
128186
129- document . getElementById ( "inputText" ) . addEventListener ( "change" , ( ) => {
130- getSize ( "inputText" , "inputSize" ) ;
131- getSize ( "outputText" , "outputSize" ) ;
132- } )
187+ async function getSize ( fieldId , sizeId ) {
188+ const input = await document . getElementById ( fieldId ) . value ;
189+ const result = await calculateStringSize ( input ) ;
190+ if ( result ) {
191+ document . getElementById ( sizeId ) . innerText = `${ result } bytes` ;
192+ }
133193
134- document . getElementById ( "outputText" ) . addEventListener ( "change" , ( ) => {
135- getSize ( "inputText" , "inputSize" ) ;
136- getSize ( "outputText" , "outputSize" ) ;
137- } )
138- function getSize ( fieldId , sizeId ) {
139- const input = document . getElementById ( fieldId ) . value ;
140- const result = calculateStringSize ( input ) ;
141- document . getElementById ( sizeId ) . innerHTML = `${ result } bytes` ;
142194 }
143-
144- // Function to check if a string is valid Base64
145- function isBase64 ( str ) {
146- try {
147- return btoa ( atob ( str ) ) === str ;
148- } catch ( err ) {
149- return false ;
150- }
195+
196+ // Base64 Encoding (Encrypt) Function
197+ function base64Encrypt ( str ) {
198+ // Convert the string to a Uint8Array (UTF-8 encoding)
199+ const encoder = new TextEncoder ( ) ;
200+ const data = encoder . encode ( str ) ;
201+ const compressedData = pako . gzip ( data ) ;
202+ // Convert the Uint8Array to a base64-encoded string
203+ return btoa ( String . fromCharCode ( ...compressedData ) ) ;
204+ }
205+
206+ // Base64 Decoding (Decrypt) Function
207+ function base64Decrypt ( base64Str ) {
208+ // Decode the base64 string to binary (Uint8Array)
209+ const compressedData = new Uint8Array ( atob ( base64Str ) . split ( "" ) . map ( c => c . charCodeAt ( 0 ) ) ) ;
210+ return pako . ungzip ( compressedData , { to : 'string' } ) ;
151211 }
152212
153213 // Calculate string
154- function calculateStringSize ( str ) {
214+ async function calculateStringSize ( str ) {
155215 const blob = new Blob ( [ str ] ) ;
156- return blob . size ;
216+ return await blob . size ;
157217 }
158218
159219 // Function to copy the output text to clipboard
160220 function copyToClipboard ( id ) {
161221 const textArea = document . getElementById ( id ) ;
162222 textArea . select ( ) ;
163223 document . execCommand ( 'copy' ) ;
164- alert ( 'Copied to clipboard!' ) ;
165224 }
166225 </ script >
167226</ body >
168- </ html >
227+
228+ </ html >
0 commit comments