01 背景

为某客户做信锐 AC 监控时,AC 下纳管的 AP 名字显示为 16 进制字串(形如 E5 95 86 E5 8A A1 E9 83 A8),客户反馈看不懂其代表的含义,要求将其转化为可读的中文名称。

02 原因

通过 SNMP 获取 AP 名称时存在两种情况:

  • 如果 AP 的名字未被更改,获取到的是 MAC 地址(不需要转化)
  • 如果 AP 的名字已被更改,获取到的是 UTF-8 编码的 16 进制数(需要转化为中文)

矛盾在于:如果 AP 名字被更改过,应该做转化;如果未被更改,则不应该做转化。于是研发人员将这个判断工作交给了实施团队——根据实际情况决定是否转化。

历史上有近 10 个客户使用了信锐 AC,都是在实施过程中人工识别和转化的。那有没有办法在代码里自动兼容这两种情况呢?答案是可以的。因为 UTF-8 编码有固定规则,完全可以通过程序区分 16 进制数是 MAC 地址还是 UTF-8 编码。

具体代码实现不在此赘述,但有的同学一提到 ASCII、GBK、GB2312、UTF、16 进制就抓瞎,所以把涉及到的编码知识在团队内做一次系统性总结和普及。

03 知识点拓展

(1)16 进制

16 进制是数字的一种呈现形式,并不是独立的编码体系。

  • 数字 10 的 16 进制表示为 A
  • 数字 10 的二进制表示为 1010

16 进制常用于简化二进制的书写,每个 16 进制位对应 4 个二进制位。

(2)ASCII 码

ASCII(美国信息交换标准代码)制定于 1960 年代,将英文字符与二进制一一对应。

  • 16进制 30 → 数字字符 0
  • 16进制 61 → 英文字母 a

ASCII 码只覆盖了英文字母、数字和常用符号,共 128 个字符,无法表示中文等非英文字符。

(3)Unicode

全球有数百种文字,计算机只认识数字。如果没有统一的表示方式,同一个汉字在不同系统可能用不同编号表示,导致乱码混乱。

Unicode 的出现解决了这个问题:它是一个全球统一的字符集,把世界上所有的文字都定义了唯一的数字表示方式(称为"码点",Code Point)。例如:

  • 汉字"你"的 Unicode 码点为 U+4F60
  • 汉字"我"的 Unicode 码点为 U+6211

(4)Unicode 的问题

Unicode 定义了字符的唯一编号,但并未规定如何在计算机中存储和传输。直接使用 Unicode 码点存储存在两个问题:

  1. 无法确定字符边界:一串字节无法识别表示几个字符
  2. 存储空间膨胀:通过补零使所有字符占用统一长度(如 4 字节),会造成存储空间和网络传输带宽的严重浪费

因此,Unicode 最终作为"字符的表示标准"而非"存储编码方式"存在。

(5)UTF 编码

随着互联网普及,UTF(Unicode Transformation Format)编码方式应运而生,真正将 Unicode 表示方式转换为实用的存储编码。

UTF-8 采用变长编码:根据字符的 Unicode 码点范围,使用 1~4 个字节来表示一个字符。

a)单字节字符(英文字母、数字等)

编码格式:0xxxxxxx

  • 第一位固定为 0,后面 7 位是 Unicode 码点
  • 对于英文单字符,UTF-8 编码与 ASCII 完全兼容

b)多字节字符(N 字节,如中文)

编码格式:

  • 第 1 字节:前 N 位全为 1,第 N+1 位为 0,剩余 8-N-1 位填充 Unicode 码点高位
  • 后续字节:前两位固定为 10,剩余 6 位填充 Unicode 码点的后续位

UTF-8 字节范围与字符类型对应关系:

Unicode 码点范围UTF-8 字节数编码格式
U+0000 ~ U+007F1 字节0xxxxxxx
U+0080 ~ U+07FF2 字节110xxxxx 10xxxxxx
U+0800 ~ U+FFFF3 字节1110xxxx 10xxxxxx 10xxxxxx
U+10000 ~ U+10FFFF4 字节11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

c)实例:汉字"你"的 UTF-8 编码

  • “你"的 Unicode 码点:U+4F60,二进制为 0100 1111 0110 0000
  • 码点落在 U+0800 ~ U+FFFF 范围,使用 3 字节编码
  • 编码格式:1110xxxx 10xxxxxx 10xxxxxx
  • 填充码点二进制后得:1110 0100 1011 1101 1010 0000
  • 对应 16 进制:E4 BD A0

这就是为什么"你"的 UTF-8 编码是 E4BDA0

04 题外话

理解 Unicode 的核心:它是文字的唯一数字化表示方式,也叫码点(Code Point)。Unicode 只负责"定义字符编号”,不负责"如何存储"。

理解 UTF 的核心:它是"把 Unicode 码点做转换,从而让其在网络传输、文件保存等场景中没有歧义的编码方式"。

其他相关编码方式:

  • UCS-2:双字节编码,用固定 2 个字节表示 Unicode 字符(已被 UTF-16 替代)
  • UCS-4:4 字节编码,用固定 4 个字节表示 Unicode 字符(存储浪费)
  • GBK/GB2312:中国国家标准,兼容 ASCII,用 1~2 字节表示字符,但不兼容其他语言的 Unicode 标准

回到最初的问题:信锐 AC 返回的 E5 95 86 E5 8A A1 E9 83 A8 正是中文"商务部"的 UTF-8 编码,只需将其按 UTF-8 规则解码即可还原为可读的中文名称。