跳转至

13 iconv字符集转换

作者:孟伟 | 最后修改:2026-04-09

一、字符编码介绍

1.1 字符编码的定义与作用

字符编码(Character encoding)是指将字符集中的字符编码为指定集合中的某一对象(例如:比特模式、自然数序列、8 位组或者电脉冲),以便文本在计算机中存储或通过通信网络传递。常见的例子包括将拉丁字母表编码成摩斯电码和 ASCII,其中 ASCII 使用 7 个或 8 个二进制位进行编码,最多可以给 256 个字符分配数值。

1.2 常见字符编码格式

  • ASCII:使用 7 个或 8 个二进制位进行编码,最多可以给 256 个字符分配数值,包括字母、数字和符号。
  • Unicode:一种国际标准字符集,支持世界上几乎所有的书写系统,包括汉字、日文假名等。
  • UTF-8:Unicode 的一种变长字符编码,由 Ken Thompson 于 1992 年创建,现已标准化为 RFC 3629。UTF-8 用 1 到 6 个字节编码 Unicode 字符。
  • GB2312:中国国家标准字符集,用于简体中文。
  • GBK:在 GB2312 基础上扩展的字符集,支持更多的中文字符。
  • Big5:用于繁体中文的字符集。

1.3 字符编码格式的使用场景和注意事项

在使用不同的字符编码格式时,需要注意以下几点:

  • 兼容性:确保发送端和接收端使用相同的字符编码,避免乱码问题。
  • 转换规则:了解 Unicode 和 UTF-8 之间的转换规则,确保正确编码和解码。
  • 应用场景:根据具体应用场景选择合适的字符编码格式,例如 Web 开发中常用 UTF-8。

二、演示功能概述

本文演示主要展示了在不同编码格式之间进行转换的工具和方法,包括 Unicode(小端和大端)、GB2312 和 UTF-8 等常见编码格式。

  • Unicode 小端编码与 GB2312 编码之间的转换。
  • Unicode 大端编码与 GB2312 编码之间的转换。
  • Unicode 小端编码与 UTF-8 编码之间的转换。
  • Unicode 大端编码与 UTF-8 编码之间的转换。
  • GB2312 编码与 UTF-8 编码之间的转换。

三、硬件环境

1、Air780EPM V1.3 版本开发板一块;

2、TYPE-C USB 数据线一根 ,Air780EPM V1.3 版本开发板和数据线的硬件接线方式为:

  • Air780EPM V1.3 版本开发板通过 TYPE-C USB 口供电;(外部供电/USB 供电 拨动开关 拨到 USB 供电一端)
  • TYPE-C USB 数据线直接插到核心板的 TYPE-C USB 座子,另外一端连接电脑 USB 口;

四、软件环境

在开始实践本示例之前,先筹备一下软件环境:

1.烧录工具: Luatools 工具

2.本demo开发测试时使用的固件为LuatOS-SoC_V2016_Air780EPM,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件Air780EPM固件Air780EHM固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;

3.LuatOS 需要的脚本和资源文件

脚本和资源文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EPM/demo/iconv

准备好软件环境之后,接下来查看如何烧录项目文件到 Air780EPM 开发板,将本篇文章中演示使用的项目文件烧录到 Air780EPM 开发板中。

五、API 接口说明

详细 API 文档请参考:https://docs.openluat.com/osapi/core/iconv/

六、代码示例介绍

下面将演示使用 iconv 进行编码的转换:

6.1 核心代码实现

--[[
@module  iconv_test
@summary 字符编码转换测试模块
@version 1.0
@date    2025.10.27
@author  孟伟
@usage
本模块提供多种字符编码之间的相互转换功能,支持以下编码转换:
1. Unicode小端(ucs2)与GB2312编码互转
2. Unicode大端(ucs2be)与GB2312编码互转
3. Unicode小端(ucs2)与UTF8编码互转
4. Unicode大端(ucs2be)与UTF8编码互转

本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;
]]

--- unicode小端编码 转化为 gb2312编码
-- @string ucs2s unicode小端编码数据
-- @return string data,gb2312编码数据
-- @usage local data = common.ucs2ToGb2312(ucs2s)
function ucs2ToGb2312(ucs2s)
    local cd = iconv.open("gb2312", "ucs2")
    return cd:iconv(ucs2s)
end

--- gb2312编码 转化为 unicode小端编码
-- @string gb2312s gb2312编码数据
-- @return string data,unicode小端编码数据
-- @usage local data = common.gb2312ToUcs2(gb2312s)
function gb2312ToUcs2(gb2312s)
    local cd = iconv.open("ucs2", "gb2312")
    return cd:iconv(gb2312s)
end

--- unicode大端编码 转化为 gb2312编码
-- @string ucs2s unicode大端编码数据
-- @return string data,gb2312编码数据
-- @usage data = common.ucs2beToGb2312(ucs2s)
function ucs2beToGb2312(ucs2s)
    local cd = iconv.open("gb2312", "ucs2be")
    return cd:iconv(ucs2s)
end

--- gb2312编码 转化为 unicode大端编码
-- @string gb2312s gb2312编码数据
-- @return string data,unicode大端编码数据
-- @usage local data = common.gb2312ToUcs2be(gb2312s)
function gb2312ToUcs2be(gb2312s)
    local cd = iconv.open("ucs2be", "gb2312")
    return cd:iconv(gb2312s)
end

--- unicode小端编码 转化为 utf8编码
-- @string ucs2s unicode小端编码数据
-- @return string data,utf8编码数据
-- @usage data = common.ucs2ToUtf8(ucs2s)
function ucs2ToUtf8(ucs2s)
    local cd = iconv.open("utf8", "ucs2")
    return cd:iconv(ucs2s)
end

--- utf8编码 转化为 unicode小端编码
-- @string utf8s utf8编码数据
-- @return string data,unicode小端编码数据
-- @usage local data = common.utf8ToUcs2(utf8s)
function utf8ToUcs2(utf8s)
    local cd = iconv.open("ucs2", "utf8")
    return cd:iconv(utf8s)
end

--- unicode大端编码 转化为 utf8编码
-- @string ucs2s unicode大端编码数据
-- @return string data,utf8编码数据
-- @usage data = common.ucs2beToUtf8(ucs2s)
function ucs2beToUtf8(ucs2s)
    local cd = iconv.open("utf8", "ucs2be")
    return cd:iconv(ucs2s)
end

--- utf8编码 转化为 unicode大端编码
-- @string utf8s utf8编码数据
-- @return string data,unicode大端编码数据
-- @usage local data = common.utf8ToUcs2be(utf8s)
function utf8ToUcs2be(utf8s)
    local cd = iconv.open("ucs2be", "utf8")
    return cd:iconv(utf8s)
end

--- utf8编码 转化为 gb2312编码
-- @string utf8s utf8编码数据
-- @return string data,gb2312编码数据
-- @usage local data = common.utf8ToGb2312(utf8s)
function utf8ToGb2312(utf8s)
    local cd = iconv.open("ucs2", "utf8")
    local ucs2s = cd:iconv(utf8s)
    cd = iconv.open("gb2312", "ucs2")
    return cd:iconv(ucs2s)
end

--- gb2312编码 转化为 utf8编码
-- @string gb2312s gb2312编码数据
-- @return string data,utf8编码数据
-- @usage local data = common.gb2312ToUtf8(gb2312s)
function gb2312ToUtf8(gb2312s)
    local cd = iconv.open("ucs2", "gb2312")
    local ucs2s = cd:iconv(gb2312s)
    cd = iconv.open("utf8", "ucs2")
    return cd:iconv(ucs2s)
end

--------------------------------------------------------------------------------------------------------
--[[
函数名:ucs2ToGb2312
功能  :unicode小端编码 转化为 gb2312编码,并打印出gb2312编码数据
参数  :
        ucs2s:unicode小端编码数据,注意输入参数的字节数
返回值:
]]
local function testucs2ToGb2312(ucs2s)
    print("ucs2ToGb2312")
    local gb2312num = ucs2ToGb2312(ucs2s) --调用的是common.ucs2ToGb2312,返回的是编码所对应的字符串
    --print("gb2312  code:",gb2312num)
    print("gb2312  code:", string.toHex(gb2312num))
end

--[[
函数名:gb2312ToUcs2
功能  :gb2312编码 转化为 unicode十六进制小端编码数据并打印
参数  :
        gb2312s:gb2312编码数据,注意输入参数的字节数
返回值:
]]
local function testgb2312ToUcs2(gb2312s)
    print("gb2312ToUcs2")
    local ucs2num = gb2312ToUcs2(gb2312s)
    print("unicode little-endian code:" .. string.toHex(ucs2num)) -- 要将二进制转换为十六进制,否则无法输出
end

--[[
函数名:ucs2beToGb2312
功能  :unicode大端编码 转化为 gb2312编码,并打印出gb2312编码数据,
大端编码数据是与小端编码数据位置调换
参数  :
        ucs2s:unicode大端编码数据,注意输入参数的字节数
返回值:
]]
local function testucs2beToGb2312(ucs2s)
    print("ucs2beToGb2312")
    local gb2312num = ucs2beToGb2312(ucs2s) -- 转化后的数据直接变成字符可以直接输出
    print("gb2312 code :" .. string.toHex(gb2312num))
end

--[[
函数名:gb2312ToUcs2be
功能  :gb2312编码 转化为 unicode大端编码,并打印出unicode大端编码
参数  :
        gb2312s:gb2312编码数据,注意输入参数的字节数
返回值:unicode大端编码数据
]]
function testgb2312ToUcs2be(gb2312s)
    print("gb2312ToUcs2be")
    local ucs2benum = gb2312ToUcs2be(gb2312s)
    print("unicode big-endian code :" .. string.toHex(ucs2benum))
end

--[[
函数名:ucs2ToUtf8
功能  :unicode小端编码 转化为 utf8编码,并打印出utf8十六进制编码数据
参数  :
        ucs2s:unicode小端编码数据,注意输入参数的字节数
返回值:
]]
local function testucs2ToUtf8(ucs2s)
    print("ucs2ToUtf8")
    local utf8num = ucs2ToUtf8(ucs2s)
    print("utf8  code:" .. string.toHex(utf8num))
end

--[[
函数名:utf8ToGb2312
功能  :utf8编码 转化为 gb2312编码,并打印出gb2312编码数据
参数  :
        utf8s:utf8编码数据,注意输入参数的字节数
返回值:
]]
local function testutf8ToGb2312(utf8s)
    print("utf8ToGb2312")
    local gb2312num = utf8ToGb2312(utf8s)
    print("gb2312 code:" .. string.toHex(gb2312num))
end

--[[
函数名:gb2312ToUtf8
功能  :gb2312编码 转化为 utf8编码,并打印出utf8编码数据
参数  :
        gb2312s:gb2312s编码数据,注意输入参数的字节数
返回值:
]]
local function testgb2312ToUtf8(gb2312s)
    print("gb2312ToUtf8")
    local utf8s = gb2312ToUtf8(gb2312s)
    print("utf8s code:" .. utf8s)
end

function iconv_test_fun()
    while true do
        sys.wait(10000)
        testucs2ToGb2312(string.fromHex("1162"))   -- "1162"是"我"字的ucs2编码,这里调用了string.fromHex将参数转化为二进制,也就是两个字节。
        testgb2312ToUcs2(string.fromHex("CED2"))   -- "CED2"是"我"字的gb2312编码
        testucs2beToGb2312(string.fromHex("6211")) -- "6211"是"我"字的ucs2be编码
        testgb2312ToUcs2be(string.fromHex("CED2"))
        testucs2ToUtf8(string.fromHex("1162"))
        testutf8ToGb2312(string.fromHex("E68891")) -- "E68891"是"我"字的utf8编码
        testgb2312ToUtf8(string.fromHex("CED2"))
    end
end

sys.taskInit(iconv_test_fun)

6.2 功能验证

6.2.1 支持的编码格式

  • ucs2: Unicode 小端编码(Little Endian)
  • ucs2be: Unicode 大端编码(Big Endian)
  • utf8: UTF-8 可变长度编码
  • gb2312: 国标 2312 编码,中文常用编码

6.2.2 字符编码示例

以汉字"我"为例:

  • UCS2 小端: 0x11 0x62string.fromHex("1162")
  • UCS2 大端: 0x62 0x11string.fromHex("6211")
  • UTF-8: 0xE6 0x88 0x91string.fromHex("E68891")
  • GB2312: 0xCE 0xD2string.fromHex("CED2")

6.2.3 运行 luatools 日志

通过日志可以看到,所有转换结果应与预期编码值一致

七、总结

至此,本教程详细介绍了 LuatOS iconv 模块的字符编码转换功能。通过该模块,物联网设备可以轻松处理多种字符编码的转换需求。

iconv 模块关键特性:

  • 支持多种常见字符编码格式
  • 提供完整的双向转换能力
  • 自动处理字节序问题
  • 内存占用小,适合嵌入式设备

7.1、注意事项

7.1 部分编码不能互相转换

当前仅支持如下 8 种编码转换 :

  • ucs2->utf8
  • ucs2->gb2312
  • gb2312->ucs2
  • gb2312->ucs2be
  • ucs2be->utf8
  • ucs2be->gb2312
  • utf8->ucs2
  • utf8->ucs2be

7.2 ucs2 与 ucs2be 大小端问题

ucs2be 是大端存储,也就是高字节数据存储在高位,因此中文字符 "你好" 对应的是 "4f60597d"

ucs2 是小端存储,也就是高字节数据存储在低位,因此中文字符 "你好" 对应的是 "604f7d59"