Erlang GB2312 (GBK) to UTF-8

本文介绍了一种从GBK及GB2312编码转换到UTF-8编码的方法,通过创建映射表来解决Erlang XML库xmerl不支持GBK和GB2312的问题。

Erlang 的XML 库xmerl 只支持ISO8859-1 和UTF-8 编码,如果XML 的编码是GBK 或者GB2312 ,则当该XML 包含中文字 符时异常。一般情况下,可以使用ICONV 的库来解决,但ICONV 好像只更新到R12 版,对R13 及以上版本支持不好。没办法,只好自己来重复发明一个 轮子。

 

注意:很多网页默认是GB2312 编码,但事实上其包含了GBK 的内容,如“冏”字是GB2312 不包括的,但 奇怪的是 绝大部分的网页都用GB2312 编码且能在浏览器和常用的编辑器上正常显示。我只能假设这些程序太聪明了:)或者这些程序内部就是用GBK ,而非GB2312 编码的。

 

1. 建立印射表。

 

该表格式为:

{GBK(GB231) 第一个字节(高字节),第二个字节(低字节)} => {UTF8 第一个字节,UTF8 第二个字节,UTF8 第三个字节, UTF8 第四个字节}

注意,如果当前字节小于128 ,则直接输出该值,无须印射。(这是因为GBKGB2312 直接支持ASCII 码的原因)。

 

  • 汉字编码规则

1. GB2312 又称国标码,由国家标准总局发布, 1981 年 5 月 1 日实施,通行于大陆。新加坡等地也使用此编码。它是一个简化字的编码规范,当然也包括其他的符号、字 母、日文假名等,共 7445 个图形字符,其中汉字占 6763 个。我们平时说 6768 个汉字,实际上里边有 5 个编码为空白,所以总共有 6763 个汉字。
  GB2312 规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。 GB2312 中汉字的编码范围为,第一字节 0xB0-0xF7( 对应十进制为 176-247) ,第二个字节 0xA0-0xFE (对应十进制为 160-254 )。

GB2312

第一个字节(高字节)

0xB0-0xF7(176-247)

第二个字节(低字节)

0xA0-0xFE 160-254

 

2. GBK 是 GB2312 的扩展,是向上兼容的,因此 GB2312 中的汉字的编码与 GBK 中汉字的相同。另外, GBK 中 还包含繁体字的编码,它与 Big5 编码之间的关系我还 没有弄明白,好像是不一致的。 GBK 中每个汉字仍然包 含两个字节,第一个字节的范围是 0x81-0xFE(即 129-254 ),第二个字节的范围是 0x40-0xFE (即 64-254 )。 GBK 中有码位 23940 个, 包含汉字 21003 个。

GBK

第一个字节(高字节)

0x81-0xFE ( 129-254 )

第二个字节(低字节)

0x40-0xFE ( 64-254 )

3. Big5 又称大五码,主要为香港与台湾使用,即是一个繁体字编码。 每个汉字由两个字节构成,第一个字节的范 围从 0X81 - 0XFE (即129-255 ),共 126 种。第二个字节的范围不连续,分别为 0X40 - 0X7E (即 64-126 ), 0XA1 - 0XFE (即 161-254 ),共157 种。

Big5

第一个字节(高字节)

0x81-0xFE ( 129-255 )

第二个字节(低字节)

0x40-0x7E ( 64-126 )

0xA1 - 0xFE ( 161-254 )

4. GB18030 是 GBK 的扩充,网络用得较少。

GB18030-2000 收录了27533 个汉字:

类别

码位范围

码位数

字符数

字符类型

双字节部分

第一字节 0xB0-0xF7
第二字节 0xA1-0xFE

6768

6763

汉字

第一字节0x81-0xA0
第二字节0x40-0xFE

6080

6080

汉字

第一字节0xAA-0xFE
第二字节0x40-0xA0

8160

8160

汉字

四字节部分

第一字节0x81-0x82
第二字节0x30-0x39
第三字节0x81-0xFE
第四字节0x30-0x39

6530

6530

CJK 统一汉字扩充A

GB18030-2005 收录了70244 个汉字:

类别

码位范围

码位数

字符数

字符类型

双字节部分

第一字节 0xB0-0xF7
第二字节 0xA1-0xFE

6768

6763

汉字

第一字节0x81-0xA0
第二字节0x40-0xFE

6080

6080

汉字

第一字节0xAA-0xFE
第二字节0x40-0xA0

8160

8160

汉字

四字节部分

第一字节0x81-0x82
第二字节0x30-0x39
第三字节0x81-0xFE
第四字节0x30-0x39

6530

6530

CJK 统一汉字扩充A

第一字节0x95-0x98
第二字节0x30-0x39
第三字节0x81-0xFE
第四字节0x30-0x39

42711

42711

CJK 统一汉字扩充B

 

5. UTF-8 也叫UTF8 是Unicode 标准的一种实现,因其兼容ASCII 码,且能自我校正错误传输,故多用于网络传输。它将Unicode 编码为: 00000000-0000007F 的字符,用单个字节来表示; 00000080-000007FF 的字符用两个字节表示 (中文的编码范围) 00000800-0000FFFF 的字符用3 字节表。有些中文甚至需要用4 字节来表示。 当要表示的内容是 7 位 的时候就用一个字节:0* ,第一个0 为标志位,剩下的空间正好可以表示ASCII  0 -127  的内容。当要表示的内容在 8   到 11  位的时候就用两个字节:110***** 10****** 第一个字节的110 和第二个字节的10 为标志位。当要表示的内容在 12  到 16  位的时候就用三个字节:1110***** 10****** 10****** 和上面一样,第一个字节的1110 和第二、三个字节的10 都是标志位,剩下的空间正好可以表示汉字。以此类推:四个字 节:11110**** 10****** 10****** 10****** ;五个字节:111110*** 10****** 10****** 10****** 10****** ;六个字节:1111110** 10****** 10****** 10****** 10****** 10****** 。一般用前四个字节。

 

Unicode 5.099089 个字符中,有71226 个字符与汉字有关。它们的分布如下:

Block 名称

开始码位

结束码位

字符数

CJK 统一汉字

4E00

9FBB

20924

CJK 统一汉字扩充A

3400

4DB5

6582

CJK 统一汉字扩充B

20000

2A6D6

42711

CJK 兼容汉字

F900

FA2D

302

CJK 兼容汉字

FA30

FA6A

59

CJK 兼容汉字

FA70

FAD9

106

CJK 兼容汉字补充

2F800

2FA1D

542

如果不算兼容汉字,Unicode 目前支持的汉字总数是20924+6582+42711=70217 。在早期的Unicode 版本中,CJK 统一 汉字区的范围是0x4E00-0x9FA5 ,也就是我们经常提到的20902 个汉字。当前版本的Unicode 增加了22 个字符,码位是 0x9FA6-0x9FBB

  •  生成印射表

这里使用C# 来生成GBK (兼容GB2312 )的印射表:

输出格式:put({gbk, FirstByte, SecondByte}, {UTF8FirstByte, SecondByte, ThirdByte,...}),

 

====================================================================


public string GBKCodeTable() {
    // First byte 129-254;
    // Second byte 64-254
    ushort c = 0;
    StringBuilder code = new StringBuilder ();
    byte[] src = null;
    byte[] tgt = null;
    for (byte first = 129; first < 255; first++){
        for (byte second = 64; second < 255; second++) {
            Encoding g = Encoding .GetEncoding("gbk");
            src = new byte[] { first, second };
            
            tgt = Encoding.Convert(g, Encoding.UTF8, src);
            
            code.Append("put({gbk, ");
            code.Append(src[0]);
            code.Append(", ");
            code.Append(src[1]);
            code.Append("}, ");
            code.Append("[");
            for (byte i = 0; i < tgt.Length; i++) {
                code.Append(tgt[i]);
                if (i < tgt.Length - 1) {
                    code.Append(", ");
                }
            }
            code.Append("])");
            code.AppendLine(", ");
        }
    }
    return code.ToString();
}

 

2. Erlang 代码



Module: encoding_converter

Method: start indicate that it load gbk to utf8 code mapping table
              to_utf8 indicate that it convert GBK or GB2312 to utf-8

 

其中,start 的建立表的语句见C# 的输出。因其太大(900 多K ),这里就不列出了。

 

用法:

 

encoding_converter:start().

encoding_converter:to_utf8(Str, "gb2312").

====================================================================

-module(noval_encoding).
-export([start/0, to_utf8/2]).
    
to_utf8(Str, Encoding) when Encoding == "gbk"; Encoding == "gb2312" ->
    if is_binary(Str) ->    gbk_to_utf8(binary_to_list(Str), [], 1, 1);
       is_list(Str) -> gbk_to_utf8(Str, [], 1, 1);
       true -> not_supported
    end.
    
gbk_to_utf8([Char | S], U, RowIndex, ColIndex) when Char < 128 ->
    case Char of
        10 -> gbk_to_utf8(S, [Char | U], RowIndex + 1, 0);
        _  -> gbk_to_utf8(S, [Char | U], RowIndex, ColIndex + 1)
    end;
    
gbk_to_utf8([A, B | S], U, RowIndex, ColIndex) ->
    case get({gbk, A, B}) of
        undefined ->
            io:format("gbk not found: ~p, ~p~n", [{gbk, A, B}, {index, RowIndex, ColIndex}]),
            gbk_to_utf8(S, U, RowIndex, ColIndex + 2);
        Other ->  gbk_to_utf8(S, list_append(Other, U), RowIndex, ColIndex + 2)
    end;
    
gbk_to_utf8([], U, _RowIndex, _ColIndex) ->
    lists:reverse(U).
    
list_append([], List) ->
    List;

list_append([H|T], List) ->
    list_append(T, [H | List]).
    
start() ->
    put({gbk, 129, 64}, [228, 184, 130]),

    %% others see c# output

    gbk_utf8_convert_table_ok.


 

 

 

 


 











 

 









 

 

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值