Files
ToolBox/src/utils/encoder.js
T
renjue f1502ed08c
CI / docker (push) Successful in 11m42s
初始化 ToolBox 开发者工具箱。
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 11:15:38 +08:00

118 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export function bytesToBase64(bytes) {
let binary = ''
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i])
return btoa(binary)
}
export function base64ToBytes(str) {
const clean = str.replace(/\s/g, '')
const binary = atob(clean)
const bytes = new Uint8Array(binary.length)
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
return bytes
}
export function encodeBase64(text) {
return btoa(unescape(encodeURIComponent(text)))
}
export function decodeBase64(text) {
return decodeURIComponent(escape(atob(text)))
}
export function encodeUrl(text) {
return encodeURIComponent(text)
}
export function decodeUrl(text) {
return decodeURIComponent(text)
}
export function encodeUnicode(text) {
let result = ''
let i = 0
while (i < text.length) {
const codePoint = text.codePointAt(i)
if (codePoint > 0xFFFF) {
// 超出 BMP 的字符,使用代理对表示
const high = Math.floor((codePoint - 0x10000) / 0x400) + 0xD800
const low = ((codePoint - 0x10000) % 0x400) + 0xDC00
result += '\\u' + high.toString(16).toUpperCase().padStart(4, '0')
result += '\\u' + low.toString(16).toUpperCase().padStart(4, '0')
i += 2 // 代理对占用两个字符位置
} else {
// BMP 字符
result += '\\u' + codePoint.toString(16).toUpperCase().padStart(4, '0')
i++
}
}
return result
}
export function decodeUnicode(text) {
try {
let result = ''
let i = 0
while (i < text.length) {
// 匹配 \uXXXX 格式
if (text[i] === '\\' && i + 1 < text.length && text[i + 1] === 'u' && i + 5 < text.length) {
const hex = text.substring(i + 2, i + 6)
if (/^[0-9a-fA-F]{4}$/.test(hex)) {
const code1 = parseInt(hex, 16)
// 检查是否是高代理(surrogate high
if (code1 >= 0xD800 && code1 <= 0xDBFF && i + 11 < text.length) {
// 检查下一个是否是低代理
if (text[i + 6] === '\\' && text[i + 7] === 'u') {
const hex2 = text.substring(i + 8, i + 12)
if (/^[0-9a-fA-F]{4}$/.test(hex2)) {
const code2 = parseInt(hex2, 16)
// 检查是否是低代理(surrogate low
if (code2 >= 0xDC00 && code2 <= 0xDFFF) {
// 组合代理对
const codePoint = 0x10000 + ((code1 - 0xD800) << 10) + (code2 - 0xDC00)
result += String.fromCodePoint(codePoint)
i += 12
continue
}
}
}
}
// 普通字符或单独的代理
result += String.fromCharCode(code1)
i += 6
continue
}
}
// 匹配 \UXXXXXXXX 格式(8位十六进制)
if (text[i] === '\\' && i + 1 < text.length && text[i + 1] === 'U' && i + 9 < text.length) {
const hex = text.substring(i + 2, i + 10)
if (/^[0-9a-fA-F]{8}$/.test(hex)) {
const code = parseInt(hex, 16)
if (code > 0x10FFFF) {
throw new Error('无效的 Unicode 码点:超出范围')
}
result += String.fromCodePoint(code)
i += 10
continue
}
}
// 普通字符
result += text[i]
i++
}
return result
} catch (e) {
throw new Error('Unicode 解码失败:' + e.message)
}
}