区分一个包含汉字的字符串是 UTF-8 还是 GBK
今天检查 svn 仓库,发现又有同学没按规定提交包含汉字的代码。我们规定,所有源文件中包含的汉字必须使用 UTF-8 编码方式,而不能使用 GBK 。
总这么人工检查也不是个事。所以我想写一个 svn 的钩子,在提交前检查。在仓库的 hooks/pre-commit.teml 加一行检查脚本应该就可以了。
我想用正则表达式匹配一下,可是想了想又觉得 UTF-8 和 GBK 的编码集有点交集,不太好做。btw, google 了一下,的确有人写过特定编码的正则表达式。
继续 google ,找到一篇跟我需求有点类似的文章UTF-8编码检测失败特例。看了正文,觉得不太靠谱,然后继续看回复,觉得这方法可行。
然后定睛一看,原来文章是孟岩写的,回复是我自己三年多前回复在他的 blog 上的。 -_-
打算还是自己写个小程序做检查,不用现成工具了。
具体算法复制回这里:
cloudwu 发表于2007-01-05 00:49:51 IP: 218.72.15.*
如果想区分一个完整的字符串是 GBK 还是 UTF8 其实蛮简单的。虽然做不到 100% 有效,但也比上面的方法强许多。
UTF8 是兼容 ascii 的,所以 0~127 就和 ascii 完全一致了。
gbk 的第一字节是高位为 1 的,第 2 字节可能高位为 0 。这种情况一定是 gbk ,因为 UTF8 对 >127 的编码一定每个字节高位为 1 。
另外,对于中文,UTF8 一定编码成 3 字节。(似乎亚洲文字都是,UTF8 中双字节好象只用于西方字符集)
所以型如 110***** 10******
的,我们一概看成 gbk/gb2312 编码。这就解决了“位”的问题。
汉字以及汉字标点(包括日文汉字等),在 UTF8 中一定被编码成:1110**** 10****** 10******
连续汉字数量不是 3 的倍数的 gb2312 编码的汉字字符串一定不会被误认为 UTF8 。用了一些gbk 扩展字,或是插入了一些 ascii 符号的字符串也几乎不会被认为是 UTF8 。
一般说来,只要汉字稍微多几个,gbk 串被误认为 UTF8 的可能性极其低。(只需要默认不使用 UTF8 中双字节表示的字符)可能性低,这里还有另外一个原因。UTF8 中汉字编码的第一个字节是 1110****
,这处于汉字的 gb2312 中二级汉字(不常用汉字,区码从 11011000 开始)的编码空间。一般是一些生僻字才会碰上。
建议继续学习:
- ORACEL RAC 字符集 (阅读:4681)
- linux下vim的编译以及终端乱码的最终解决方案 (阅读:3573)
- 如何在MYSQL5.5只支出utf8环境下正常使用GBK网站 (阅读:2870)
- oracle查看字符集 修改字符集 (阅读:2894)
- mysql latin1转utf8 的两种方法 (阅读:2486)
- mysql字符集和校验规则概念小介 (阅读:2297)
- mysql字符集与校验规则的设置 (阅读:2283)
- java中文乱码解决之道(一)—–认识字符集 (阅读:2503)
- mysql连接通道中的字符集和校验规则 (阅读:2203)
- 关于MySQL的字符集 (阅读:2127)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:云风的 BLOG 来源: 云风的 BLOG
- 标签: 字符集
- 发布时间:2010-07-07 14:48:25
- [70] Twitter/微博客的学习摘要
- [67] IOS安全–浅谈关于IOS加固的几种方法
- [64] 如何拿下简短的域名
- [64] android 开发入门
- [63] find命令的一点注意事项
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [59] Oracle MTS模式下 进程地址与会话信
- [58] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则