当前位置: 首页 > news >正文

Unicode 字符串转 UTF-8 编码算法剖析

📊 Unicode 字符串转 UTF-8 编码算法剖析

——从 C# char 到 C++ wchar_t 的编码转换原理

引用:UTF-8 编解码可视化分析


🔍 1. 算法功能概述

该函数将 Unicode 字符串(C# string)转换为 UTF-8 编码的字节数组,同时输出有效字节数 count
核心流程

  1. 计算 UTF-8 编码所需字节数
  2. 分配缓冲区(额外预留 3 字节)
  3. 逐字符编码为 UTF-8 字节序列
开始
计算字节数
分配缓冲区
编码转换
返回结果

🧠 2. 算法原理与 UTF-8 编码规则

UTF-8 是变长编码,规则如下:

在这里插入图片描述

Unicode 码点范围UTF-8 字节序列结构字节数位模式图示
U+0000 ~ U+007F0xxxxxxx1[0xxx xxxx]
U+0080 ~ U+07FF110xxxxx 10xxxxxx2[110x xxxx] [10xx xxxx]
U+0800 ~ U+FFFF1110xxxx 10xxxxxx 10xxxxxx3[1110 xxxx] [10xx xxxx] [10xx xxxx]

💡 :C# char 为 16 位 Unicode,C++ wchar_t 在 Windows 中与之等价(Linux 为 32 位)。


🔄 3. 算法流程详解
步骤 1:计算 UTF-8 字节数

在这里插入图片描述

int k = 0;
while (i < s.Length) {char ch = s[i++];if (ch < 0x80) k++;        // ASCII 字符(1 字节)else if (ch < 0x800) k += 2; // 2 字节字符else if (ch < 0x10000) k += 3; // 3 字节字符(含 CJK 字符)
}
count = k; // 输出有效字节数
  • 时间复杂度:O(n),需遍历整个字符串。
步骤 2:分配缓冲区
buf = new byte[count + 3]; // 额外分配 3 字节(安全填充)
  • 为什么 +3?
    预留空间防止溢出(UTF-8 单字符最多占 3 字节),确保写入安全。
步骤 3:编码转换(核心)

在这里插入图片描述

fixed (byte* p = buf) { // 固定内存地址(避免 GC 移动)while (i < s.Length) {char ch = s[i++];// 1 字节编码(ASCII)if (ch < 0x80) p[k++] = (byte)(ch & 0xFF); // 2 字节编码(拉丁字母扩展)else if (ch < 0x800) {p[k++] = (byte)(((ch >> 6) & 0x1F) | 0xC0); // 110xxxxxp[k++] = (byte)((ch & 0x3F) | 0x80);        // 10xxxxxx}// 3 字节编码(中/日/韩文字符)else if (ch < 0x10000) {p[k++] = (byte)(((ch >> 12) & 0x0F) | 0xE0); // 1110xxxxp[k++] = (byte)(((ch >> 6) & 0x3F) | 0x80); // 10xxxxxxp[k++] = (byte)((ch & 0x3F) | 0x80);         // 10xxxxxx}}
}
  • 位操作解析
    原始字符
    位分解
    添加前缀
    组合字节

⚠️ 4. 算法局限性
算法局限
不支持代理对
缓冲区浪费
缺少4字节编码
无法处理表情符号
多分配3字节
不支持补充平面
  • 不支持代理对(Surrogate Pairs)
    无法处理 U+10000 以上的字符(如 emoji 𠮷),需补充 4 字节编码逻辑。
  • 缓冲区浪费:多分配 3 字节(可通过精确计算优化)。

📝 5. 完整代码(含逐行注释)
public static byte[] GetUTF8StringBuffer(string s, out int count)
{count = 0; // 初始化输出参数if (s == null){throw new ArgumentNullException("s"); // 空字符串检查}byte[] buf = null; // 存储结果的字节数组int k = 0;         // 临时计数器(字节数/写入位置)int i = 0;         // 字符串遍历索引// === 步骤 1:计算 UTF-8 编码所需字节数 ===while (i < s.Length){char ch = s[i++]; // 逐个读取字符if (ch < 0x80)    // ASCII 字符(0x00 ~ 0x7F){k++;          // 占 1 字节}else if (ch < 0x800) // 0x80 ~ 0x7FF(拉丁字母扩展){k += 2;       // 占 2 字节}else if (ch < 0x10000) // 0x800 ~ 0xFFFF(CJK 字符等){k += 3;       // 占 3 字节}}// === 步骤 2:分配缓冲区(额外 +3 字节) ===buf = new byte[(count = k) + 3]; // count 赋值为 k,总长度 = k+3// === 步骤 3:编码转换(不安全代码块) ===unsafe // 启用不安全代码{fixed (byte* p = buf) // 固定缓冲区内存地址{i = 0; // 重置字符串索引k = 0; // 重置字节数组索引while (i < s.Length){char ch = s[i++]; // 读取下一个字符// --- 1 字节编码 ---if (ch < 0x80){p[k++] = (byte)(ch & 0xFF); // 直接存储低 8 位}// --- 2 字节编码 ---else if (ch < 0x800){// 构造首字节:110xxxxx (0xC0 | 高 5 位)p[k++] = (byte)(((ch >> 6) & 0x1F) | 0xC0);// 构造次字节:10xxxxxx (0x80 | 低 6 位)p[k++] = (byte)((ch & 0x3F) | 0x80);}// --- 3 字节编码 ---else if (ch < 0x10000){// 构造首字节:1110xxxx (0xE0 | 高 4 位)p[k++] = (byte)(((ch >> 12) & 0x0F) | 0xE0);// 构造次字节:10xxxxxx (0x80 | 中 6 位)p[k++] = (byte)(((ch >> 6) & 0x3F) | 0x80);// 构造尾字节:10xxxxxx (0x80 | 低 6 位)p[k++] = (byte)((ch & 0x3F) | 0x80);}}}}return buf; // 返回 UTF-8 字节数组
}

🎯 6. 总结
算法价值
高效编码转换
跨语言兼容
内存安全
优化方向
支持4字节编码
精确缓冲区分配
使用Span提升性能
  • 核心价值:高效实现 Unicode 到 UTF-8 的转换,适用于网络传输或跨语言交互。
  • 优化方向
    1. 支持 4 字节编码(代理对)
    2. 移除多余缓冲区分配
    3. 使用 Span<byte> 提升性能
http://www.dtcms.com/a/341058.html

相关文章:

  • FPGA实现Aurora 64B66B图像视频点对点传输,基于GTH高速收发器,提供2套工程源码和技术支持
  • 科研笔记:博士论文写作攻略
  • IPSEC安全基础前篇
  • 七十三、【Linux数据库】MySQL数据库PXC 集群概述与演示
  • mvdr波束形成
  • week3-[分支结构]2023
  • STM32F407VGT6从零建立一个标准库工程模板+VSCode或Keil5
  • 【电气工程学习】
  • 可传参配置的同步异步fifo
  • PyTorch 社区贡献 和 设计原则
  • Web 安全之延迟攻击(Delay Attack)详解
  • PyCharm2025无法启动Powershell.exe的解决办法
  • 发那科机器人程序调整功能
  • 好家园房产中介网后台管理完整(python+flask+mysql)
  • 【图论】拓扑排序
  • 48 C++ STL模板库17-容器9-关联容器-映射(map)多重映射(multimap)
  • Spring Boot如何配置Liveness和Readiness探针
  • 【Android】Activity 如何进行数据传输
  • java17学习笔记-switch总结
  • 使用 GraalVM Native Image 将 Spring Boot 应用编译为跨平台原生镜像:完整指南
  • linux 内核 - 内存管理单元(MMU)与地址翻译(一)
  • yolo_RK3588系列(三)
  • mac电脑软件左上角的关闭/最小化/最大化按钮菜单的宽度和高度是多少像素
  • ijkplayer Android 编译
  • strncpy 函数使用及其模拟实现
  • AI重塑软件测试:质量保障的下一站
  • 成本管控:餐饮利润的隐形守护者
  • Zemax光学设计输出3D
  • 4位量化:常规的线性层被替换成了4位线性层(48)
  • 酶 EC number 预测工具CLEAN的安装和使用