Download index.html from CVNSS/Bilacode: direct link, hf CLI and curl.
- Browser
- Download file 10.8 kB
-
https://huggingface.co/spaces/CVNSS/Bilacode/resolve/main/index.html
- Command line
-
hf download hf://spaces/CVNSS/Bilacode/index.html
-
curl -L -o index.html https://huggingface.co/spaces/CVNSS/Bilacode/resolve/main/index.html
10.8 kB
| <html lang="vi"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>CVNSS4.0 ⇄ Bila Hex/Nhị phân | Chưa hỗ trợ chuỗi dài</title> | |
| <style> | |
| body { background: #1e2232; font-family: 'Fira Mono', monospace; margin: 0; } | |
| .container { max-width: 760px; margin: 44px auto; background: #181f29; border-radius: 16px; | |
| box-shadow: 0 3px 18px #000c; padding: 32px 24px 24px 24px;} | |
| h2 { color: #e0e7ef; font-weight: 500; margin-bottom: 8px;} | |
| label { font-weight: bold; color: #38bdf8; margin-top: 12px; display: block;} | |
| textarea { width: 100%; font-size: 1em; background: #1e293b; color: #f1f5f9; | |
| border-radius: 7px; padding: 12px; border: 1px solid #334155; | |
| margin-bottom: 14px; min-height: 48px; resize: vertical;} | |
| button { background: #38bdf8; color: #020617; border: none; border-radius: 8px; | |
| padding: 11px 20px; font-size: 1em; font-family: inherit; font-weight: 600; | |
| margin: 7px 13px 7px 0; box-shadow: 0 1px 5px #0891b2aa; transition: 0.12s;} | |
| button:hover { background: #0ea5e9; color: #fff;} | |
| .outblock { background: #222b38; border-radius: 8px; margin-top: 12px; margin-bottom: 10px; } | |
| .outlabel { color: #6ee7b7; font-size: 0.99em; padding: 8px 0 2px 2px; } | |
| .output { color: #e5e5e5; background: none; padding: 8px 8px 4px 8px; font-size: 1.08em; | |
| word-break: break-all; font-family: 'Fira Mono', monospace; min-height: 16px;} | |
| .error { color: #f87171; font-weight: bold; padding: 7px 0 0 0;} | |
| .note { color: #a5b4fc; font-size: 0.97em; margin-top: 12px;} | |
| .byline { text-align: right; margin-top: 26px; color: #64748b; font-size: 0.97em;} | |
| @media (max-width: 800px) { .container {padding: 10px; max-width: 99vw;} } | |
| ::selection { background: #38bdf888; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h2>CVNSS4.0 ⇄ Bila Hex/Nhị phân<br> Hiện chỉ hỗ trợ khoảng 30 ký tự để test</h2> | |
| <label for="ascii">CVNSS4.0:</label> | |
| <textarea id="ascii" placeholder="Nhập chữ cái, số, dấu cách... Chuỗi dài cỡ 50 ký tự đều được!"></textarea> | |
| <button onclick="asciiToCBOR()">CVNSS4.0 → Bila</button> | |
| <button onclick="clearAll()">Xoá</button> | |
| <div class="error" id="err_ascii"></div> | |
| <div class="outblock"> | |
| <div class="outlabel">Bila Hex:</div> | |
| <div class="output" id="cborhex"></div> | |
| <div class="outlabel">Bila Nhị phân:</div> | |
| <div class="output" id="cborbin"></div> | |
| </div> | |
| <label for="cborhex_in">Bila Hex:</label> | |
| <textarea id="cborhex_in" placeholder="Nhập mã Hex hợp lệ (header 78xx, 79xxxx, ... không giới hạn độ dài)"></textarea> | |
| <button onclick="cborHexToAscii()">Bila Hex → CVNSS4.0</button> | |
| <div class="error" id="err_hex"></div> | |
| <label for="cborbin_in">Bila Nhị phân:</label> | |
| <textarea id="cborbin_in" placeholder="Nhập mã Nhị phân hợp lệ"></textarea> | |
| <button onclick="cborBinToAscii()">Bila Nhị phân → CVNSS4.0</button> | |
| <div class="error" id="err_bin"></div> | |
| <div class="outblock"> | |
| <div class="outlabel">Kết quả:</div> | |
| <div class="output" id="ascii_out"></div> | |
| </div> | |
| <div class="note"> | |
| • Nhập/dán tối đa 30-40 ký tự.<br> | |
| • Tự động loại ký tự không hợp lệ (chỉ giữ A–Z, a–z, 0–9, dấu cách).<br> | |
| • Mã Hex dài sẽ tự động dùng header 78xx, 79xxxx theo chuẩn RFC7049.<br> | |
| • Kết quả chưa tương thích sẽ báo lỗi, lấy ký tự CVNSS4.0 (<a href="https://chuvnsongsong.com/" target="_blank" style="color:#38bdf8">Chữ VN Song Song 4.0</a>). | |
| </div> | |
| <div class="byline">© Long Ngo, 2025 – Bản demo đang thử nghiệm</div> | |
| </div> | |
| <script> | |
| // Chặn realtime ký tự lạ khi gõ/dán vào textarea (giữ input sạch) | |
| document.getElementById('ascii').addEventListener('input', function() { | |
| let clean = this.value.replace(/[^A-Za-z0-9 ]+/g, ''); | |
| if(this.value !== clean) { | |
| this.value = clean; | |
| document.getElementById('err_ascii').textContent = '❌ Đã tự động loại bỏ ký tự không hợp lệ!'; | |
| } else { | |
| document.getElementById('err_ascii').textContent = ''; | |
| } | |
| }); | |
| function cleanASCII(s) { | |
| return s.replace(/[\r\n\t\u200B-\u200D\uFEFF]/g, ""); | |
| } | |
| function checkValidASCII(s) { | |
| return /^[A-Za-z0-9 ]+$/.test(s); | |
| } | |
| // Hỗ trợ CBOR chuẩn mọi độ dài: <24, <256, <65536 ký tự | |
| function asciiToCBOR() { | |
| let t = document.getElementById('ascii').value; | |
| document.getElementById('err_ascii').textContent = ""; | |
| if (!t) return showCBOR('', ''); | |
| let tclean = cleanASCII(t); | |
| if (!checkValidASCII(tclean)) { | |
| let wrong = tclean.replace(/[A-Za-z0-9 ]/g, ""); | |
| document.getElementById('err_ascii').textContent = | |
| '❌ Chỉ cho phép A–Z, a–z, 0–9, dấu cách! Ký tự lỗi: [' + wrong.split("").join(" ") + ']'; | |
| showCBOR('', ''); | |
| return; | |
| } | |
| let encoder = new TextEncoder(); | |
| let bytes = encoder.encode(tclean); | |
| let hex = "", b = ""; | |
| if (bytes.length < 24) { | |
| hex = (0x60 + bytes.length).toString(16); | |
| } else if (bytes.length < 256) { | |
| hex = "78" + bytes.length.toString(16).padStart(2, "0"); | |
| } else if (bytes.length < 65536) { | |
| hex = "79" + bytes.length.toString(16).padStart(4, "0"); | |
| } else { | |
| document.getElementById('err_ascii').textContent = '❌ Chuỗi quá dài (tối đa 65.535 ký tự)!'; | |
| showCBOR('', ''); | |
| return; | |
| } | |
| hex += Array.from(bytes).map(x => x.toString(16).padStart(2, "0")).join(''); | |
| b = hex.match(/.{1,2}/g).map(x => parseInt(x, 16).toString(2).padStart(8, '0')).join(''); | |
| showCBOR(hex, b); | |
| } | |
| function cborHexToAscii() { | |
| let hex = document.getElementById('cborhex_in').value | |
| .replace(/[^0-9a-fA-F]/g, '') | |
| .toLowerCase(); | |
| document.getElementById('err_hex').textContent = ""; | |
| if (!hex) return showAscii(''); | |
| if (hex.length % 2 !== 0) { | |
| document.getElementById('err_hex').textContent = '❌ Hex phải có số ký tự chẵn!'; | |
| showAscii(''); | |
| return; | |
| } | |
| if (!/^[0-9a-f]+$/.test(hex)) { | |
| document.getElementById('err_hex').textContent = '❌ Hex không hợp lệ!'; | |
| showAscii(''); | |
| return; | |
| } | |
| try { | |
| let idx=0, l=0, fb=parseInt(hex.substr(idx,2),16); idx+=2; | |
| if ((fb&0xe0)===0x60) l=fb&0x1f; | |
| else if(fb===0x78) { l=parseInt(hex.substr(idx,2),16); idx+=2; } | |
| else if(fb===0x79) { l=parseInt(hex.substr(idx,4),16); idx+=4; } | |
| else { document.getElementById('err_hex').textContent = '❌ Không đúng mã string'; showAscii(''); return; } | |
| let bh = hex.substr(idx, l*2); | |
| if (bh.length<l*2) { | |
| document.getElementById('err_hex').textContent = '❌ Thiếu bytes, cần ' + (l*2) + ' ký tự hex, chỉ có ' + bh.length; | |
| showAscii(''); | |
| return; | |
| } | |
| let bs=[]; | |
| for(let i=0;i<bh.length;i+=2) bs.push(parseInt(bh.substr(i,2),16)); | |
| let s; | |
| try { | |
| s = new TextDecoder().decode(new Uint8Array(bs)); | |
| } catch (e) { | |
| document.getElementById('err_hex').textContent = '❌ Không thể giải mã UTF-8: ' + e.message; | |
| showAscii(''); | |
| return; | |
| } | |
| let clean = cleanASCII(s); | |
| if (!checkValidASCII(clean)) { | |
| let wrong = clean.replace(/[A-Za-z0-9 ]/g, ""); | |
| document.getElementById('err_hex').textContent = | |
| '❌ Dữ liệu nhập không hợp lệ (chỉ cho A–Z, a–z, 0–9, dấu cách)! Ký tự lỗi: [' + | |
| wrong.split("").join(" ") + ']'; | |
| showAscii(''); | |
| return; | |
| } | |
| showAscii(clean); | |
| } catch (err) { | |
| document.getElementById('err_hex').textContent = '❌ Lỗi giải mã: ' + err.message; | |
| showAscii(''); | |
| } | |
| } | |
| function cborBinToAscii() { | |
| let bin = document.getElementById('cborbin_in').value.trim().replace(/\s+/g,''); | |
| document.getElementById('err_bin').textContent = ""; | |
| if (!bin) return showAscii(''); | |
| if (!/^[01]+$/.test(bin)) { document.getElementById('err_bin').textContent = '❌ Nhị phân không hợp lệ!'; showAscii(''); return; } | |
| if (bin.length%8!==0) { document.getElementById('err_bin').textContent = '❌ Chuỗi phải là bội số 8!'; showAscii(''); return; } | |
| try { | |
| let idx=0, l=0, fb=parseInt(bin.substr(idx,8),2); idx+=8; | |
| if ((fb&0xe0)===0x60) l=fb&0x1f; | |
| else if(fb===0x78) { l=parseInt(bin.substr(idx,8),2); idx+=8; } | |
| else if(fb===0x79) { l=parseInt(bin.substr(idx,16),2); idx+=16; } | |
| else { document.getElementById('err_bin').textContent = '❌ Không đúng CBOR string'; showAscii(''); return; } | |
| let bs=[]; | |
| for(let i=0;i<l;i++) { | |
| if(idx+8>bin.length) { document.getElementById('err_bin').textContent = '❌ Thiếu bytes'; showAscii(''); return; } | |
| bs.push(parseInt(bin.substr(idx,8),2)); idx+=8; | |
| } | |
| let s; | |
| try { | |
| s = new TextDecoder().decode(new Uint8Array(bs)); | |
| } catch (e) { | |
| document.getElementById('err_bin').textContent = '❌ Không thể giải mã UTF-8: ' + e.message; | |
| showAscii(''); | |
| return; | |
| } | |
| let clean = cleanASCII(s); | |
| if (!checkValidASCII(clean)) { | |
| let wrong = clean.replace(/[A-Za-z0-9 ]/g, ""); | |
| document.getElementById('err_bin').textContent = | |
| '❌ Dữ liệu nhập không hợp lệ (chỉ cho A–Z, a–z, 0–9, dấu cách)! Ký tự lỗi: [' + | |
| wrong.split("").join(" ") + ']'; | |
| showAscii(''); | |
| return; | |
| } | |
| showAscii(clean); | |
| } catch (err) { | |
| document.getElementById('err_bin').textContent = '❌ Lỗi giải mã: ' + err.message; | |
| showAscii(''); | |
| } | |
| } | |
| function showCBOR(hex, bin) { | |
| document.getElementById('cborhex').textContent = hex; | |
| document.getElementById('cborbin').textContent = bin; | |
| document.getElementById('ascii_out').textContent = ""; | |
| } | |
| function showAscii(ascii) { | |
| document.getElementById('ascii_out').textContent = ascii; | |
| } | |
| function clearAll() { | |
| document.getElementById('ascii').value = ''; | |
| document.getElementById('cborhex_in').value = ''; | |
| document.getElementById('cborbin_in').value = ''; | |
| document.getElementById('err_ascii').textContent = ''; | |
| document.getElementById('err_hex').textContent = ''; | |
| document.getElementById('err_bin').textContent = ''; | |
| showCBOR('', ''); | |
| showAscii(''); | |
| } | |
| </script> | |
| </body> | |
| </html> | |