Appearance
实现 文本转二进制 工具
分类:developer | 标签:二进制、编码、UTF-8 UTF-8 字节与二进制互转
2.1 功能说明
UTF-8 字节与二进制互转
2.1.1 使用指南
功能说明
文本与二进制(UTF-8 字节,8 位一组)互转。
使用场景
底层编码学习、位级数据传输校验。
编码矩阵
「编码矩阵」页签提供更多进制视角:
- 文本 ↔ 十六进制:按 UTF-8 字节输出两位一组的 Hex,可切换大小写、可选空格分隔。反向输入时会自动忽略空格、逗号、换行与 0x 前缀。
- 文本 ↔ 八进制:按 UTF-8 字节输出三位一组的 Oct,固定以空格分隔;反向输入按空白切分,每组取值范围 000-377。
- ASCII / 码点表:逐字符列出十进制、十六进制、八进制、二进制码点及其 UTF-8 字节序列,中文等非 ASCII 字符会标注实际占用字节数。
提示:十六进制与八进制均以「字节」为单位,因此一个中文字符通常对应 3 个字节(3 组 Hex 或 3 组 Oct)。
2.2 代码实现
2.2.1 组件结构
本工具是一个基于 Vue 3 <script setup> 语法的单文件组件(SFC),统一包裹在 ToolPageShell 组件内,由它提供页面标题、工具 ID、分类与「使用指南」插槽等通用外壳;核心业务逻辑(响应式状态、计算属性、事件处理函数)全部写在 <script setup> 中,输入/输出通过 el-input、el-button 等 Element Plus 组件与用户交互,所有数据均在浏览器本地处理,不会上传服务器。
2.2.2 核心逻辑概览
<script setup> 中定义的主要函数/方法:
run()copy()clear()runEnc()copyEnc()clearEnc()
2.2.3 关键实现代码
以下是该工具的完整 <script setup> 实现(核心代码)。模板(<template>)与样式(<style>)已省略。
vue
import { ref, computed } from 'vue'
import ToolPageShell from '@/components/ToolPageShell.vue'
const tab = ref('bin')
const mode = ref('t2b')
const input = ref('')
const output = ref('')
const error = ref('')
function run() {
error.value = output.value = ''
const src = input.value
if (!src) { error.value = '请输入内容'; return }
try {
if (mode.value === 't2b') {
const bytes = new TextEncoder().encode(src)
output.value = Array.from(bytes).map(b => b.toString(2).padStart(8, '0')).join(' ')
} else {
const chunks = src.trim().split(/\s+/)
if (!chunks.every(c => /^[01]{8}$/.test(c))) { error.value = '二进制必须由若干个 8 位 0/1 组(空格分隔)组成'; return }
const bytes = chunks.map(c => parseInt(c, 2))
output.value = new TextDecoder().decode(Uint8Array.from(bytes))
}
} catch (e) { error.value = '转换失败:' + e.message }
}
function copy() { if (output.value) navigator.clipboard?.writeText(output.value) }
function clear() { input.value = output.value = error.value = '' }
const encMode = ref('t2h')
const hexUpper = ref(false)
const hexSpace = ref(true)
const encInput = ref('')
const encOutput = ref('')
const encError = ref('')
const encPlaceholder = computed(() => {
if (encMode.value === 't2h') return '输入文本,如 Hello 中文'
if (encMode.value === 'h2t') return '输入十六进制,如 48 65 6c 6c 6f(空格/逗号/0x 前缀均可)'
if (encMode.value === 't2o') return '输入文本,如 Hello 中文'
return '输入八进制,如 110 145 154 154 157(空格分隔,每组 3 位)'
})
function runEnc() {
encError.value = ''
encOutput.value = ''
const src = encInput.value
if (!src.trim()) { encError.value = '请输入内容'; return }
try {
if (encMode.value === 't2h') {
const bytes = new TextEncoder().encode(src)
let list = Array.from(bytes).map(b => b.toString(16).padStart(2, '0'))
if (hexUpper.value) list = list.map(s => s.toUpperCase())
encOutput.value = list.join(hexSpace.value ? ' ' : '')
} else if (encMode.value === 'h2t') {
const cleaned = src.replace(/0x/gi, '').replace(/[\s,;]+/g, '')
if (!cleaned) { encError.value = '未识别到有效的十六进制字符'; return }
if (!/^[0-9a-fA-F]+$/.test(cleaned)) { encError.value = '十六进制只能包含 0-9 与 a-f'; return }
if (cleaned.length % 2 !== 0) { encError.value = '十六进制长度必须为偶数(每个字节两位)'; return }
const bytes = []
for (let i = 0; i < cleaned.length; i += 2) bytes.push(parseInt(cleaned.slice(i, i + 2), 16))
encOutput.value = new TextDecoder().decode(Uint8Array.from(bytes))
} else if (encMode.value === 't2o') {
const bytes = new TextEncoder().encode(src)
encOutput.value = Array.from(bytes).map(b => b.toString(8).padStart(3, '0')).join(' ')
} else {
const chunks = src.trim().split(/[\s,;]+/).filter(Boolean)
if (!chunks.every(c => /^[0-7]{1,3}$/.test(c))) { encError.value = '八进制每组只能是 1-3 位的 0-7 数字'; return }
const bytes = chunks.map(c => parseInt(c, 8))
if (bytes.some(b => b > 255)) { encError.value = '八进制每组取值不能超过 377(十进制 255)'; return }
encOutput.value = new TextDecoder().decode(Uint8Array.from(bytes))
}
} catch (e) { encError.value = '转换失败:' + e.message }
}
function copyEnc() { if (encOutput.value) navigator.clipboard?.writeText(encOutput.value) }
function clearEnc() { encInput.value = encOutput.value = encError.value = '' }
const asciiInput = ref('')
const asciiRows = computed(() => {
const chars = Array.from(asciiInput.value)
const encoder = new TextEncoder()
return chars.slice(0, 300).map((ch, i) => {
const cp = ch.codePointAt(0)
const utf8 = Array.from(encoder.encode(ch)).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ')
return {
index: i + 1,
char: ch === ' ' ? '(空格)' : ch === '\n' ? '(换行)' : ch === '\t' ? '(制表)' : ch,
dec: cp,
hex: '0x' + cp.toString(16).toUpperCase(),
oct: '0o' + cp.toString(8),
bin: cp.toString(2).padStart(cp > 255 ? 16 : 8, '0'),
utf8
}
})
})2.3 效果截图
