要从事学术研究,一定要学好数学,数学可以把对事物的描述精确化。
tuenhai为什么要学习编程?其中一个原因就是利用编程工具进行一些数学运算。
记得大约10年前,那时tuenhai还没有电脑,要进行大数计算,怎么办?那时就到处打听,哪里有数位多一些的计算器。一般计算器只有8位,多一些的12位,还是不够用。有一次和故人到大城市,总算打听到了超过12位的计算器,考虑再三,还是没有买下来(不知故人还有没有记得这件事,毕竟过去这么多年了)。

父亲把我们以前读过的教材,练习本都保存着,我把粘满灰尘的数学教材找出来,放在我的书房,有时还会去随便翻翻。
现在学校教育是彻头彻尾的失败。教育没有和实际结合,毕业不久,学过的知识就很多交还给老师了。想起来,学校教育至少浪费了我5年光阴,工作中又至少浪费了我8年光阴,从出生到现在,竟有近一半时间浪费掉了,实在可怕。

把学校教育批评得一无是处,那么理想的教育应该是怎么样的呢?
理想的教育应该是一切学科相通的,只有这样,知识才能活起来,学而即用,不用死记。这样的学习,只有快乐,没有痛苦。

这样的学校教育可谓是完美,在这个不完美的世界可能永远不会实现。就象中医,这么多人说要发扬真正的中医,但现代人没有这个福气,连伪中医都要衰落,何况真中医。现代“小火神”为什么不写书,或许有深机在焉。

一切学科相通,从而理解这个世界,这个题目太大了,tuenhai(tuenhai.com)也只是玩味了一点点。这里只讨论一下用编程的方法数字与汉字的转换,同时也附录一些资料,方便研究。

'tuenhai所用获得汉字或字符对应的区位符
Function quwei(ByVal x As String) As String '
x = Asc(x) 'Asc 返回输入字符的码位或字符代码。对于单字节字符集 (SBCS),返回值范围为 0 到 255;对于双字节字符集 (DBCS),返回值范围为 -32768 到 32767。对于单字节 ASCII 字符的图表,请参见 ASCII 字符代码。
x = Hex((x)) '返回表示数字的十六进制值的字符串。刘=FFFFC1F5,前面的4个F去掉,得到16进制的内码。16进制的C=10进制的12
Dim str As String
str = Format(CDec("&H" & Strings.Mid(x, 5, 2)) - 160, "00") & Format(CDec("&H" & Strings.Mid(x, 7, 2)) - 160, "00")
'Strings.Mid(x, 5, 2) '得到16进制的内码,“刘”内码高位=C1
'CDec("&H" & str) '转换成10进制内码,"&H"表示16进制 “刘”内码高位=193
'-160 得到10进制区码, “刘”区码是33
'Format(decQu, "00") '格式化为两位数表示
Return str
End Function
'GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0,
'在DBCS中,GB内码的存储格式始终是big endian,即高位在前。
' 区位码是与汉字一一对应的编码,用四位数字表示, 前两位从01 到94称区码,后两位从01到94称位码。 一个汉字的前一半是 ASCⅡ码为“160+区码”的字符,后一半是ASCⅡ码为“160+ 位码”的字符。
'例如:“刘”的区位码是 3385,其意为区码33位码85,它是由ASCⅡ码为160+33=193和160+85=245的两个字符组成。

'tuenhai所用获得区位符对应汉字或字符
Function hanzi(ByVal x As String) As String '
On Error Resume Next
Dim str As String
str = Chr("&H" & Hex(Val(Strings.Left(x, 2)) + 160) & Hex(Val(Strings.Right(x, 2)) + 160))
Return (str)
End Function
'Chr 使用 System.Text 命名空间中的 Encoding 类来确定当前线程使用的是单字节字符集 (SBCS) 还是双字节字符集 (DBCS)。然后将 CharCode 作为相应字符集中的码位。对于 SBCS 字符,范围为 0 到 255,对于 DBCS 字符,范围为 -32768 到 65535。
'ChrW 以 CharCode 作为 Unicode 码位。其范围与当前线程的区域性和代码页设置无关。-32768 到 -1 范围内的值的处理方式与 +32768 到 +65535 范围内的值相同。

(更多文章请访问www.tuenhai.com 20060427 剡)

<<<区位码>>>

附录:

从汉字到区位码的转换

http://blog.csdn.net/leeajax/archive/2004/07/12/39686.aspx
学校要我们填写毕业生的情况表,机读卡那种,姓名要用区位码.我想如果用程序来查询的话,就是数据库查找,我想编一个应该很简单的,就上网看看有没有类似的程序,然后我再用它的数据库自己实现一个,可让我查到了一个文章讲如何实现从汉字到区位码的转换,呵呵,可以不用数据库了.
区位码是与汉字一一对应的编码,用四位数字表示, 前两位从01 到94称区码,后两位从01到94称位码。 一个汉字的前一半是 ASCⅡ码为“160+区码”的字符,后一半是ASCⅡ码为“160+ 位码”的字符。
例如:“刘”的区位码是 3385,其意为区码33位码85,它是由ASCⅡ码为160+33=193和160+85=245的两个字符组成。

我用简单的控制台程序实现如下
#i nclude
#i nclude
void main()
{
char i[64];
while(1)
{
cout<<"输入单个字母退出"< cin>>i;
if(strlen(i)==1)break;
for(int j=0;j cout<<(i[j]+96)*100+i[j+1]+96< }
}

如何随机生成指定数目的国标汉字?

http://blog.csdn.net/northwolves/archive/2004/07/25/51270.aspx

为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准: GB2312-80《信息交换用汉字编码字符集》基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个"区",每一列称为一个"位",因此,这个方阵实际上组成了一个有94个区(区号分别为0 1到94)、每个区内有94个位(位号分别为01到94)的汉字字符集。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的"区位码"。在汉字的区位码中,高两位为区号,低两位为位号。 在区位码中,01-09区为682个特殊字符,16~87区为汉字区,包含6763个汉字 。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列)。

所以,当我们需要n个任意汉字时,我们不必建一个全部汉字表,而是利用区位码实现常用汉字的提取。

下面的代码可以实现任意数目汉字的生成:

Private Sub getrndhanzi(ByVal n As Integer)
Dim s() As String, i As Integer
Dim temp1 As Integer, temp2 As Integer
ReDim s(1 To n)
Randomize
For i = 1 To n
temp1 = 16 + Int(Rnd * 72)
If temp1 = 55 Then
temp2 = Int(Rnd * 90) '一级汉字从1601-1694,1701-1794,.....5401-5494,5501-5589,共94*40-5=3755 个汉字
Else
temp2 = Int(Rnd * 95) '二级汉字从5601-5694,5701-5794,.....8601-8694,8701-8794,共94*32=3008 个汉字
End If
s(i) = Chr("&H" & Hex(temp1 + 160) & Hex(temp2 + 160))
Next
Debug.Print Join(s, "")'输出
End Sub

Private Sub Command1_Click()
Dim i As Integer
For i = 1 To 25 '分别生成1-25个任意汉字
getrndhanzi i
Next
End Sub

输出:


夫敞
途罨椽
涅搦侄铽
榨藸禒艟球
枵舟斟盯滩桫
狲暗田苫撂蕾岢
冠澧炫鲼噘惺馘柘
巧愁炔哔臆策籼锭昏
紶假媪慈乘嘎肤景濡薤
呋刨锺灰榉懋唇弱献囟垤
均耋撤阗驿迩愍殒埚砸宕薅
蒹翦俄形碌哧烀爝懒缭嫔捭浑
瑾砜疬哜遒濂勾彐綘珩苓就萌炳
光椁旖趁鲲頎壕狁媪暑额忾帷淤黹
湫熏裤降旺廓淳傻蜕脬荪色注紫劾吾
陶沥瑗骶埴于喃刮瘿突赅斛简铨觞抨唼
格鸽乜衍夙菀鲡败陆褐哙苑滓淆踵讫头绑
德泠婷岙湔池桨郅峁汩卒控诉刍镗椎鬣越嫉
义懂聂其定鳓脯膪巯吐昏罚返抖陵沌戗喘茺缂
废雾旯浠疼赃勋妓鳟埏帮盂蕹朐裂祆膻拌脎威纯
宛免作绣稞涑枭搬怿旦熨呈弃驰翔聚饰栩燧艴氢贫
豕源髑乍蚍夏己履毕芤毁篑子褊崖坏忑霉钿瘢驵迁裨
獬纷胚桨衫蹒疯祧武琢吣酃踱免逘浊顸坐磬挫郐婶缪锰
拽技薯帙陕槲逗蜱嘧雌怙诖椭踉盔锍认致暝榴蘖逆捻螨噬

附:

汉字与区位码转换代码:

Function quwei(ByVal x As String) As String '获得某汉字或字符对应的的区位码
If Asc(x) >= 0 Then Exit Function
x = Hex(Asc(x))
quwei = Format(CDec("&H" & Left(x, 2)) - 160, "00") & Format(CDec("&H" & Right(x, 2)) - 160, "00")
End Function

Function hanzi(ByVal x As String) As String'获得某区位码对应汉字或字符
hanzi = Chr("&H" & Hex(Val(Left(x, 2)) + 160) & Hex(Val(Right(x, 2)) + 160))
End Function

经验总结--字符串与编码

http://www.cnblogs.com/hellosnoopy/articles/98127.html

Posted on 2005-01-27 12:17 HelloSnoopy开发田地 阅读(229) 评论(0) 编辑 收藏 收藏至365Key
SRC:http://search.csdn.net/Expert/topic/1880/1880675.xml?temp=3.344363E-02
这几个月作手机短信的项目,碰到了很多字符编码的问题,真头痛。经过多番资料的搜索、亲手尝试和高人的指点,现在好像没那么迷惘了。现作了一些总结跟大家分享(有误之处请指点)

首先应该把字节数组看成是String的载体。
dot Net使用的字符串String是Unicode编码的;它也是以Unicode编码的形式显示字符串。

以下是用自己语言对几个常用函数的说明:
(自己总结的,反正看不明MSDN)
bytes=System.Text.Encoding.Unicode.GetBytes(str)
作用:把str的载体作Unicode->Unicode的编码转换--也就是没有对载体作任何的转换。因些使用此函数可以得代表该String载体的字节数组。
str=System.Text.Encoding.Unicode.GetString(bytes)
作用:对字节数组作Unicode->Unicode的编码转换--即没有转换,把经过转换后的字节数组作为str的载体。

bytes=System.Text.Encoding.Utf8.GetBytes(str)
作用:把str的载体作Utf8->Unicode的编码转换。返回的是经过转换后的字符数组
str=System.Text.Encoding.Utf8.GetString(bytes)
作用:对字节数组作Gb2312->Unicode的编码转换,把经过转换后的字节数组作为str的载体。

bytes=System.Text.Encoding.GetEncoding("GB2312").GetBytes(str)
作用:把str的载体作Gb2312->Unicode的编码转换。返回的是经过转换后的字符数组
str=System.Text.Encoding.GetEncoding("GB2312").GetString(bytes)
作用:对字节数组作Gb2312->Unicode的编码转换,把经过转换后的字节数组作为str的载体。

如此类推
bytes=System.Text.Encoding.GetEncoding("XXX").GetBytes(str)
作用:把str的载体作XXX->Unicode的编码转换。返回的是经过转换后的字符数组
str=System.Text.Encoding.GetEncoding("XXX").GetString(bytes)
作用:对字节数组作XXX->Unicode的编码转换,把经过转换后的字节数组作为str的载体。

这里是我收集的一些有关字符编码的资料:http://61.145.116.154/bm/
还有:
http://www.unicode.org/charts/unihan.html
根据Unicode编码查其对应字符的字形、Utf8、汉字区位码等
http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/GB/GB2312.TXT Unicode与Gb2312的对照表
http://www.sun.com/developers/gadc/technicalpublications/articles/mabiao.txt
Unicode与Gbk对照表

用C#生成中文汉字验证码的基本原理

http://dev.csdn.net/develop/article/67/67031.shtm

前几天去申请免费QQ号码,突然发现申请表单中的验证码内容换成了中文,这叫真叫我大跌眼镜感到好笑,Moper上的猫儿们都大骂腾讯采用中文验证码。^_^
我不得不佩服腾讯为了防止目前网络上横行的QQ号码自动注册机而采取中文验证码的手段。仔细想了想感觉用程序生成随机的中文验证码并不是很难,下面就来介绍一下使用C#生成随机的中文汉字的原理。

1、汉字编码原理
到底怎么办到随机生成汉字的呢?汉字从哪里来的呢?是不是有个后台数据表,其中存放了所需要的所有汉字,使用程序随机取出几个汉字组合就行了呢?使用后台数据库先将所有汉字存起来使用时随机取出,这也是一种办法,但是中文汉字有这么多,怎么来制作呢?其实可以不使用任何后台数据库,使用程序就能做到这一切。要知道如何生成汉字,就得先了解中文汉字的编码原理。
1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准: GB2312-80《信息交换用汉字编码字符集》基本集,简称GB2312,这个字符集是我国中文信息处理技术的发展基础,也是国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,简称GB18030,编程时如果涉及到编码和本地化的朋友应该对GB18030很熟悉。这是是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,同时也是未来我国计算机系统必须遵循的基础性标准之一。
目前在中文WINDOWS操作系统中,.NET编程中默认的的代码页就是GB18030简体中文。但是事实上如果生成中文汉字验证码只须要使用GB2312字符集就已经足够了。字符集中除了我们平时大家都认识的汉字外,也包含了很多我们不认识平时也很少见到的汉字。如果生成中文汉字验证码中有很多我们不认识的汉字让我们输入,对于使用拼音输入法的朋友来说可不是好事,五笔使用者还能勉强根据汉字的长相打出来,呵呵!所以对于GB2312字符集中的汉字我们也不是全都要用。
中文汉字字符可以使用区位码来表示,见

汉字区位码表 http://navicy2005.home4u.china.com/resource/gb2312tbl.htm
汉字区位码代码表 http://navicy2005.home4u.china.com/resource/gb2312tbm.htm

其实这两个表是同一回事,只不过一个使用十六进制分区表示,一个使用区位所在的数字位置表示。 例如“好”字的十六进制区位码是ba c3,前两位是区域,后两位代表位置,ba处在第26区,“好”处在此区汉字的第35位也就是c3位置,所以数字代码就是2635。这就是GB2312汉字区位原理。根据《汉字区位码表 》我们可以发现第15区也就是AF区以前都没有汉字,只有少量符号,汉字都从第16区B0开始,这就是为什么GB2312字符集都是从16区开始的。

2、.Net程序处理汉字编码原理分析
在.Net中可以使用System.Text来处理所有语言的编码。在System.Text命名空间中包含众多编码的类,可供进行操作及转换。其中的Encoding类就是重点处理汉字编码的类。通过在.NET文档中查询Encoding类的方法我们可以发现所有和文字编码有关的都是字节数组,其中有两个很好用的方法:

Encoding.GetBytes ()方法将指定的 String 或字符数组的全部或部分内容编码为字节数组
Encoding.GetString ()方法将指定字节数组解码为字符串。

没错我们可以通过这两个方法将汉字字符编码为字节数组,同样知道了汉字GB2312的字节数组编码也就可以将字节数组解码为汉字字符。通过对“好”字进行编码为字节数组后

Encoding gb=System.Text.Encoding.GetEncoding("gb2312");
object[] bytes=gb.Encoding.GetBytes ("好");

发现得到了一个长度为2的字节数组bytes,使用

string lowCode = System.Convert.ToString(bytes[0], 16); //取出元素1编码内容(两位16进制)
string hightCode = System.Convert.ToString(bytes[1], 16);//取出元素2编码内容(两位16进制)

之后发现字节数组bytes16进制变码后内容竟然是{ba,c3},刚好是“好”字的十六进制区位码(见区位码表)。
因此我们就可以随机生成一个长度为2的十六进制字节数组,使用GetString ()方法对其进行解码就可以得到汉字字符了。不过对于生成中文汉字验证码来说,因为第15区也就是AF区以前都没有汉字,只有少量符号,汉字都从第16区B0开始,并且从区位D7开始以后的汉字都是和很难见到的繁杂汉字,所以这些都要排出掉。所以随机生成的汉字十六进制区位码第1位范围在B、C、D之间,如果第1位是D的话,第2位区位码就不能是7以后的十六进制数。在来看看区位码表发现每区的第一个位置和最后一个位置都是空的,没有汉字,因此随机生成的区位码第3位如果是A的话,第4位就不能是0;第3位如果是F的话,第4位就不能是F。
好了,知道了原理,随机生成中文汉字的程序也就出来了,以下就是生成4个随机汉字的C#控制台代码:

3、程序代码:

using System;
using System.Text;

namespace ConsoleApplication
{
class ChineseCode
  {
public static void Main()
{
//获取GB2312编码页(表)
Encoding gb=Encoding.GetEncoding("gb2312");

//调用函数产生4个随机中文汉字编码
object[] bytes=CreateRegionCode(4);

//根据汉字编码的字节数组解码出中文汉字
string str1=gb.GetString((byte[])Convert.ChangeType(bytes[0], typeof(byte[])));
string str2=gb.GetString((byte[])Convert.ChangeType(bytes[1], typeof(byte[])));
string str3=gb.GetString((byte[])Convert.ChangeType(bytes[2], typeof(byte[])));
string str4=gb.GetString((byte[])Convert.ChangeType(bytes[3], typeof(byte[])));

//输出的控制台
   Console.WriteLine(str1 + str2 +str3 +str4);
   }

/**//*
此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组,每个字节数组代表一个汉字,并将
四个字节数组存储在object数组中。
参数:strlength,代表需要产生的汉字个数
*/
public static object[] CreateRegionCode(int strlength)
{
//定义一个字符串数组储存汉字编码的组成元素
string[] rBase=new String [16]{"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

Random rnd=new Random();

//定义一个object数组用来
object[] bytes=new object[strlength];

/**//*每循环一次产生一个含两个元素的十六进制字节数组,并将其放入bject数组中
每个汉字有四个区位码组成
区位码第1位和区位码第2位作为字节数组第一个元素
区位码第3位和区位码第4位作为字节数组第二个元素
*/
for(int i=0;i {
//区位码第1位
int r1=rnd.Next(11,14);
string str_r1=rBase[r1].Trim();

//区位码第2位
rnd=new Random(r1*unchecked((int)DateTime.Now.Ticks)+i);//更换随机数发生器的

种子避免产生重复值
int r2;
if (r1==13)
{
r2=rnd.Next(0,7);
}
else
{
r2=rnd.Next(0,16);
}
string str_r2=rBase[r2].Trim();

//区位码第3位
rnd=new Random(r2*unchecked((int)DateTime.Now.Ticks)+i);
int r3=rnd.Next(10,16);
string str_r3=rBase[r3].Trim();

//区位码第4位
rnd=new Random(r3*unchecked((int)DateTime.Now.Ticks)+i);
int r4;
if (r3==10)
{
r4=rnd.Next(1,16);
}
else if (r3==15)
{
r4=rnd.Next(0,15);
}
else
{
r4=rnd.Next(0,16);
}
string str_r4=rBase[r4].Trim();

//定义两个字节变量存储产生的随机汉字区位码
byte byte1=Convert.ToByte(str_r1 + str_r2,16);
byte byte2=Convert.ToByte(str_r3 + str_r4,16);
//将两个字节变量存储在字节数组中
byte[] str_r=new byte[]{byte1,byte2};

//将产生的一个汉字的字节数组放入object数组中
bytes.SetValue(str_r,i);

}

return bytes;

}
  }

}

实现了随机生成汉字后,就可以使用.NET GDI来绘制自己需要的验证码图形了。具体的怎样生成验证码图片,以及改变其中字符的长和宽等效果网上已经有很多相关的文章,这里由于篇幅就不再介绍了。不过有一点要说明的是以上代码在中文版的Windows下才能运行,因为它带有GB的字符集,如果你是其他语言的操作系统,就需要安装GB字符集了。

有什么问题可以到 http://www.cnblogs.com/navicy/ 发表看法。
http://navicy.126.com

用.NET获取汉字的区位码(C#)

http://dev.csdn.net/article/58/58359.shtm

首先复习一下计算机基础知识:

  计算机中最底层的数据都是用二进制及0和1来表示的。每个0或1称作1位,第8位二进制数叫做1个字节,它可以表示ASCII码中的一个字符。中文计算机中用两个字节即16位二进制来表示一个汉字。而在Unicode编码中所有的符号(包括汉字,英文,标题及其它众多符号)都是为两字节(16)位来表示。

  在System.Text命名空间中包含众多编码的类,可供进行操作及转换,下面用两个实例来进行区位码及汉字之间的互换,希望能起到举一反三的效果,让大家可以轻松处理文字编码方面的问题:

程序代码:

  using System;
  using System.Text;
  class CodingChange
  {
  public string CharacterToCoding(string character)
  {
  string coding = "";
  for (int i = 0; i  {
  byte[] bytes = System.Text.Encoding.Unicode.GetBytes(character.Substring(i,1)); //取出二进制编码内容
  string lowCode = System.Convert.ToString(bytes[0], 16); //取出低字节编码内容(两位16进制)
  if (lowCode.Length == 1)
  lowCode = "0" + lowCode;
  string hightCode = System.Convert.ToString(bytes[1], 16);//取出高字节编码内容(两位16进制)
  if (hightCode.Length == 1)
  hightCode = "0" + hightCode;
  coding += (lowCode + hightCode);//加入到字符串中,
  }
  return coding;
  }
  public string CodingToCharacter(string coding)
  {
  string characters = "";

转自:http://www.guoblog.com/blogview.asp?logID=201

作者Blog:http://blog.csdn.net/AppleBBS/

2进制、8进制、10进制、16进制...各种进制间的轻松转换(c#)

http://blog.csdn.net/gztoby/archive/2004/08/16/76293.aspx

在.NET Framework中,System.Convert类中提供了较为全面的各种类型、数值之间的转换功能。其中的两个方法可以轻松的实现各种进制的数值间的转换:

Convert.ToInt32(string value, int fromBase):

可以把不同进制数值的字符串转换为数字,其中fromBase参数为进制的格式,只能是2、8、10及16:

如Convert.ToInt32(”0010”,2)执行的结果为2;

Convert.ToString(int value, int toBase):

可以把一个数字转换为不同进制数值的字符串格式,其中toBase参数为进制的格式,只能是2、8、10及16:

如Convert.ToString(2,2)执行的结果为”0010”

现在我们做一个方法实现各种进制间的字符串自由转换:选把它转成数值型,然后再转成相应的进制的字符串:

public string ConvertString(string value, int fromBase, int toBase)

{

int intValue = Convert.ToInt32(value, fromBase);

return Convert.ToString(intValue, toBase);
}

其中fromBase为原来的格式

toBase为将要转换成的格式

yolle [原作]

进制转换

http://www.ypdoor.com/blog/article.asp?id=76
电脑上的常用进制有:2、8、10、16四种,在修改中经常接触的是2、10和16进制,基本上需要了解的是2和16互转、10和16互转,其他多了解也没亏

2转16:

4个2进制位为一个16进制数,2进制1111为16进制F,2进制中千位的1=8,百位的1=4,十位的1=2,个位的1=1,将各个位的数作相应转换再相加,的到的数就是10进制数0-15,可轻松转换成16进制。如01011100,可看成是两组2进制数0101和1100,则这个数就是16进制的5C。

10转16:

100以内一点的10转16心算比较快,复杂的用“计算器”算了。10转16用传统的计算方式可以了,就是大于15小于256的10进制数除以16为的值为十位的16进制数,其余数为个位的16进制数,没余数则个位为0。如61的16进制是3D,61除以16得3余13,3作十位数,13转成D为各位数。
16转10:
用相反的道理,将十位数乘以16加上个位数。如5A,将5乘以16得80,加上A的10进制10,结果是90。
最直接方便的方法是用windows或win95中的计算器,打开计算器,将计算器置成科学型(win95的乘法),选中十进制选择钮,输入十进制数然后选择二进制选择钮,OK!又快又准确。可是如果你想成为一个合格的程序员的话,你就必须充分了解十进制数和二进制数的特点,最好的方法是你多做一些进制转换的题目,这是程序员训练中的传统做法。
三、以十六进制作桥梁
十进制到二进制的转换实在麻烦,而且二进制数实在不易记忆和理解,你能马上感觉到一万元是多少钱,但是你能感觉到10011100010000(二进制)是多少吗?为了编程和使用方便,在二进制和十进制之间有了一座桥梁十六进制。十六进制是逢十六进一,0、1、2、3、4、5、…9、A、B、C、D、E、F、10、11、12……。到了9以后用ABCDEF表示,十六进制数与二进制数的转换非常方便。
首先你应当牢记下表
二进制 十六进制
0 0
1 1
10 2
11 3
100 4
101 5
110 6
111 7
1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F
二进制数转换成十六进制数方法如下,以二进制数1101110为例:
将二进制数从右面开始以四位为一组分组,最左面不够四位的补0,按上表查得对应的十六进制数,组合起来以后就成了。
0110 1110的十六进制数是6E
十六进制转换成二进制方法如下,以十六进制数3E为例:
将十六进制的每一位转换成四位二进制数,不足四位的在左面补0,组合起来即可得到二进制数。
3E的二进制数是00111110,既是111110
当然你也可以用计算器得出结果。但也建议你熟练掌握。

Unicode简介

http://www.1cn.biz/java/index.php?q=node/79
关键词: 字库,unicode,big5

Unicode是一种字符编码规范 。

先从ASCII说起。ASCII是用来表示英文字符的一种编码规范,每个ASCII字符占用1个字节(8bits)

因此,ASCII编码可以表示的最大字符数是256,其实英文字符并没有那么多,一般只用前128个(最高位为0),其中包括了控制字符、数字、大小写字母和其他一些符号 。

而最高位为1的另128个字符被成为“扩展ASCII”,一般用来存放英文的制表符、部分音标字符等等的一些其他符号

这种字符编码规范显然用来处理英文没有什么问题 。(实际上也可以用来处理法文、德文等一些其他的西欧字符,但是不能和英文通用),但是面对中文、阿拉伯文之类复杂的文字,255个字符显然不够用

于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做“GB2312-80”,它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。

但是这个方法有问题,最大的问题就是,中文文字没有真正属于自己的编码,因为扩展ASCII码虽然没有真正的标准化,但是PC里的ASCII码还是有一个事实标准的(存放着英文制表符),所以很多软件利用这些符号来画表格。这样的软件用到中文系统中,这些表格符就会被误认作中文字,破坏版面。而且,统计中英文混合字符串中的字数,也是比较复杂的,我们必须判断一个ASCII码是否扩展,以及它的下一个ASCII是否扩展,然后才“猜”那可能是一个中文字 。

总之当时处理中文是很痛苦的。而更痛苦的是GB2312是国家标准,台湾当时有一个Big5编码标准,很多编码和GB是相同的,所以……,嘿嘿。

这时候,我们就知道,要真正解决中文问题,不能从扩展ASCII的角度入手,也不能仅靠中国一家来解决。而必须有一个全新的编码系统,这个系统要可以将中文、英文、法文、德文……等等所有的文字统一起来考虑,为每个文字都分配一个单独的编码,这样才不会有上面那种现象出现。

于是,Unicode诞生了。

Unicode有两套标准,一套叫UCS-2(Unicode-16),用2个字节为字符编码,另一套叫UCS-4(Unicode-32),用4个字节为字符编码。

以目前常用的UCS-2为例,它可以表示的字符数为2^16=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符 。

UTF-8的问题后面会提到 。

在Unicode里,所有的字符被一视同仁。汉字不再使用“两个扩展ASCII”,而是使用“1个Unicode”,注意,现在的汉字是“一个字符”了,于是,拆字、统计字数这些问题也就自然而然的解决了 。

但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII字符集之间的不兼容问题。

我们知道,ASCII字符是单个字节的,比如“A”的ASCII是65。而Unicode是双字节的,比如“A”的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了 。

另一个更加严重的问题是,C语言使用'/0'作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉 。

于是,比Unicode更伟大的东东诞生了,之所以说它更伟大是因为它让Unicode不再存在于纸上,而是真实的存在于我们大家的电脑中。那就是:UTF 。

UTF= UCS Transformation Format UCS转换格式

它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种:UTF-8和UTF-16 。

其中UTF-16和上面提到的Unicode本身的编码规范是一致的,这里不多说了。而UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容 。

UTF-8有点类似于Haffman编码,它将Unicode编码为00000000-0000007F的字符,用单个字节来表示;

00000080-000007FF的字符用两个字节表示

00000800-0000FFFF的字符用3字节表示

因为目前为止Unicode-16规范没有指定FFFF以上的字符,所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。

在UTF-8里,英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理类可以对UTF编码进行处理。

下面说说中文的问题。

由于历史的原因,在Unicode之前,一共存在过3套中文编码标准。

GB2312-80,是中国大陆使用的国家标准,其中一共编码了6763个常用简体汉字。Big5,是台湾使用的编码标准,编码了台湾使用的繁体汉字,大概有8千多个。HKSCS,是中国香港使用的编码标准,字体也是繁体,但跟Big5有所不同。

这3套编码标准都采用了两个扩展ASCII的方法,因此,几套编码互不兼容,而且编码区间也各有不同

因为其不兼容性,在同一个系统中同时显示GB和Big5基本上是不可能的。当时的南极星、RichWin等等软件,在自动识别中文编码、自动显示正确编码方面都做了很多努力 。

他们用了怎样的技术我就不得而知了,我知道好像南极星曾经以同屏显示繁简中文为卖点。

后来,由于各方面的原因,国际上又制定了针对中文的统一字符集GBK和GB18030,其中GBK已经在Windows、Linux等多种操作系统中被实现。

GBK兼容GB2312,并增加了大量不常用汉字,还加入了几乎所有的Big5中的繁体汉字。但是GBK中的繁体汉字和Big5中的几乎不兼容。

GB18030相当于是GBK的超集,比GBK包含的字符更多。据我所知目前还没有操作系统直接支持GB18030。

谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:

问题一:
使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?

我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?

问题二:
最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。
查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。

0、big endian和little endian
big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。

“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

1、字符编码、内码,顺带介绍汉字编码
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。

GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。

从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。

这里还有一些细节:

GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。

在DBCS中,GB内码的存储格式始终是big endian,即高位在前。

GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。

2、Unicode、UCS和UTF
前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。

Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。

根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。

在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。

目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。

UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。

IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。

3、UCS-2、UCS-4、BMP

UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:

UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

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 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

读者可以用记事本测试一下我们的编码是否正确。

UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。

5、UTF的字节序和BOM
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是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 WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。

6、进一步的参考资料
本文主要参考的资料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

我还找了两篇看上去不错的资料,不过因为我开始的疑问都找到了答案,所以就没有看:

"Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
"Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)

20060427-汉字区位码查询与算法——microsoft visual studio 2005系列相关推荐

  1. 汉字区位码查询与算法——microsoft visual studio 2005系列

    要从事学术研究,一定要学好数学,数学可以把对事物的描述精确化. tuenhai为什么要学习编程?其中一个原因就是利用编程工具进行一些数学运算. 记得大约10年前,那时tuenhai还没有电脑,要进行大 ...

  2. Microsoft Visual Studio 2005中使用水晶报表

    Microsoft Visual Studio 2005中使用水晶报表 沈阳 王智 OICQ:16994162 http://wangzhihome.51.net/ 2006-4-11 如有转贴请注明 ...

  3. Microsoft Visual Studio 2005 怎么更改安装路径?

    Microsoft Visual Studio 2005 怎么更改安装路径? 要更改安装位置,必须卸载 Microsoft Visual Studio 2005 Premier Partner Edi ...

  4. 关于 Microsoft Visual Studio 2005 无法调试应用程序的解决方法

    关于 Microsoft Visual Studio 2005 无法调试应用程序的解决方法 (downmoon) 在VS 2005 中编写Windows的应用程序时,提示:试图运行项目时出错:无法启动 ...

  5. Microsoft Visual Studio 2005 Beta 2 下载地址

    http://lab.msdn.microsoft.com/vs2005/ 转载于:https://www.cnblogs.com/gwazy/archive/2005/04/25/144631.ht ...

  6. Microsoft Visual Studio 2005 简体中文专业版(DVD)下载地址

    下载地址一: http://www.05sun.com/ViewDownloadUrl.asp?ID=436 下载地址二: http://www.sooweb.net/Soft/System-Util ...

  7. Microsoft Visual Studio 2005 多线程时 解决不是该线程创建的来访问

    在Program.cs 加上 System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false; 转载于:https://www.cn ...

  8. 学习笔记转汉字区位码查询与算法

    汉字区位码查询与算法 2007-10-27 09:44 7680人阅读 评论(0) 收藏 举报 算法stringbytecharacterencodinginteger 目录(?)[+] 汉字区位码查 ...

  9. 未解决:错误的结果 2 (从“D:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe”返回)。...

    今天在编译一个VC2005的应用程序时提示该错误.在网上搜了一下这个文件,原来是一个C/C++优化编译器小工具. 我在生成正好在项目属性里面设置了优化速度功能,发现了问题所在. 于是我打开cmd,直接 ...

最新文章

  1. 听说做前后端的都是这个体会? | 每日趣闻
  2. 如何用Markdown轻松排版知乎专栏文章?
  3. beam search算法
  4. Vs Code 配置C/C++ 开发环境
  5. 如何通向“广义人工智能”?LSTM 提出者之一Sepp Hochreiter:将符号 AI 与神经 AI 相结合...
  6. asp exce l连接字符串_C++基础知识篇:C++ 字符串
  7. 马超计算机博士,湖南大学设计院马超民等博士生团队发明“手势”控制汽车
  8. 设备名称和设备责任人输出写反了,重新写了,重新发送邮箱
  9. java getoutputstream_Java Connection.getOutputStream方法代码示例
  10. 阿里云服务器新手选型指南
  11. win10+64位 安装Theano并实现GPU加速
  12. ubuntu启动时的初始化信息二
  13. jade linux 安装教程,ROS-Jade版在UbuntuKylin15.04上的安装
  14. qt中的句柄类,实体类
  15. 嵌入式Linux开发细分四个岗位
  16. 大疆2019届秋招笔试--测试工程师
  17. 今天分享给你几个绘制Excel表格的技巧
  18. Faraday:微博广告分层实验平台架构
  19. 网络创业者莱恩-福克斯:最后一分钟的奇迹
  20. Certificate Transparency

热门文章

  1. 搭建注册中心Eureka运行时报错:[ main] o.s.b.d.LoggingFailureAnalysisReporter :
  2. BERT-MRC论文笔记
  3. Docker系列(1-简介篇) -- 为什么要使用docker?
  4. DNA计算机及DNA存储
  5. 国网对计算机二级科目要求,今起!计算机等级考试可以网报,二级部分科目获证条件调整...
  6. dll转换成.a /dll转换lib
  7. Android Q 适配指南 让你少走一堆弯路
  8. 电脑字体突然变细了:macOS Mojave 在非Retina屏幕下字体太细了怎么办
  9. 线性异质双官能PEG试剂荧光素-聚乙二醇-巯基FITC-PEG-SH
  10. 全面深改直面民生“硬骨头” 这些领域获得感满满