踩坑记录【一】 - String与bytes 的转换

概述

C++写习惯了,其实不太能关注到 String 和 bytes 的区别在C++里,std::string 的底层实现是二进制序列,也可以用来哦存储 bytes 的。

但是并不是所有平台都是一样的,很多平台的String 底层实现涉及编码,直接复制字节会导致编码错误。

问题场景

在 atkts 平台上,需要吧一个bytes 转为 string

javascript 复制代码
String func(Uint8Array<int> input) {
  // 处理转换
}

这种问题其实在cpp 上很好处理

c 复制代码
void binaryToString(char* binaryData, std::size_t length) {
    std::string str(binaryData, length);
    // 现在 str 包含了二进制数据
}

同样的思路,在 arkts 上撸了一波

ini 复制代码
function uint8ArrayToString(uint8Array) {
    let result = '';
    for (let i = 0; i < uint8Array.length; i++) {
        result += String.fromCharCode(uint8Array[i]);
    }
    return result;
}

然后就发现炸了,arkts 转出来的结果和原始数据怎么完全对不上捏

原因分析

原因其实很好分析,对 cpp 来说,下面的语句是不会发生编码转换的

c 复制代码
std::string str(binaryData, length);

但是对 arkts 来说,下面的语句会用 unicode 编码,将每个字节视为UTF-16代码单元,纯二进制数据可能是在 uttf-16 表之外的,即 utf-16 含盖的数据范围其实是比二进制更小的,转换失败就乱码了

arduino 复制代码
String.fromCharCode(uint8Array[i])

这个时候会有聪明鬼说我换个 api ,比如用TextDecoder,当转后会发现,其实还是乱码,因为 arkts 底层 String 和 std::string 完全不同。arkts 的 String 默认一定是一个编码好的字符串,找不到任何方法把一个未编码的二进制存进入。

javascript 复制代码
function uint8ArrayToString(uint8Array: Uint8Array): string {
    const decoder = new TextDecoder('utf-8');
    return decoder.decode(uint8Array);
}

解决方案

这个时候又会有聪明跳出来,说我硬要把二进制放到 String 里怎么搞。业务上确实可能有这样的需求,比如用 proto 跨语言平台传递数据,协议就是一个 String 类型,没有 bytes 类型,那一定得转成 String 了。

这个是时候,可以用 base64,吧纯二进制转为 base64String,就能往下传了。

总结一下

String 和 bytes 是两个东西,String 能 cover 的数据范围更小

C++和ArkTS处理字符串的方式存在本质差异:

  1. C++的 std::string
    • 根本上是一个字节容器,不涉及字符编码转换。
    • 可以直接存储任意字节数据,不会进行任何解释或转换。
  1. ArkTS的 String
    • 使用UTF-16编码存储字符。
    • 每个字符占用16位,但对于ASCII字符(0-127),可以使用一个代码单元表示。
    • 对非ASCII字符(如汉字、表情符号等),则需要使用两个代码单元(即4字节)。
      因此,当你直接使用String.fromCharCode逐字节转换时,会遇到以下问题:
  • 无法正确表示多字节字符。
  • 部分字节可能被解释为无效字符,导致乱码或不可见字符。
相关推荐
今天不要写bug6 小时前
基于qrcode前端实现链接转二维码的生成与下载
前端·javascript·typescript·vue
憧憬少9 小时前
记录一个Typescript的IoC容器的实现
typescript
行走的陀螺仪1 天前
高级前端 Input 公共组件设计方案(Vue3 + TypeScript)
前端·javascript·typescript·vue·组件设计方案
by__csdn1 天前
微前端架构:从理论到实践的全面解析
前端·javascript·vue.js·架构·typescript·vue·ecmascript
Hao_Harrision2 天前
50天50个小项目 (React19 + Tailwindcss V4) ✨| RandomChoicePicker(标签生成)
前端·typescript·react·vite7·tailwildcss
Hao_Harrision2 天前
50天50个小项目 (React19 + Tailwindcss V4) ✨| FAQ Collapse(问题解答折叠面板)
前端·typescript·react·vite7·tailwildcss
by__csdn2 天前
javascript 性能优化实战:垃圾回收优化
java·开发语言·javascript·jvm·vue.js·性能优化·typescript
by__csdn2 天前
JavaScript性能优化:减少重绘和回流(Reflow和Repaint)
开发语言·前端·javascript·vue.js·性能优化·typescript·vue
凯小默2 天前
【TypeScript+Vue3+Vite+Vue-router+Vuex+Mock 进行 WEB 前端项目实战】学习笔记共 89 篇(完结)
typescript·echarts·mock·vue3·vite·vuex·vue-router
深兰科技2 天前
坦桑尼亚与新加坡代表团到访深兰科技,促进AI在多领域的应用落地
java·人工智能·typescript·scala·perl·ai大模型·深兰科技