汉字与区位码互转(天天使用的String存储的是内码),几个常见汉字编码,附有读书笔记
汉=BABA(内码)=-A0A0=2626(区位码)
字=D7D6(内码)=-A0A0=5554(区位码)
各种编码查询表:http://bm.kdd.cc/
“啊”字是GB2312之中的第一个汉字,会以两个字节,0xB0(第一个字节)0xA1(第二个字节)储存。
难=C4D1=50385
汉=BABA=47802
字=D7D6=55254
中=D6D0=54992
文=CEC4=52932
国=B9FA=47610
华=BBAA=48042
夏=CFC4=53188
吴=CEE2=52962
A=65
€=128
À=192
æ=230
GBK里特有的字:
在GB 2312-80推出以后才简化的汉字(如“啰”)
部分人名用字(如中国前总理朱镕基的“镕”字)
GBK3扩充区的第一个汉字“丂”的ANSI编码是8140H,这一点是经过理论和实践双验证的。
GBK的存储方式是大头存储,但Unicode是小头存储,参考:
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
----------------------------------------------------------------------------------------------
//汉字转区位码
function Str2GB(const S: AnsiString): string;
const G = 160; // 160 = hA0
var n, m: word;
begin
n := Ord(S[1]);
m := Ord(S[2]);
Result := FormatFloat('00', n-G) + FormatFloat('00', m-G);
end;
//区位码转汉字
function GB2Str(const n: Word): string;
const G = 160;
begin //前2位数 //后2位数
Result := string(AnsiChar(n div 100 + G) + AnsiChar(n mod 100 + G));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GB2Str(StrToInt(Edit1.Text)));
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(Str2GB(AnsiString(Edit2.Text)));
end;
----------------------------------------------------------------------------------------------
特别注意,这是D7-XE7都可以使用的程序。因为ANSI与Unicode的区别仅仅在于,ANSI英文表示是一个字符,Unicode的英文是两个字符。但ANSI和Unicode处理中文的时候,都是两个字符,且两者内容完全一致。这么说ANSI与Unicode对汉字的处理几乎没有区别,区别在于对英文字符的处理,并且Unicode下还能处理除了中文以外的语言的特殊字符(比如俄文字符)。另外各个不同的ANSI编码之间那就真的是完全不同、鸡对鸭讲了。
===================================================
总结:这说明平时天天用到String,存储的是汉字的内码(不是区位码)。理论解释:汉字机内码,又称“汉字ASCII码”,简称“内码”,指计算机内部存储,处理加工和传输汉字时所用的由0和1符号组成的代码。输入码被接受后就由汉字操作系统的“输入码转换模块”转换为机内码,与所采用的键盘输入法无关。机内码是汉字最基本的编码,不管是什么汉字系统和汉字输入方法,输入的汉字外码到机器内部都要转换成机内码,才能被存储和进行各种处理。
前面是使用的是“内码”和“区位码”,其实还有一个“国际码”,关系如下:
内码(String使用的编码)=国标码(国家定义)+8080H(其实就是使最高位为1)=区位码(国家定义的基础表格)+A0A0H(多加了2020H)
出现最高位的原因是:
汉字处理系统要保证中西文的兼容,当系统中同时存在ASCII码和汉字国标码时,将会产生二义性。例如:有两个字节的内容为30H和21H,它既可表示汉字“啊”的国标码,又可表示西文“0”和“!”的ASCII码。为此,汉字机内码应对国标码加以适当处理和变换。国标码的内码为二字节长的代码,它是在相应国标码的每个字节最高位上加“1”。
出现国标码的原因是:
GB2312-80 GB2312将代码表分为94个区,对应第一字节;每个区94个位,对应第二字节,两个字节的值分别为区号值和位号值加32(20H),因此也称为区位码。(读书笔记:94=5EH,这个值远小于128,因此加上20H等于7EH=126,因此再做变换没关系。而且我查了具体的Word文件,最后一项编码就是5E,而不是5F,这只能说GB2312定义的字符太少了,没有充分利用所有的空间。而且我特别注意到,每一个区的最后一行的低位F位置,确实没有定义任何汉字。问题,为什么要做变换?回答:查完基础表以后,再加上2020H就是国标码,政府就是这么规定的,没什么理由。为了方便和快速处理,实际编程使用最方便计算机标识的编码——内码,来使用,就可以直接标识是否汉字。区位码和国标码只是一种理论解释和定义,对程序员来说其实没什么用的。)
国标码是汉字信息交换的标准编码,但因其前后字节的最高位为0,与ASCII码发生冲突(读书笔记:国标码定义有道理,但不实用。另外我查了一下网上的GB2312Word文件,第一个字符就是A1A1,即已经加好了A0A0的内码,这样虽然对程序员更实用,但这个表格其实已经是被加工过的,而不是国家最初定义的从零开始的基础表格),如“保”?字,国标码为31H和23H,而西文字符“1”和“#”的ASCII也为31H和23H,现假如内存中有两个字节为31H和23H,这到底是一个汉字?,还是两个西文字符“1”和“#”于是就出现了二义性,显然,国标码是不可能在计算机内部直接采用的,于是,汉字的机内码采用变形国标码。
其变换方法为:将国标码的每个字节都加上128,即将两个字节的最高位由0改1,其余7位不变,如:由上面我们知道,“保”字的国标码为3123H,前字节为00110001B,后字节为00100011B,高位改1为10110001B和10100011B 即为B1A3H,因此,汉字的机内码就是B1A3H。
参考:
http://baike.baidu.com/view/1199269.htm
http://baike.baidu.com/view/990066.htm
举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。
例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节)0xA1(第二个字节)储存。(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。
---------------------------------------------------------------------------
下一个问题:测试一下QT存储的是什么码?我猜是内码的Unicode标识。因此QT字符串与Unicode版Delphi字符串应该兼容的(Delphi字符串头部在负方向,QT看不到)
汉字与区位码互转(天天使用的String存储的是内码),几个常见汉字编码,附有读书笔记的更多相关文章
- 汉字与区位码互转(天天使用Delphi的String存储的是内码,Windows记事本存储的文件也是内码),几个常见汉字的各种编码,utf8与unicode的编码在线查询,附有读书笔记 good
汉=BABA(内码)=-A0A0=2626(区位码)字=D7D6(内码)=-A0A0=5554(区位码) 各种编码查询表:http://bm.kdd.cc/ 汉(记住它,以后碰到内存里的数值,就会有敏 ...
- JavaScript 汉字与拼音互转终极方案 附JS拼音输入法
转:http://www.codeceo.com/article/javascript-pinyin.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的 ...
- 【干货】JS版汉字与拼音互转终极方案,附简单的JS拼音输入法
前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...
- unicode编码、字符的转换和得到汉字的区位码
一:unicode编码.字符的转换截图 二:unicode编码.字符的转换代码 using System; using System.Collections.Generic; using System ...
- C# 汉字与区位码之间的相互转换(中文数字字母可以,支持空格,但是特殊字符未来得及测试)
using System; using System.Text; namespace Test { class MainClass { /// <summary> /// 中文空白字符,用 ...
- JS版汉字与拼音互转终极方案,附简单的JS拼音输入法
原文:http://www.cnblogs.com/liuxianan/p/pinyinjs.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多 ...
- JS版汉字与拼音互转终极方案,附简单的JS拼音
前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...
- 字王·国标二级字库汉字GB内码un码三合一对照表2016版
国标二级字库汉字GB内码un码三合一对照表 字王2016版 汉字内码表,是制作字库的基础,简单.便利的版本很少,根据实战经验,特此制作这个三合一版本的汉字.GB内码.Unicode码对照表: l 提供 ...
- 刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?(没有BOM,所以被误判为UTF8。“联通”两个汉字的GB内码,其第一第二个字节的起始部分分别是“110”和“10”,,第三第四个字节也分别是“110”和“10”)
1. 当用一个软件(比如Windows记事本或Notepad++)打开一个文本文件时,它要做的第一件事是确定这个文本文件究竟是使用哪种编码方式保存的,以便于该软件对其正确解码,否则将显示为乱码. 一般 ...
随机推荐
- linux之let用法
shell程序中的操作默认都是字符串操作,在要运行数学运算符的时候可能得到意想不到的答案: var=1 var=$var+1 echo $var output:1+1 从这个例子中可以看出shell字 ...
- SSH无密码登陆问题解决
转载 http://my.oschina.net/hunzi/blog/10687 安装好Cygwin后,SSH需要设置为无密码登陆, 首先查看是ssh还是ssh2:ls -l `which ssh` ...
- vs2010开发android的准备工作
安装 Mono for Android for Visual Studio 2010 需要下面4个步骤: 安装 JDK 安装 Android SDK 配置模拟器 安装 Mono for Android ...
- 初尝Windows 下批处理编程
本文叫“ 初尝Windows 下批处理编程”是为了延续上一篇“初尝 Perl”,其实对于博主而言批处理以及批处理编程早就接触过了. 本文包括以下内容 1.什么是批处理 2.常用批处理命令 3.简介批处 ...
- C++ txt文档读取
void readfile(string filepath){ ifstream myfile; if (!myfile) { cout << "打开文件出错!"; e ...
- 关于php的认识和介绍
php的介绍: 什么是php? <1>:php是一个编程语言 <2>:php是处理php编程语言的一个软件.php语言必须运行在php软件上. 为什么要学习php? php可以 ...
- Windows Phone 8 开发初体验
Windows Phone 8 是当前除了Android.IPhone之外,第3大智能手机运行平台.作为微软技术的忠实fans,一直关注和跟进微软技术的最新进展.这里就给大家简单介绍一下,如何进行Wi ...
- Win7 钩子 超时 失效
这段时间在程序中,使用了全局钩子,但是在测试时发现,会偶尔失效. 在网上搜索到了这两篇文章: VC底层钩子程序在Win7/Vista下无效 Hooking problem in Windows 7 这 ...
- Cakephp 创建无模型的Controller
控制器(Controller)如果没有特定的表/模型关联的话,哪怕建测试都会出错,但你可以加一行到控制器(Controller)里就好了public $uses=array(); 或者 public ...
- 宅男福利--利用Python简单爬图
Ver beta..代码粗陋. 使用说明以Windows为例, Python版本为2.7.6 确认你电脑已经安装了Python, Windows默认安装路径为C:\Python27.如果没有安装,先下 ...