字符编码转换

6 篇文章 0 订阅
1 篇文章 0 订阅

1. 背景

在团队合作开发中,经常发现组员的代码中含有的中文字段在自己这儿显示是乱码的,使用编辑器确认才发现是使用的编码格式不一样导致,比如组员使用GBK编码,自己使用utf-8编码,就会出现乱码问题。

2. 解决方案

不同开发之间使用的编辑器字符编码格式不一样,而同一个字符,在不同编码格式中所代表的含义也是不同,这是导致乱码现象的直接原因。解决思路整体有2种:

  1. 将另外一种编码转换为自己本地的编码,或者设置本地编辑器的编码格式和对方相同;
  2. 团队之间形成约定 ,要求所有人都统一按照一种编码格式进行编码;

对于团队而言,按照方案2形成统一的约定,是最简单省事的方法。但对于像第三方或者开源的文档,是没有办法形成一个统一的,就需要采用方案1进行编码转换了。

3. 编码转换实现

3.1 shell实现

shell 下可以使用 iconv 工具进行字符编码转换

iconv工具的使用帮助如下:

用法: iconv [选项...] [文件...]
转换给定文件的编码。

 输入/输出格式规范:
  -f, --from-code=名称     原始文本编码
  -t, --to-code=名称       输出编码

 信息:
  -l, --list                 列举所有已知的字符集

 输出控制:
  -c                         从输出中忽略无效的字符
  -o, --output=文件        输出文件
  -s, --silent               关闭警告
      --verbose              打印进度信息

  -?, --help                 给出此帮助列表
      --usage                给出简要的用法信息
  -V, --version              打印程序版本号

将一个 gbk 编码格式的文件转换成 utf-8 格式,操作如下:

iconv -f gbk -t utf-8 gbk.txt -o utf8.txt 

注意:笔者发现使用linux下的file命令是无法显示gbk等编码格式的,显示的全部都是ISO-8859,但实际上如果使用 vscode这种编辑器查看的编码格式是gbk。因此,在不知道实际编码格式的情况下,去实现编码格式转换还是很困难的。

3.2 python实现

python实现的原理就是先用 gbk 编码打开指定的文件,读取内容,然后使用 utf-8 格式编码重新写入

def encode_conv(src_file, dst_file):
    with open(src_file, 'r', encoding='gbk') as f:
        content = f.read()
    
    with open(dst_file, 'w', encoding='utf-8') as f:
        f.write(content)
        
if __name__ == '__main__':
    encode_conv('gbk.txt', 'utf8.txt')

这里其实也有个问题,当预先不知道文件编码的时候,使用 open打开的时候会报错,因为使用的是默认的 utf-8的编码读数据,然后读取到的字节格式不能被识别导致的。这种情况,需要预先设置一些可能的编码格式,然后进行异常处理,直至得到正确的编码格式。

3.3 开源工具实现

也可以从 github 上下载开源的转换工具实现 codetransmit转换工具

4. 常见中文字符编码介绍

4.1 字符编码解决什么问题

计算机可以识别并进行运算的只有01,世界上各种语言组成又是各不相同的,如何让这些文字可以被正常显示呢?当前的通用方案是:全部按照一种约定好的长度字节进行编码,如使用2个字节,同时建立一套2个字节的码表,把识别到的字符值去码表查找。其中,约定的长度可以定长的(gb2312gbk),也可以是变长的(utf-8)。字符编码解决的也就是按照一种约定的长度解析字节流,然后在一个事先建立好的mapping中去查找所代表的的字符。

4.2 常见的中文字符编码

  • UTF-8
  • GB2312
  • GBK
  • GB18030

4.3 常见中文字符编码关系

如下图所示:
在这里插入图片描述

!

utf-8 是一种变长的字符编码格式,使用的是 unicode 的码点编号。GB2312 和 GBK 使用的是2个字节编码格式,其中GB2312是GBK的扩展,GB18030使用的4个字节编码,可以兼容GBK和GB2312。

4.4 unicide字符集与utf-8

Unicode 为 全世界所有字符编制了一个码点符号,提供了一套映射关系。utf-8 本质使用的就是 unicode 的码点符号,所以使用utf-8可以显示所有符号,大家也尽可能的使用utf-8格式进行编码。

  • utf-8 是使用变长字节(1-6字节)来进行编码的,第一个字节的二进制中首部连续的1的个数表示实际使用的字节编码数量,其余字节默认以“10”开头。
    在这里插入图片描述

例如,“中”的utf编码格式文件使用二进制查看,实际的二进制数据为e4b8 ad0a

中(e4b8 ad0a)1110 01001011 10001010 11010000 1010

从第一个字节克可知,“中”由3个字节编码而成,按照上面的表格,去掉每个字节的首部就是

中(4E2D–>0100 1110 0010 1101)0100 1110 0010 1101

从上面可以看出,utf编码使用的码点是和unicode码点对应上的。细心的我们发现了一个事情,“中”的文本数据里面最有一个字符“a”是怎么回事?“a”的ascii代表的是“\n”,也就是换行,相当于多了一个换行符号,应该是系统自己带上的。另外也说明了对于单字节编码,首部是“0”。
code码点对应上的。细心的我们发现了一个事情,“中”的文本数据里面最有一个字符“a”是怎么回事?“a”的ascii代表的是“\n”,也就是换行,相当于多了一个换行符号,应该是系统自己带上的。另外也说明了对于单字节编码,首部是“0”。

程序员必备:彻底弄懂常见的7种中文字符编码1


  1. 文章参考 ↩︎

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来鸟 鸣间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值