声明,以下内容均为网上搜索而来,不做特别出处
汉字编码-字符编码
输入码、区位码、国标码和机内码
区位码 +2020H ->国标码 +800H ->机内码
输入码就是使用英文键盘输入汉字时的编码.
大体可分为顺序码、音码、形码、音形码四类。
如“保”字,用全拼,输入码为码为“BAO”,用区位码(有一种特殊的区位码输入法,输入四个数字就可以打出汉字),输入码为“1703”,用五笔字型则为“WKS”。
区位码:(即国标区位码)
我国国家标准局于1981年5月颁布了《信息交换用汉字编码字符集——基本集》,代号为GB2312-80,共对6763个汉字和682个图形字符进行了编码,其编码原则为:汉字用两个字节表示,每个字节用七位码(高位为0),;国家标准将汉字和图形符号排列在一个94行94列的二维代码表中;每两个字节分别用两位十进制编码,前字节的编码称为区码,后字节的编码称为位码,此即区位码;如“保”字在二维代码表中处于17区第3位,区位码即为“1703 ”。
国标码:(即汉字国际交换码)
国标码并不等于区位码,它是由区位码稍作转换得到,
其转换方法为:先将十进制区码和位码转换为十六进制的区码和位码,;这样就得了一个与国标码有一个相对位置差的代码,;再将这个代码的第一个字节和第二个字节分别加上20H,就得到国标码。如:“保”字的国标码为3123H,它是经过下面的转换得到的:1703D->1103H->+20H->3123H。
机内码:
国标码是汉字信息交换的标准编码,但因其前后字节的最高位为0,与ASCII码发生冲突,如“保”字,国标码为31H和23H,而西文字符“1”和“#”的SCII也为31H和23H,现假如内存中有两个字节为31H和23H,;这到底是一个汉字,还是两个西文字符“1”;和“#”?于是就出现了二义性,显然,国标码是不可能在计算机内部直接采用的,于是,;汉字的机内码采用变形国标码,其变换方法为:将国标码的每个字节都加上128,即将两个字节的最高位由0改1,其余7位不变,如:由上面我们知道,“保”字的国标码为3123H,前字节为00110001B,后字节为00100011B,高位改1为10110001B和10100011B即为B1A3H,因此,字的机内码就是B1A3H;。
显然,汉字机内码的每个字节都大于128,这就解决了与西文字符的ASCII码冲突的问题。
汉字编码的发展
GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。
GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号。
从 ASCII、GB2312到GBK,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。
2000 年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。从汉字字汇上说,GB18030在GB13000.1的20902个汉字的基础上增加了CJK扩展A的6582个汉字(Unicode码 0x3400-0x4db5),一共收录了27484个汉字。
CJK就是中日韩的意思。Unicode为了节省码位,将中日韩三国语言中的文字统一编码。GB13000.1就是ISO/IEC 10646-1的中文版,相当于Unicode 1.1。
GB18030 的编码采用单字节、双字节和4字节方案。其中单字节、双字节和GBK是完全兼容的。4字节编码的码位就是收录了CJK扩展A的6582个汉字。例如:UCS的0x3400在GB18030中的编码应该是8139EF30,UCS的0x3401在GB18030中的编码应该是8139EF31。
UTF-8 GBK UTF8 GB2312 之间的区别和关系
UTF-8
Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。
GBK
在国家标准GB2312基础上,扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。
各种编码的理解
简单来说,unicode,gbk和大五码(Big-5)就是编码的值【字符集/字符编码集】,而utf-8,uft-16之类就是这个值的表现形式【字符编码方案】.
GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312
字节序
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面(高位先存放在低地址,即高位优先存储),就是big endian。如果将49写在前面,就是little endian。
Unicode、UCS和UTF
Unicode 也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"UniversalMultiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode CharacterSet"的缩写。UCS就是unicode
根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。
在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。
目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode4.1.0。ISO的最新标准是ISO 10646-3:2003。
UCS 只是规定如何编码,并没有规定如何传输、保存这个编码。例如“汉”字的UCS编码是6C49,我可以用4个ascii数字来传输、保存这个编码;也可以用 utf-8编码:3个连续的字节E6 B189来表示它。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO- 8859-1完全兼容。UTF是“UCSTransformation Format”的缩写。
4、UTF编码
UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:
UCS-2编码(16进制) UTF-8字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx10xxxxxx。将6C49写成二进制是:0110 110001 001001,用这个比特流依次代替模板中的x,得到:111001101011000110001001,即E6 B1 89。
读者可以用记事本测试一下我们的编码是否正确。需要注意,UltraEdit在打开utf-8编码的文本文件时会自动转换为UTF-16,可能产生混淆。你可以在设置中关掉这个选项。更好的工具是HexWorkshop。
UTF- 16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于 0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为 UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。
UTF的字节序和BOM
UTF- 8以字节为编码单元,没有字节序的问题。
UTF-16以两个字节为编码单元,字节顺序的方法是BOM。
BOM是Byte order Mark。
在 UCS编码中有一个叫做"ZERO WIDTHNO-BREAKSPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF- 8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTHNO-BREAKSPACE"的UTF-8编码是EF BB BF。如果接收者收到以EF BBBF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
参考资料
本文主要参考的资料是"Short overview of ISO-IEC 10646 and Unicode"(http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。
附录1再说说区位码、GB2312、内码和代码页
有的朋友对文章中这句话还有疑问:
“GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。”
我再详细解释一下:
“GB2312 的原文”是指国家1980年的一个标准《中华人民共和国国家标准信息交换用汉字编码字符集基本集 GB2312-80》。这个标准用两个数来编码汉字和中文符号。第一个数称为“区”,第二个数称为“位”。所以也称为区位码。1-9区是中文符号,16-55区是一级汉字,56-87区是二级汉字。现在Windows也还有区位输入法,例如输入1601得到“啊”。(这个区位输入法可以自动识别 16进制的GB2312和10进制的区位码,也就是说输入B0A1同样会得到“啊”。)
内码是指操作系统内部的字符编码。早期操作系统的内码是与语言相关的。现在的Windows在系统内部支持Unicode,然后用代码页适应各种语言,“内码”的概念就比较模糊了。微软一般将缺省代码页指定的编码说成是内码。
内码这个词汇,并没有什么官方的定义,代码页也只是微软这个公司的叫法。作为程序员,我们只要知道它们是什么东西,没有必要过多地考证这些名词。
所谓代码页(codepage)就是针对一种语言文字的字符编码。例如GBK的code page是CP936,BIG5的code page是CP950,GB2312的code page是CP20936。
Windows中有缺省代码页的概念,即缺省用什么编码来解释字符。例如Windows的记事本打开了一个文本文件,里面的内容是字节流:BA、BA、D7、D6。Windows应该去怎么解释它呢?
是按照Unicode编码解释、还是按照GBK解释、还是按照BIG5解释,还是按照ISO8859-1去解释?如果按GBK去解释,就会得到“汉字”两个字。按照其它编码解释,可能找不到对应的字符,也可能找到错误的字符。所谓“错误”是指与文本作者的本意不符,这时就产生了乱码。
答案是Windows按照当前的缺省代码页去解释文本文件里的字节流。缺省代码页可以通过控制面板的区域选项设置。记事本的另存为中有一项ANSI,其实就是按照缺省代码页的编码方法保存。
Windows的内码是Unicode,它在技术上可以同时支持多个代码页。只要文件能说明自己使用什么编码,用户又安装了对应的代码页,Windows就能正确显示,例如在HTML文件中就可以指定charset。
有的HTML文件作者,特别是英文作者,认为世界上所有人都使用英文,在文件中不指定charset。如果他使用了0x80-0xff之间的字符,中文 Windows又按照缺省的GBK去解释,就会出现乱码。这时只要在这个html文件中加上指定charset的语句,例如:
<metahttp-equiv="Content-Type" content="text/html;charset=ISO8859-1">
如果原作者使用的代码页和ISO8859-1兼容,就不会出现乱码了。
再说区位码,啊的区位码是1601,写成16进制是0x10,0x01。这和计算机广泛使用的ASCII编码冲突。为了兼容00-7f的ASCII编码,我们在区位码的高、低字节上分别加上A0。这样“啊”的编码就成为B0A1。我们将加过两个A0的编码也称为GB2312编码,虽然GB2312的原文根本没提到这一点。
Dos/Unix 的文本区别
在计算机领域里,所谓文本就是不含任何格式的文字!
DOS下和UNIX下的文本格式在换行符有些差异:UNIX是\n,而Windows\DOS下是\r\n
即基于DOS/Windows的文本文件在每一行末尾有一个CR(回车)和 LF(换行),而 UNIX文本只有一个换行。
MAC的换行符为CR
JC:DOS和unix是文本的运行环境
JC:UTF-8,Unicode、ASCII等多种文本编码格式是文本文件的存储编码方式
ultraedit中^n(表示UNIX文件中的回车换行符号),^p(表示DOS文件中的回车换行符号)
手机认证测试
一致性测试
包括:射频测试、协议测试、音频测试、OTA测试和EMC测试等
GCF
Global Certification Forum,全球认证论坛
GCF是由运营商和终端制造商共同成立的一个组织,目的是通过独立的认证过程来确保终端的全球互操作。
它包含了主要的GSM(或未来的UMTS)网络运营商和世界上主流的终端制造商,并邀请测试仪器仪表开发商参加GCF的活动
定义了每个终端所必须接受的测试,保证了终端的可靠、一致的行为。
PTCRB
PCS Type Certification Review Board(PCS型号认证委员会),成立于1997年3月,并于2001年5月加入了对GSM850频段的要求,是美国标准化组织发展的一个重要的里程碑。
与GCF类似的,PTCRB也是有运营商和一些大的手机厂商组成,还包括一些认可实验室。PTCRB的成员分为两个级别,完全会员(Full or ActiveMembers)和观察员(Passiveor Observing Members)。
FTA
FTA测试全称是全面型号认证(FULL TYPE APPROVAL)。所有的移动电话生产企业为了使自己生产的手机能进入市场,都必须取得国际移动设备标识(该标识在全球范围内是唯一的),
即IMEI, IMEI是由GSM MOU(即GSM联盟,包括GSM的运营商和GSM手机的生厂商)组织授权的中立的发证机构(NOTIFY BODY)
根据FTA 认证实验室的测试报告发放。其内容分为软件测试、硬件测试和电磁兼容测试,测试项目共有三百多项
CTA
china type approval
手机生产环节
BVT
BVT是Build Verification Test,基本验证测试,对完成的代码进行编译和连接,产生一个构造,以检查程序的主要功能是否会像预期一样进行工作。
DVT
DVT是Design Verification Test的简称,设计验证测试,是硬件生产中不可缺少的一个检测环节,包括模具测试、电子性能、外观测试等等。
PVT
PVT全称为Process Verification Test,意为小批量过程验证测试,硬件测试的一种,主要验证新机型的各功能实现状况并进行稳定性及可靠性测试
EVT
EVT-Engineer Verification Test,工程样品验证测试
数据校验(奇偶、CRC)
1.1什么是数据校验
通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。
1.2最简单的检验
实现方法:最简单的校验就是把原始数据和待比较数据直接进行比较,看是否完全一样这种方法是最安全最准确的。同时也是效率最低的。
适用范围:简单的数据量极小的通讯。
关于比较流行的数据校验算法有很多,如奇偶校验Parity Check、 bcc异或校验法(blockcheck character)、 crc循环冗余校验(Cyclic Redundancy Check)、 md5校验。各个算法的适用范围不同,前两种适用于要求不太高的数据通信,cr则可用于硬盘数据和网络传输,而md5则适用于数据比较大或要求比较高的场合。
/***奇偶校验Parity Check******************************************/
实现方法:在数据存储和传输中,字节中额外增加一个比特位,用来检验错误。校验位可以通过数据位异或计算出来。
应用例子:单片机串口通讯有一模式就是8位数据通讯,另加第9位用于放校验值。
/***BCC******************************************/
bcc异或校验法(block check character)
实现方法:很多基于串口的通讯都用这种既简单又相当准确的方法。它就是把所有数据都和一个指定的初始值(通常是0)异或一次,最后的结果就是校验值,通常
把她附在通讯数据的最后一起发送出去。接收方收到数据后自己也计算一次异或和校验值,如果和收到的校验值一致就说明收到的数据是完整的。
校验值计算的代码类似于:
unsigned uCRC=0;//校验初始值
for(int i=0;i<DataLenth;i++)uCRC^=Data[i];
适用范围:适用于大多数要求不高的数据通讯。
应用例子:ic卡接口通讯、很多单片机系统的串口通讯都使用。
/***CRC******************************************/
Cyclic Redundancy Check
下面为CRC的计算过程:
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
TTL / RS232 电平
Chipset UART is TTL; PC UART is RS232
S232电平为+12V为逻辑负,-12为逻辑正,TTL电平为5V为逻辑正,0为逻辑负