| 76 | // string -> bytes. Hex stops at the first invalid pair; base64 is |
| 77 | // forgiving (skips invalid characters, '=' terminates), like Node. |
| 78 | const __encodeStr = (string, enc) => { |
| 79 | switch (enc) { |
| 80 | case "utf8": return new TextEncoder().encode(string); |
| 81 | case "latin1": case "ascii": |
| 82 | return Uint8Array.from(string, (c) => c.charCodeAt(0) & 255); |
| 83 | case "utf16le": { |
| 84 | const out = new Uint8Array(string.length * 2); |
| 85 | for (let i = 0; i < string.length; i++) { |
| 86 | const c = string.charCodeAt(i); |
| 87 | out[i * 2] = c & 255; out[i * 2 + 1] = c >>> 8; |
| 88 | } |
| 89 | return out; |
| 90 | } |
| 91 | case "hex": { |
| 92 | const n = string.length >>> 1; |
| 93 | const out = new Uint8Array(n); |
| 94 | let i = 0; |
| 95 | for (; i < n; i++) { |
| 96 | const pair = string.slice(i * 2, i * 2 + 2); |
| 97 | if (!/^[0-9a-fA-F]{2}$/.test(pair)) break; |
| 98 | out[i] = parseInt(pair, 16); |
| 99 | } |
| 100 | return i === n ? out : out.subarray(0, i); |
| 101 | } |
| 102 | default: { // base64 / base64url |
| 103 | const out = []; |
| 104 | let acc = 0, bits = 0; |
| 105 | for (let i = 0; i < string.length; i++) { |
| 106 | const c = string.charCodeAt(i); |
| 107 | if (c === 61) break; // '=' |
| 108 | const v = c < 128 ? __b64lut[c] : -1; |
| 109 | if (v < 0) continue; |
| 110 | acc = (acc << 6) | v; bits += 6; |
| 111 | if (bits >= 8) { bits -= 8; out.push((acc >>> bits) & 255); } |
| 112 | } |
| 113 | return Uint8Array.from(out); |
| 114 | } |
| 115 | } |
| 116 | }; |
| 117 | const __decodeStr = (bytes, enc) => { |
| 118 | switch (enc) { |
| 119 | case "utf8": return new TextDecoder().decode(bytes); |