主题
encoder — 编码转换
模块名:encoder
在字节串与 Base64、十六进制字符串之间互相转换。常用于把二进制数据放进 JSON/MQTT 这类文本协议里传输,或把串口报文转成可读的十六进制便于排查。
全部是库级函数,没有对象。
函数总览
| 函数 | 作用 |
|---|---|
encoder.tobase64 | 字节串 → Base64 字符串 |
encoder.frombase64 | Base64 字符串 → 字节串 |
encoder.tohex | 字节串 → 小写十六进制字符串 |
encoder.fromhex | 十六进制字符串 → 字节串(严格) |
encoder.from16hex(input_string) | 字节串 → 大写十六进制字符串 |
encoder.to16hex(input_string) | 十六进制字符串 → 字节串(宽松) |
命名方向容易混淆:toXXX 表示「转成 XXX 格式」,fromXXX 表示「从 XXX 格式还原」。from16hex 是例外,其实际功能是「转成大写十六进制」。
encoder.tobase64
lua
encoder.tobase64(data) --> string把字节串编码为 Base64 字符串。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | data | string | 是 | — | 待编码的原始字节串,可为空串 |
返回值
| 类型 | 说明 |
|---|---|
| string | Base64 字符串;输入为空串时返回空串 |
示例
lua
local b64 = encoder.tobase64(raw_bytes)encoder.frombase64
lua
encoder.frombase64(str) --> string把 Base64 字符串解码为原始字节串。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | str | string | 是 | — | Base64 字符串 |
返回值
| 类型 | 说明 |
|---|---|
| string | 解码后的字节串 |
说明
- 长度非法或含非法字符会直接报错,外部输入建议用
pcall包一层。
encoder.tohex
lua
encoder.tohex(data) --> string把字节串逐字节转为小写十六进制字符串,每字节两个字符。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | data | string | 是 | — | 原始字节串 |
返回值
| 类型 | 说明 |
|---|---|
| string | 小写十六进制字符串,例如 3 字节 01 AB 0F → "01ab0f" |
示例
lua
port:reg(com.RECVDATA, function(data)
print("收到: " .. encoder.tohex(data))
end)encoder.fromhex
lua
encoder.fromhex(str) --> string把十六进制字符串转回字节串。严格模式。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | str | string | 是 | — | 十六进制字符串,接受 0-9、a-f、A-F |
返回值
| 类型 | 说明 |
|---|---|
| string | 还原后的字节串 |
说明
- 长度必须为偶数,出现非法字符或奇数长度会直接报错。需要容错请用
encoder.to16hex。
encoder.from16hex
lua
encoder.from16hex(data) --> string把字节串转为大写十六进制字符串。功能与 tohex 相同,只是输出大写。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | data | string | 是 | — | 原始字节串,可为空串 |
返回值
| 类型 | 说明 |
|---|---|
| string | 大写十六进制字符串,例如 "01AB0F";输入为空串时返回空串 |
实用例程
lua
array[i][4] = plc.d(609)
--print(array[i][1],array[i][2],array[i][3],array[i][4])
end
--MC_3E_tcp协议设置---------------------------------------------
plc.d(600, 0) --清除连接状态
错误代码, 通讯状态 = "", ""
Parse, 超时, D0 = 0, 0, 0 --定义全局变量
--plc采集通讯协议
client_eth = tcp_client.creat("192.168.1.100", 4990, plc.eth_ip()) --网口建立连接服务器对象
client_eth:set_timeout(1000)
client_eth:reg(tcp_client.RECVDATA, function(eth_data) --注册接收数据回调函数
if eth_data ~= nil then
plc_data = encoder.from16hex(eth_data) --数据转字符串
print(D0, plc.d(600), "<名称>" .. plc_data)
Parse = 1 --接受完成,允许解析
end
end
)
client_eth:reg(tcp_client.CONNECTED, function() --注册连接成功回调函数
通讯状态 = "连接服PLC成功"
plc.d(600, 2)
client_eth:send(Mitsubishi_mc_3E())
end
)
client_eth:reg(tcp_client.DISCONNECTED, function() --注册断开连接回调函数把上面的地址、主题、引脚替换成你项目里的即可。
encoder.to16hex
lua
encoder.to16hex(str) --> string把十六进制字符串转回字节串。宽松模式:跳过所有非十六进制字符,并向下取整到偶数个有效字符。
参数
| # | 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|---|
| 1 | str | string | 是 | — | 十六进制字符串,0-9/A-F/a-f 之外的字符被忽略 |
返回值
| 类型 | 说明 |
|---|---|
| string | 还原后的字节串;输入为空串时返回空串 |
示例
lua
-- 带空格、带 0x 前缀都能容忍
local raw = encoder.to16hex("01 03 00 00 00 0A")说明
- 与
fromhex的区别:fromhex遇非法字符或奇数长度直接报错;to16hex静默忽略非法字符、丢弃末尾多出的半字节,不报错。处理人工输入或带分隔符的报文时用to16hex更方便。
实用例程
lua
--以下为传感器校正程序(主要是clo2)
plc.df(120,0.01)--初始化值
dsxz =timer.start(5000,function()
local sjs=math.random() / 50 --返回一个0-1之间随机数,除10
local clo2 =plc.df(120) * 1 --校正传感器 y=ax+b的公式
print("clo2:",clo2)
if clo2 < 0.1 then clo2 = 0.1+sjs end
plc.df(12,clo2)
print("<名称>",clo2)
end)
serial=com.setup(1,9600,com.NONE,8,1)
buff2=encoder.to16hex("<设备ID或凭据>")
serial:send(buff2)
print(" 修改成功 ")
--以下为成品水DTU程序
xd=mqtt.creat("192.168.1.100", 1883, "<名称>", "<名称>", "<名称>")--建立MQTT对象
mqtt.reg(xd,mqtt.CONNECTED,function()--注册登陆成功回调函数
print("xd连接成功")
mqtt.subscribe(xd,"/sys/thing/property/post_reply/<设备ID>/dlinks_<设备ID>",0)--订阅消息
end)
mqtt.reg(xd,mqtt.DISCONNECTED,function()--注册网络断开事件
print("xd 网络断开")
end
)把上面的地址、主题、引脚替换成你项目里的即可。
常见用法
把上位机下发的十六进制命令发到串口
lua
local raw = encoder.to16hex("01 03 00 00 00 0A C5 CD")
port:send(raw)通过 MQTT 传输二进制报文
lua
port:reg(com.RECVDATA, function(data)
mqtt.publish(mqttc, "device/raw",
json.encode({ hex = encoder.tohex(data), b64 = encoder.tobase64(data) }), 0, 0)
end)注意事项
tohex输出小写、from16hex输出大写,对方要求固定大小写时注意选对函数。- 需要 MD5 或随机字节:用
crypto.md5/crypto.random_bytes,但该模块只在部分机型上提供(LP3232、LP3288(ESP32-S3 平台),LP8910、LP8911、LP8912、LP8913、LP8915、LP8916、LP8922(4G 平台),LP2300、LP2323(STM32H750 平台),以及上位机的内置软设备与软 PLC 模拟器);没有它的机型只能自己实现或换方案,见加密模块。 AES 在全部机型上都有plc.aes_encode/plc.aes_decode,Base64 有本页的tobase64/frombase64与plc.base64_encode/plc.base64_decode。 - 整数和字节的互转用 Lua 标准库的
string.pack/string.unpack,不是本模块的职责。
例程
统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。
例程 1:上位机下发的十六进制命令发到串口
适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 / 上位机 | 依赖模块:encoder com | 难度:★☆☆
场景:云平台下发 01 03 00 00 00 0A 形式命令,转成字节串发串口。
完整代码(可直接下载运行):
lua
local raw = encoder.to16hex("01 03 00 00 00 0A C5 CD") -- 忽略空格,宽容
port:send(raw)要点:to16hex 宽松模式,跳过空格/0x 前缀;严格版 fromhex 遇非法字符报错。
验证方法:串口线上看到正确的 Modbus 报文。
注意事项:tohex 输出小写、from16hex 输出大写,对方要求固定大小写时选对函数。
例程 2:二进制报文走 MQTT/JSON
适用:同上 | 依赖模块:encoder json mqtt | 难度:★☆☆
场景:把串口收到的二进制原样用 JSON 上报(十六进制或 Base64)。
完整代码(可直接下载运行):
lua
port:reg(com.RECVDATA, function(data)
mqtt.publish(mqttc, "device/raw",
json.encode({ hex = encoder.tohex(data), b64 = encoder.tobase64(data) }), 0, 0)
end)要点:tohex 输出小写十六进制,tobase64 输出 Base64,任选其一。
验证方法:云端收到可读的 hex/b64 字段。
注意事项:整数/字节互转用 string.pack/unpack,不是本模块职责。
例程 3:注意事项——tohex 与 from16hex 的大小写
适用:同上 | 依赖模块:encoder | 难度:★☆☆
完整代码(可直接下载运行):
lua
print(encoder.tohex("AB")) -- "6162"(输入字节串,逐字节转小写 hex)
print(encoder.from16hex("01AB")) -- 字节串,注意函数名"from"但功能是转大写 hex 字符串
-- 命名易混:toXXX=转成XXX格式;from16hex 是例外,功能=转成大写 hex要点:tohex→小写 hex,from16hex→大写 hex;fromhex 严格、to16hex 宽松还原。
验证方法:对照输出确认大小写。
注意事项:对方要求固定大小写时选错函数会导致校验失败。