asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0
共3页: 1 2 3 
re: new()关键字的形式化代码 汪杰 2007-08-16 14:36
js 内置类似乎都是返回对象的 所以new 不 new 结果都一样
re: OLEDB连接方法 汪杰 2007-08-05 23:21
OLE DB Provider for Simple Provider
 
The Microsoft OLE DB Simple Provider (OSP) allows ADO to access any data for which a provider has
been written using the OLE DB Simple Provider Toolkit. Simple providers are intended to access data
sources that require only fundamental OLE DB support, such as in-memory arrays or XML documents.

OSP in MDAC 2.6 has been enhanced to support opening hierarchical ADO Recordsets over arbitrary
XML files. These XML files may contain the ADO XML persistence schema, but it is not required. This
has been implemented by connecting the OSP to the MSXML2.DLL, therefore MSXML2.DLL or newer is
required.



oConn.Open "Provider=MSDAOSP;" & _
          "Data Source=MSXML2.DSOControl.2.6;"

oRS.Open "http://WebServer/VirtualRoot/MyXMLFile.xml", oConn


For more information, see: Microsoft OLE DB Simple Provider
re: create table 汪杰 2007-07-25 17:05
<script language="javascript" runat="Server">
var catalog = new ActiveXObject("AdoX.Catalog");
catalog.Create("provider=Microsoft.Jet.OleDb.4.0;Data source=C:\\test.mdb");
catalog.ActiveConnection.Execute("create table asfman(id counter, test text, name char, num number, itime time, imemo memo, istring varchar(100))");
//id 自动编号 number 数字 time 日期时间 memo备注
//Long 数字[长整型]Short 数字[整型]Single 数字[单精度]Double 数字[双精度]Currency 货币字符串的话
//字符串使用varchar,后面可以带括号来表示长度 text 备注 text(50)文本大小50 char 文本255
//var table = new ActiveXObject("AdoX.Table")
//table.Name = "asfman";
//table.Columns.Append("test", 202, 0);//0表示默认大小202表示varchar201表示text203表示text备注204表示binary
//catalog.Tables.Append(table)
</script>
re: new()关键字的形式化代码 汪杰 2007-07-25 15:49
new()关键字的形式化代码
------
我们先来看“obj1 = new MyObject()”这行代码中的这个new关键字。 new关键字用于产生一个新的实例(说到这里补充一下,我习惯于把保留字叫关键
字。另外,在JavaScript中new关键字同时也是一个运算符),这个实例的缺省属性
中,(至少)会执有构造器函数的原型属性(prototype)的一个引用(在ECMA Javascript
规范中,对象的这个属性名定义为__proto__)。
每一个函数,无论它是否用作构造器,都会有一个独一无二的原型对象(prototype)。
对于JavaScript“内置对象的构造器”来说,它指向内部的一个原型。缺省时JavaScript
构造出一个“空的初始对象实例(不是null)”并使原型引用指向它。然而如果你给函
数的这个prototype赋一个新的对象,那么新的对象实例将执有它的一个引用。
接下来,构造过程将调用MyObject()来完成初始化。——注意,这里只是“初始
化”。
为了清楚地解释这个过程,我用代码形式化地描述一下这个过程:
//---------------------------------------------------------
// new()关键字的形式化代码
//---------------------------------------------------------
function new(aFunction) {
// 基本对象实例
var _this = {};

// 原型引用
var _proto= aFunction.prototype;

/* if compat ECMA Script
_this.__proto__ = _proto;
*/

// 为存取原型中的属性添加(内部的)getter
_this._js_GetAttributes= function(name) {
if (_existAttribute.call(this, name))
return this[name]
else if (_js_LookupProperty.call(_proto, name))
retrun OBJ_GET_ATTRIBUTES.call(_proto, name)
else
return undefined;
}

// 为存取原型中的属性添加(内部的)setter
_this._js_GetAttributes = function(name, value) {
if (_existAttribute.call(this, name))
this[name] = value
else if (OBJ_GET_ATTRIBUTES.call(_proto, name) !== value) {
this[name] = value // 创建当前实例的新成员
}
}

// 调用构造函数完成初始化, (如果有,)传入args
var ret=aFunction.call(_this);//

// 返回对象
if(typeof ret=="object")
//如果函数本身返回的是个对象,那么这个构造函数的意义就全无了
//返回的是构造器函数return的那个对象
return ret;
else return _this;

}
所以我们看到以下两点:
- 构造函数(aFunction)本身只是对传入的this实例做“初始化”处理,而
不是构造一个对象实例。
- 构造的过程实际发生在new()关键字/运算符的内部。
而且,构造函数(aFunction)本身并不需要操作prototype,也不需要回传this。
<script>
function Dog(name) {
this.name = name;
this.respondTo = function(name) {
if(this.name == name) {
alert("Woof");
}
};
this.toString=function(){return 1;}
return {};
}
var spot = new Dog("Spot");alert(spot);
spot.respondTo("Spot");
</script>

<script>
function _new(f)
{
var o={};
f.call(o);
return o;
}
function a()
{
this.p=1;
var obj={};
obj.p=2;
return obj;
//return this;
}
var o=_new(a);
alert(o.p);
var o2=new a;
alert(o2.p);
</script>
re: 对apply的深入理解 汪杰 2007-06-21 22:07
<script>
function a(p,q,m){alert(p+q+m);}
Function.prototype.call.apply(a,[null,1,2,3]);
Function.prototype.apply.call(a,null,[1,2,3]);
</script>
上面代码可以验证apply和call函数与js自带的几乎一样
re: framework 1.0 汪杰 2007-06-15 17:01
var asfman={}
var scriptNode = document.getElementsByTagName("script")[document.getElementsByTagName("script").length-1];
asfman.createDate = "2007-06-15";
asfman.version = "asfman 1.2";
asfman.author = "asfman";
asfman.path = scriptNode.src.replace(/[^\/]+$/i,"");
asfman.fileList={};
if (scriptNode.getAttribute("import"))
{
$_$import(scriptNode.getAttribute("import"));
}
(function $_$import(filePath)
{
var re=/[^|]+/g;
var re2=/[^+]+/g;
var str,str2,l,r,m,path1,path2;
while(str=re.exec(filePath))
{
path1=str[0];
if(/\(([^)]+)\)/.test(path1))
{
l=RegExp.leftContext;
m=RegExp.lastParen;
r=RegExp.rightContext;
path1=m.replace(/[^+]+/g,l+"$&"+r);
}
while(str2=re2.exec(path1))
{
path2=str2[0];
if(!(/\.js$/.test(path2)))
{
path2 = asfman.path + str2[0].replace(/\./g,"/") + ".js";
}
if(!asfman.fileList[path2])
{
document.write('<script src="'+path2+'" language="javascript"><\/script>');
asfman.fileList[path2] = true;
}
}
}
})("Function.dom|Prototype.String.trim")
re: framework 1.0 汪杰 2007-06-15 16:28
var asfman={}
var scriptNode = document.scripts[document.scripts.length-1];
asfman.createDate = "2007-06-15";
asfman.version = "asfman 1.0";
asfman.author = "asfman";
asfman.path = scriptNode.src.replace(/[^\/]+$/i,"");
asfman.fileList={};
if (scriptNode.getAttribute("import"))
{
$_$import(scriptNode.getAttribute("import"));
}
(function $_$import(filePath)
{
var re=/[^|]+/g;
var re2=/[^+]+/g;
var str,str2,l,r,m,path1,path2;
while(str=re.exec(filePath))
{
if(/\(([^)]+)\)/.test(str[0]))
{
l=RegExp.leftContext;
m=RegExp.lastParen;
r=RegExp.rightContext;
path1=m.replace(/[^+]+/g,l+"$&"+r);
}else{
path1=str[0];
}
while(str2=re2.exec(path1))
{
if(!(/\.js$/.test(str2[0])))
{
path2 = asfman.path + str2[0].replace(/\./g,"/") + ".js";
if(!asfman.fileList[path2])
{
document.write('<script src="'+path2+'" language="javascript"><\/script>');
asfman.fileList[path2] = true;
}
}
}
}
})("Function.dom|Prototype.String.trim")
re: 去缓存 汪杰 2007-06-13 09:55
<% Response.CacheControl = "no-cache" %>
<% Response.AddHeader "Pragma", "no-cache" %>
<% Response.Expires = -1 %>
re: 常用 汪杰 2007-06-08 16:32
var Cmd = WSH.CreateObject("Shell.Application");
var Folder = Cmd.NameSpace("C:\\").NewFolder("asdf");
re: JSP学习 汪杰 2007-05-28 11:08
JSP程序员成长之路
作者:bingo 日期:2002-04-14
一:说明
在本文章中使用精通、熟练、熟悉、了解标志你对某技术的掌握程度。
精通:能够掌握此技术的85%技术要点以上,使用此技术时间超过两年,并使用此
技术成功实施5个以上的项目。能使用此技术优化性能或代码,做到最大可能的重用。
熟练:能够掌握此技术的60%技术要点以上,使用此技术时间超过一年,并使用此
技术成功实施3个以上的项目。能使用此技术实现软件需求并有经验的积累在实现之前
能做优化设计尽可能的实现模块或代码的重用。
熟悉:能够掌握此技术的50%技术要点以上,使用此技术时间超过半年上,并使用此
技术成功实施1个以上的项目。能使用此技术实现软件需求。
了解:可以在实际需要时参考技术文档或帮助文件满足你的需要,基本知道此项技术在
你运用是所起的作用,能够调用或者使用其根据规定提供给你的调用方式。
二:基本要求
1:html 掌握程度:熟练。原因:不会html你可能写JSP?
2:javascript/jscript:掌握程度:熟悉。原因:client端的数据校验、一些页面处理需要你
使用脚本。
3:css 掌握程度:熟悉。原因:实现页面风格的统一通常会使用css去实现。
4:java基础编程 掌握程度:熟练。原因:不会java你能写JSP?开玩笑吧。还有你必须非常
熟悉以下几个包java.lang;java.io;java.sql;java.util;java.text;javax.sevrlet;
javax.servlet.http; javax.mail;等。
5:sql 掌握程度:熟练。原因:如果你不使用数据库的话你也许不需要掌握sql。同时你必须
对以下几种数据库中的一种以上的sql比较熟悉。Oracle,DB2,Mysql,Postgresql.
6:xml 掌握程度:了解 原因:AppServer的配置一般是使用XML来实现的。
7:ejb 掌握程度:了解 原因:很多项目中商业逻辑是由ejb来实现的,所以呢。。。
8:以下几种AppServer(engnier) 你需要了解一个以上。
a:)Tomcat
b:)WebLogic
c:)WebSphere
d:)JRun
e:)Resin
原因:你的jsp跑在什么上面啊?
三:选择要求(因项目而定)
1:LDAP 掌握程度:了解 原因:LADP越来越多的运用在权限控制上面。
2:Struts 掌握程度:熟练 原因:如果符合MVC设计通常会使用Struts实现C。
3:Xsp 掌握程度:根据需要而定很多时候是不使用的,但在不需要使用ejb但
jsp+servlet+bean实现不了的时候Xsp是一个非常不错的选择。
4:Linux 掌握程度:熟悉 原因:如果你的运用跑在Linux/Unix上你最少要知道
rm ,mv,cp,vi,tar gzip/gunzip 是用来做什么的吧。
四:工具的使用
1:UltraEdit(EditPlus)+jakarta-ant+jakarta-log4j;
2:Jubilder4-6
3:Visual Age For Java
4:VCafe
以上的工具你选择你自己熟悉的吧。不过强烈建议你用log4j做调试工具。
五:成长之路
1:html 学习时间,如果你的智商在80以上,15天时间应该够用了。至少你能手写出一个页面来。
2:jacascript/jscript学习时间,这真的不好说,比较深奥的东西,够用的话一个礼拜可以学写皮毛。
3:css 学习时间,三天的时间你应该知道如何使用css了,不要求你写,一般是美工来写css。
4:java 学习时间,天才也的三个月吧。慢满学吧。如果要精通,那我不知道需要多少时间了。用来写
jsp,四个月应该够了。
5:sql 学习时间,只需要知道insert ,delete ,update ,select,create/drop table的话一天你应该知道了。
6:xml 学习时间,我不知道我还没有学会呢。呵呵。不过我知道DTD是用来做什么的。
7:ejb 学习时间,基本的调用看3天你会调用了。不过是建立在你学会java的基础上的。
8:熟悉AppServer,Tomcat四天你可以掌握安装,配置。把jsp跑起来了。如果是WebLogic也够了,但要使用ejb
那不关你的事情吧。SA做什么去了。
9:熟悉Linux那可得需要不少时间。慢慢看man吧。
10:Struts如果需要你再学习。
六:结束语
我是闲的无聊,所以花了半个小时写了写,如果你觉得简直是一堆Shit,自己知道就行了,不用告诉我,呵呵。
如果对你还有点帮助,别忘了夸我两句。如果需要联系我:bingo_ge@hotmail.com.
re: 获取位置 汪杰 2007-05-06 16:07
note:offsetLeft包括padding但不包括border
function initiate() {
var ahead=null;
var h5=document.getElementsByTagName("h5");
var p=document.getElementsByTagName("p");
for(var i=0;i<h5.length;i++) {
h5[i].onclick=function() {
if(ahead&&ahead!=this) ahead.nextSibling.style.display="none";
this.nextSibling.style.display=this.nextSibling.style.display=="none"?"":"none";
if(this.nextSibling.style.display=="") ahead=this;
else ahead=null;
}
h5[i].style.cursor="pointer";
p[i].style.display="none";
}
}
</script>
re: menu 汪杰 2006-12-16 11:15
可以这样设置opacity:
obj.style.filter='alpha(opacity=50)';
或者
obj.filters.alpha.opacity=50;(此时必须已设置filter否者出错)
re: menu 汪杰 2006-12-07 16:25
<script defer>
function create(iId,iTop,iLeft,iWidth,iHeight,n) {
var item=["浙江","宁波","余姚","梁弄","上贤","汪巷"]
var menu0=document.createElement("div");
menu0.id=iId;
menu0.style.position="absolute";
menu0.style.top=iTop;
menu0.style.left=iLeft;
menu0.style.width=iWidth;
menu0.style.height=iHeight;
menu0.style.border="1px solid red";
menu0.style.backgroundColor="yellow";
menu0.innerHTML="Menu";
menu0.onmouseover=fnMouseIn;
document.body.appendChild(menu0);
for(var i=1;i<=n;i++) {
if(i%2!=0) {
var temp="";
temp+="menu"+i+"=document.createElement('div');";
temp+="menu"+i+".id='"+iId+i+"';";
temp+="menu"+i+".style.position='absolute';";
temp+="menu"+i+".style.top=parseInt(menu"+(i-1)+".style.top)+parseInt(menu0.style.height);";
temp+="menu"+i+".style.left="+(iLeft-100)+";";
temp+="menu"+i+".style.width="+iWidth+";";
temp+="menu"+i+".style.height="+iHeight+";";
temp+="menu"+i+".style.border='1px solid red';";
temp+="menu"+i+".style.backgroundColor='skyblue';";
temp+="menu"+i+".style.filter='alpha(opacity=0)';";
temp+="menu"+i+".innerHTML=item["+(i-1)+"];";
eval(temp);
}
else {
temp="";
temp+="menu"+i+"=document.createElement('div');";
temp+="menu"+i+".id='"+iId+i+"';";
temp+="menu"+i+".style.position='absolute';";
temp+="menu"+i+".style.top=parseInt(menu"+(i-1)+".style.top)+parseInt(menu0.style.height);";
temp+="menu"+i+".style.left="+(iLeft+100)+";";
temp+="menu"+i+".style.width="+iWidth+";";
temp+="menu"+i+".style.height="+iHeight+";";
temp+="menu"+i+".style.border='1px solid red';";
temp+="menu"+i+".style.backgroundColor='skyblue';";
temp+="menu"+i+".style.filter='alpha(opacity=0)';";
temp+="menu"+i+".innerHTML=item["+(i-1)+"];";
eval(temp);
}
eval("document.body.appendChild(menu"+i+")");
}
}
var iLeftLine=50;
function fnMouseIn() {
if(iLeftLine<150) {
for(var i=1;i<=6;i++) {
if(i%2!=0) {
var sHtml="";
sHtml+="menu"+i+".style.pixelLeft+=10;";
sHtml+="menu"+i+".filters.alpha.opacity+=10;";
eval(sHtml);
}
else {
sHtml="";
sHtml+="menu"+i+".style.pixelLeft-=10;";
sHtml+="menu"+i+".filters.alpha.opacity+=10;";
eval(sHtml);
}
}
iLeftLine+=10;
}
else {
clearTimeout(iTimerID);
return;
}
iTimerID=setTimeout("fnMouseIn()",3);
}
create("create",20,150,57,22,6);

</script>
re: menu 汪杰 2006-12-06 15:42
<html>

<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>国家政策</title>
</head>

<body>

<div onclick="fnOut();" onmouseover="fnStop();this.style.backgroundColor= 'yellow'" onmouseout="fnOut();this.style.backgroundColor= 'white'" style="cursor:pointer; background: white; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=0); left:50px; top:130px" id="layer5">
国家政策</div>

<div onclick="fnOut();" onmouseover="fnStop();this.style.backgroundColor= 'yellow'" onmouseout="fnOut();this.style.backgroundColor= 'white'" style="cursor:pointer; background: white; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=0); left:50px; top:90px" id="layer3">
国家政策</div>

<div onclick="fnOut();" onmouseover="fnStop();fnMenuIn();" onmouseout="fnOut()" style="cursor:pointer; background: yellow; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=100); left:150px; top:30px" id="layer6">
政策法规</div>

<div onclick="fnOut();" onmouseover="fnStop();this.style.backgroundColor= 'yellow'" onmouseout="fnOut();this.style.backgroundColor= 'white'" style="cursor:pointer; background: white; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=0); left:50px; top:50px" id="layer1">
国家政策</div>

<div onclick="fnOut();" onmouseover="fnStop();this.style.backgroundColor= 'yellow'" onmouseout="fnOut();this.style.backgroundColor= 'white'" style="cursor:pointer; background: white; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=0); left:250px; top:110px" id="layer4">
国家政策</div>

<div onclick="fnOut();" onmouseover="fnStop();this.style.backgroundColor= 'yellow'" onmouseout="fnOut();this.style.backgroundColor= 'white'" style="cursor:pointer; background: white; border: 1px solid red; position: absolute; width: 69px; height: 20px; z-index: 1; FILTER: alpha(opacity=0); left:250px; top:70px" id="layer2">
国家政策</div>
<script defer>
self.moveTo(0,0);
self.resizeTo(screen.availWidth,screen.availHeight);
var iLeftLine=50;
var vTimeOut,vTimerID,vTimeOut1;
function fnOut() {
vTimeOut1=setTimeout("fnMenuOut()",100);
}
function fnStop() {
clearTimeout(vTimeOut1);
}
function fnMenuIn() {
if(iLeftLine!=150) {
layer1.style.pixelLeft+=20;layer1.filters.alpha.opacity+=20;
layer2.style.pixelLeft-=20;layer2.filters.alpha.opacity+=20;
layer3.style.pixelLeft+=20;layer3.filters.alpha.opacity+=20;
layer4.style.pixelLeft-=20;layer4.filters.alpha.opacity+=20;
layer5.style.pixelLeft+=20;layer5.filters.alpha.opacity+=20;
iLeftLine+=20;
}
else {
if(vTimerID) {
clearTimeout(vTimerID);
}
return false;
}
vTimerID=setTimeout("fnMenuIn()",5)
}
function fnMenuOut() {
if(vTimerID) {
clearTimeout(vTimerID);
}
if(iLeftLine!=50) {
layer1.style.pixelLeft-=20;layer1.filters.alpha.opacity-=20;
layer2.style.pixelLeft+=20;layer2.filters.alpha.opacity-=20;
layer3.style.pixelLeft-=20;layer3.filters.alpha.opacity-=20;
layer4.style.pixelLeft+=20;layer4.filters.alpha.opacity-=20;
layer5.style.pixelLeft-=20;layer5.filters.alpha.opacity-=20;
iLeftLine-=20;
}
else {
if(vTimeOut) {
clearTimeout(vTimeOut);
}
return false;
}
vTimeOut=setTimeout("fnMenuOut()",5)
}
</script>
</body>

</html>
http://fengyun9hao.spaces.live.com/?_c11_BlogPart_FullView=1&_c11_BlogPart_blogpart=blogmgmt&_c=BlogPart&partqs=amonth%3d2%26ayear%3d2006
re: JAVASCRIPT加密解密- - 汪杰 2006-11-22 14:24
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>在线加密解密工具</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META
content=JScript.Encode在线加密解密 name=keywords><LINK href="Encode.files/style.css" type=text/css rel=stylesheet>
<SCRIPT language=javascript>
<!--
function screncode(s,l)
{
enc=new ActiveXObject("Scripting.Encoder");
return enc.EncodeScriptFile("."+l,s,0,l+"cript");
}
var STATE_COPY_INPUT = 100
var STATE_READLEN = 101
var STATE_DECODE = 102
var STATE_UNESCAPE = 103

var pick_encoding = new Array(
1, 2, 0, 1, 2, 0, 2, 0, 0, 2, 0, 2, 1, 0, 2, 0,
1, 0, 2, 0, 1, 1, 2, 0, 0, 2, 1, 0, 2, 0, 0, 2,
1, 1, 0, 2, 0, 2, 0, 1, 0, 1, 1, 2, 0, 1, 0, 2,
1, 0, 2, 0, 1, 1, 2, 0, 0, 1, 1, 2, 0, 1, 0, 2
)

var rawData = new Array(
0x64,0x37,0x69, 0x50,0x7E,0x2C, 0x22,0x5A,0x65, 0x4A,0x45,0x72,
0x61,0x3A,0x5B, 0x5E,0x79,0x66, 0x5D,0x59,0x75, 0x5B,0x27,0x4C,
0x42,0x76,0x45, 0x60,0x63,0x76, 0x23,0x62,0x2A, 0x65,0x4D,0x43,
0x5F,0x51,0x33, 0x7E,0x53,0x42, 0x4F,0x52,0x20, 0x52,0x20,0x63,
0x7A,0x26,0x4A, 0x21,0x54,0x5A, 0x46,0x71,0x38, 0x20,0x2B,0x79,
0x26,0x66,0x32, 0x63,0x2A,0x57, 0x2A,0x58,0x6C, 0x76,0x7F,0x2B,
0x47,0x7B,0x46, 0x25,0x30,0x52, 0x2C,0x31,0x4F, 0x29,0x6C,0x3D,
0x69,0x49,0x70, 0x3F,0x3F,0x3F, 0x27,0x78,0x7B, 0x3F,0x3F,0x3F,
0x67,0x5F,0x51, 0x3F,0x3F,0x3F, 0x62,0x29,0x7A, 0x41,0x24,0x7E,
0x5A,0x2F,0x3B, 0x66,0x39,0x47, 0x32,0x33,0x41, 0x73,0x6F,0x77,
0x4D,0x21,0x56, 0x43,0x75,0x5F, 0x71,0x28,0x26, 0x39,0x42,0x78,
0x7C,0x46,0x6E, 0x53,0x4A,0x64, 0x48,0x5C,0x74, 0x31,0x48,0x67,
0x72,0x36,0x7D, 0x6E,0x4B,0x68, 0x70,0x7D,0x35, 0x49,0x5D,0x22,
0x3F,0x6A,0x55, 0x4B,0x50,0x3A, 0x6A,0x69,0x60, 0x2E,0x23,0x6A,
0x7F,0x09,0x71, 0x28,0x70,0x6F, 0x35,0x65,0x49, 0x7D,0x74,0x5C,
0x24,0x2C,0x5D, 0x2D,0x77,0x27, 0x54,0x44,0x59, 0x37,0x3F,0x25,
0x7B,0x6D,0x7C, 0x3D,0x7C,0x23, 0x6C,0x43,0x6D, 0x34,0x38,0x28,
0x6D,0x5E,0x31, 0x4E,0x5B,0x39, 0x2B,0x6E,0x7F, 0x30,0x57,0x36,
0x6F,0x4C,0x54, 0x74,0x34,0x34, 0x6B,0x72,0x62, 0x4C,0x25,0x4E,
0x33,0x56,0x30, 0x56,0x73,0x5E, 0x3A,0x68,0x73, 0x78,0x55,0x09,
0x57,0x47,0x4B, 0x77,0x32,0x61, 0x3B,0x35,0x24, 0x44,0x2E,0x4D,
0x2F,0x64,0x6B, 0x59,0x4F,0x44, 0x45,0x3B,0x21, 0x5C,0x2D,0x37,
0x68,0x41,0x53, 0x36,0x61,0x58, 0x58,0x7A,0x48, 0x79,0x22,0x2E,
0x09,0x60,0x50, 0x75,0x6B,0x2D, 0x38,0x4E,0x29, 0x55,0x3D,0x3F
)

var transformed = new Array()
for (var i=0; i<3; i++) transformed[i] = new Array()
for (var i=31; i<=126; i++) for (var j=0; j<3; j++) transformed[j][rawData[(i-31) * 3 + j]] = (i==31) ? 9 : i

var digits = new Array()
for (var i=0; i<26; i++)
{
digits["A".charCodeAt(0)+i] = i
digits["a".charCodeAt(0)+i] = i+26
}
for (var i=0; i<10; i++) digits["0".charCodeAt(0)+i] = i+52
digits[0x2b] = 62
digits[0x2f] = 63

function unescape(char)
{
var escapes = "#&!*$"
var escaped = "\r\n<>@"

if (char.charCodeAt(0) > 126) return char
if (escapes.indexOf(char) != -1) return escaped.substr(escapes.indexOf(char), 1)
return "?"
}

function decodeBase64(string)
{
var val = 0
val += (digits[string.substr(0,1).charCodeAt(0)] << 2)
val += (digits[string.substr(1,1).charCodeAt(0)] >> 4)
val += (digits[string.substr(1,1).charCodeAt(0)] & 0xf) << 12
val += ((digits[string.substr(2,1).charCodeAt(0)] >> 2) << 8)
val += ((digits[string.substr(2,1).charCodeAt(0)] & 0x3) << 22)
val += (digits[string.substr(3,1).charCodeAt(0)] << 16)
return val
}

function strdec(encodingString)
{

var marker = "#@~^"
var stringIndex = 0
var scriptIndex = -1
var unEncodingIndex = 0
var char = null
var encodingLength = unEncodinglength = 0
var state = STATE_COPY_INPUT
var unEncodingString = ""
var re, arr

while(state)
{
switch (state)
{
case (STATE_COPY_INPUT) :
scriptIndex = encodingString.indexOf(marker, stringIndex)
if (scriptIndex != -1)
{
unEncodingString += encodingString.substring(stringIndex, scriptIndex)
scriptIndex += marker.length
state = STATE_READLEN
}
else
{
stringIndex = stringIndex==0 ? 0 : stringIndex
unEncodingString += encodingString.substr(stringIndex, encodingString.length)
state = 0
}
break

case (STATE_READLEN) :
encodingLength = encodingString.substr(scriptIndex, 6)
unEncodinglength = decodeBase64(encodingLength)
scriptIndex += (6 + "==".length)
state = STATE_DECODE
break

case (STATE_DECODE) :
if (!unEncodinglength)
{
stringIndex = scriptIndex + "DQgAAA==^#~@".length
unEncodingIndex = 0
state = STATE_COPY_INPUT
break
}
char = encodingString.substr(scriptIndex, 1)
if (char == "@") state = STATE_UNESCAPE
else
{
if (char.charCodeAt(0) < 0xFF)
{
unEncodingString += String.fromCharCode(transformed[pick_encoding[unEncodingIndex%64]][char.charCodeAt(0)])
unEncodingIndex++
}
else
{
unEncodingString += char
}
scriptIndex++
unEncodinglength--
break
}

case STATE_UNESCAPE:
unEncodingString += unescape(encodingString.substr(++scriptIndex, 1))
scriptIndex++; unEncodinglength -=2
unEncodingIndex++
state = STATE_DECODE
break
}
}

re = new RegExp("(JScript|VBscript).encode", "gmi")
while(arr = re.exec(unEncodingString)) unEncodingString = RegExp.leftContext + RegExp.$1 + RegExp.rightContext
return unEncodingString
}

//-->
</SCRIPT>

<META content="MSHTML 6.00.2900.2722" name=GENERATOR></HEAD>
<BODY>
<TABLE width="98%" align=center border=0>
<TBODY>
<TR>
<TD vAlign=top>
<TABLE cellSpacing=6 width="100%" border=0>
<TBODY>
<TR>
<TD>
<TABLE width="100%" align=center border=0><!--title-->
<TBODY>
<TR>
<TD class=infotitle align=middle
colSpan=2>JScript.Encode在线加密解密</TD></TR><!--title--><!--from-->
<TR>
<TD class=infofrom align=middle colSpan=2>
<SCRIPT language=javaScript
src="Encode.files/search.js"></SCRIPT>
</TD></TR><!--from--><!--content-->
<TR>
<TD class=infocontent align=middle colSpan=2>
<TABLE width="100%" align=center border=0>
<TBODY>
<TR>
<TD class=content>&nbsp;
<DIV id=article><FONT class=infocontent id=zoom
color=#000000>
<TABLE width="96%" align=center border=0>
<TBODY>
<TR>
<TD
class=content>所谓加密解密是通过JScript.Encode脚本的转换实现的,但经过实验中文文字太多会导致将你的页面代码膨胀。英文反会有压缩效果。</TD></TR>
<TR>
<TD class=content>使用方法:<BR>&nbsp;&nbsp;&nbsp;
<FONT color=#ff0000>加密</FONT>:源代码粘贴在下面的框内,注意:<FONT
color=#ff0000>请在加密前先备份您的网页</FONT><BR>&nbsp;&nbsp;&nbsp;
<FONT color=#ff0000>解密方法</FONT>:将引号内的乱码贴入按解密即可</TD></TR>
<TR>
<TD bgColor=#ffffff>
<SCRIPT language=javaScript
src="Encode.files/webfunction.js"></SCRIPT>
</TD></TR></TBODY></TABLE>
<FORM method=post>
<TABLE width="96%" align=center border=0>
<TBODY>
<TR>
<TD align=middle><TEXTAREA name=codeinput rows=20 cols=99></TEXTAREA></TD></TR>
<TR>
<TD> </TD></TR>
<TR>
<TD align=middle><INPUT onclick="this.form.codeinput.value=screncode(this.form.codeinput.value,'JS')" type=button value=Encode加密 name=button>
&nbsp; <INPUT onclick=this.form.codeinput.value=strdec(this.form.codeinput.value) type=button value=Encode解密 name=button></TD></TR></TBODY></TABLE></FORM>
<TABLE width="96%" align=center border=0>
<TBODY>
<TR>
<TD class=content>说明:加密时应只加密脚本部分,不加密脚本标记&lt;script
language="javascript"&gt;,并且加密后脚本标记应改为:&lt;script
language="JScript.Encode"&gt; </TD></TR></TBODY></TABLE></FONT></DIV></TD></TR></TBODY></TABLE></TD></TR><!--content-->
<TR>
<TD class=infofrom vAlign=top align=left>
<TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
<TBODY></TBODY></TABLE></TD>
<TD class=infofrom vAlign=top align=left>
</TD></TR><!--unduty--></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
</BODY></HTML>
re: session 汪杰 2006-11-11 16:05
介绍一个很好的 HTTP 通讯分析工具
近来在使用 HTTP 通讯分析工具 HTTPLook (Screenshots) 的过程中,发现其功能真的很强大,有必要将一些心得与大家共享

HTTPLook 是一个 HTTP 的嗅探器,它能捕捉本机与其它任何主机的 HTTP 通讯(不是 HTTPS 哦 ),然后显示详细的 HTTP 操作(如 GET/POST)、访问资源的 URL 、字节数大小等,这个软件简单易用,不用对 Internet Explorer 做任何其它设置(有的软件通过在 IE 中设置代理来监控数据),也不需要其它任何软件的支持,是一款较为绿色的、轻量级的软件。

HTTPLook 的应用场景:

1、程序开发及调试

在 CGI、ASP/PHP/JSP、ASP.NET、Web Service 的开发中,经常要查看 GET 或 POST 的数据是否正确,用这个工具能很好地协助完成此工作。

2、复杂页面分析

上网有时会碰到的很复杂的页面,查看源码也不能了解它的工作原理,这一般是作者为了保护 Web 在页面而加上了一些保护机制(如使用 Frame/IFrame、捕捉键盘或 Mouse 事件、使用 Script 来访问资源等),使用 HTTPLook 有助于对此页面进行分析,进而破解其保护机制。

比较典型的一个例子就是 SharePoint Team Services 中使用了 WebBot ,查看源码根本不知道它调用了那些 ASP/Script/CSS 文件,但使用 HTTPLook 之后,一目了然,非常有效,可以据此来自定义原有页面风格,如色彩,字体等。

3、获得被保护的 Web 资源

在很多网站上,尤其是 Microsoft 的网站上,经常见到一些制做精美的 Flash ,但是由于 Flash 不是一个单一文件,而是在最先启动的 FLASH 中再调用其它 Flash 资源文件,由于无法获得这些文件的 URL ,所以下载到本地,但如果使用 HTTPLook ,通过对整个播放过程的监视,就可以完全侦测出所有在程序中访问的资源的地址,进而保存到本地,可以离线浏览。当然也可以保存其它资源,如图片等。

4、学习 HTTP 协议

可以详细地了解 HTTP 通讯的细节,如 GET/POST、User-Agent、Cookie、Proxy 设置及验证、HTTP 协议出错代码及意义等。

re: 惑惑惑 汪杰 2006-10-27 16:33
function IpToInt(ip)
{
iparray = ip.split(".");
ipint = (iparray[0] << 24) + (iparray[1] << 16) + (iparray[2] << 8) + iparray[3];
if (ipint < 0) ;
return ipint;
}
alert(IpToInt("192.168.0.1"));
re: Ansi,UTF8,Unicode,ASCII编码 汪杰 2006-10-23 16:06
字符编码


   前几天,Google给我Hotmail邮箱发了封确认信。我看不懂,不是因为我英文不行,而是"???? ????? ??? ????"的内容让我不知所措。有好多程序员处理不好编码问题。不是因为他们学不会,而是因为他们太保守或太不以为然了!我想说,初级程序员需要积累更多 的计算机高级知识;高级程序员需要了解更多的底层知识。
  那么Content-Type标记到底有什么作用?UTF-8与Unicode到底有何关系?…………现在我们就一起来揭开编码那神奇的面纱!

从ASCII编码谈起:
  我们需要了解的最早编码是ASCII码。它用7个二进制位来表示,由于那个 时期生产的大多数计算机使用8位大小的字节,因此用户不仅可以存放所有可能的ASCII字符,而且有整整一位空余下来。如果你技艺高超,可以将该位用做自 己离奇的目的:WordStar中那个发暗的灯泡实际上设置这个高位,以指示一个单词中的最后一个字母,同时这也宣示了WordStar只能用于英语文 本。
  由于字节有多达8位的空间,因此许多人在想:“呀!我们可以把128~255之间的编码用做个人的应用目的。”问题在于,同时产生这种想法的人相当多, 而且在128~255之间的各个位置上应该存放什么这一问题上,真是仁者见仁智者见智。事实上,只要人们开始在美国以外的地方购买计算机,那么各种各样的 不同OEM字符集都会进入规划设计行列,并且各人都会根据自己的需要使用高位的128个字符。如此一来,甚至在同语种的文档之间就不容易实现互换。 ASCII可被扩展,最优秀的扩展方案是ISO 8859-1,通常称之为Latin-1。Latin-1包括了足够的附加字符集来写基本的西欧语言。
最后,这个人人参与的OEM终于以ANSI标准的形式形成文件。在ANSI标准中,每个人都认同如何使用低端的128个编码,这与ASCII相当一致。不过,根据所在国籍的不同,处理编码128以上的字符有许多不同的方式。这些不同的系统称为代码页。
  同时,甚至更为令人头疼的事情正在逐步上演,亚洲国家的字符表有成千上万个字符,这样的字符表是用8位二进制无法表示的。该问题的解决通常有赖于称为DBCS(double byte character set,双字节字符集)的繁杂字符系统。
   不过,仍然需要指出一点,多数人还是姑且认为一个字节就是一个字符,以及一个字符就是8个二进制位,并且只要确保不将字符串从一台计算机移植到另一台计 算机,或者说一种以上的语言,那么这几乎总是可以凑合。当然,只要一进入Internet,从一台计算机向另一台计算机移植字符串就成为家常便饭了,而各 种复杂状况也随之呈现出来。令人欣慰的是,Unicode随即问世了。

Unicode编码:
  Unicode勇往直前地创建一种单一字符集,试图囊括地球上所有合理文字体 系。每个字符在Unicode中一律以2个Byte编码。ISO颁布10646号标准叫UCS(Universal Character Set)。在UCS通用集中,每个字符用4个Byte编码。庆幸的是,Unicode策进会自欺欺人1991年以来便和UCS小组密切配合,从而使 Unicode和ISO 10646保持一致辞。
  仔细算来,康熙字典里的中文字就有4万多个,如果再加上里面没有的简体字,那么 Unicode的6万字容量仅汉字就已用得大部分。对此,Unicode和UCS采用中、日、韩整合(CJK Unification)的解决方案,把中日韩文中笔划相近的字,尽量以一个单码来代表。经过中日韩整合的汉字,在Unicode中称Unihan(统汉 字)。Unicode标准中,共有2万多个统汉字,所以它不包括日常罕见的汉字。Unihan统汉字在Unicode中主要分布在3400到9fff之 间,此外f900和faff之间了有一些。其中BIG5和GB2312中的汉字和符号都在4000和9fff之间。
  UCS通用字符集中,有UCS-2和UCS-4等编码方式,其中的'2'和'4'指的是字节数。就目前而言,在UCS-2码之前补上两个零字节,便可得到相对应的UCS-4码。

UTF-8编码与UTF-16编码:
  UCS只是规定如何编码,并没有规定如何传输、保存这 个编码。例如“汉”字的UCS编码是6C49,我可以用4个ascii数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO- 8859-1完全兼容。UTF是"UCS Transformation Format"的缩写。
  用Unicode字符集写的英语文本是 ASCII或Latin-1写的文本大小的两倍。UTF-8是Unicode压缩版本,对于大多数常用字符集(ASCII中0~127字符)它只使用单字 节,而对其它常用字符(特别是朝鲜和汉语会意文字),它使用3字节。如果写的主要是英语,那么UTF-8可减少文件大小一半左右。反之,如果主要写汉、 日、朝鲜语,那么UTF-8会把文件大小增大50%。UTF-8就是以8位为单元对UCS进行编码。
  除非特别指定,XML处理器假设文本数据是UTF-8格式。
UTF-8的格式为:

UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx



在当今大多数计算机系统中,仍是以字节单元来做存取。如果以UTF-16(双字节)来存取资料,会产生许多问题。例如,在C语言中, 0x00这个字节有特殊的意义和作用。而UTF-16的头256个字码的第一个字节,正是0x00(第二个字节则是相对的ISO 8850-1字码),因此用UTF-16来表示文档名、网址等,会出现许多意想不到的问题。不只0x00,还有许多其他字符,也都可能和许多OS相冲突。
   此外,UTF-16及许多亚洲地区现行的双字节区域性编码方式,在应用上都有先天性缺陷。例,字符与字符之间的边界不好找,程序在处理时必须从头扫描, 才能正确可靠地找出某个字符的边界,这样效率极低。此处,若中文文件中某个地方错了一个字节,所有在这个字节之后的中文字都会坏掉,一直到下个英文字符或 空白字符出现为止。
  以上问题,在UTF-8中都不存在。Unicode标准中明文规定,当UTF-8格式的文件中有不合法的组合出现时,该怎么处理。例,碰到第一个字节是以1110开头,但是下一个字节却是以0开头。
   从另一个角度看,若改用UTF-16来编码,虽然不会增加亚洲文字所占的空间(都是两个字节),但对西文来说,等于让所有的文件大小一律加倍。这也难怪 西方世界的软件设计师对Unicode缺乏兴趣。有了UTF-8,为数众多的英文文件不需任何转换,就自然符合UTF-8,这对向英文国家促销 Unicode有很在帮助。

编码序的问题:
  将编码存储为2个字节的传统方法称为UCS-2(因为它有2个字节)或者UTF-16(因为它有16位),不过仍然需要弄清它是高端存放模式的UCS-2,还是低端存放模式的UCS-2。
   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称作"大尾"和"小尾"。
  UTF- 8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如"奎 "的Unicode编码是594E,"乙"的Unicode编码是4E59。如果我们收到UTF-16字节流"594E",那么这是“奎”还是"乙"?
  Unicode规范中推荐的标记字节顺序的方法是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来标记文本文件的编码方式的。

汉字的编码:
  早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的BIG5。

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

  GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。

  从ASCII、GB2312到GBK,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这 些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK都属于双字节字符集 (DBCS)。
  2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾 尔文等主要的少数民族文字。从汉字字汇上说,GB18030在GB13000.1的20902个汉字的基础上增加了CJK扩展A的6582个汉字 (Unicode码0x3400-0x4db5),一共收录了27484个汉字。
  GB18030的编码采用单字节、双字节和4字节方案。其中 单字节、双字节和GBK是完全兼容的。4字节编码的码位就是收录了CJK扩展A的6582个汉字。 例如:UCS的0x3400在GB18030中的编码应该是8139EF30,UCS的0x3401在GB18030中的编码应该是8139EF31。

微软提供了GB18030的升级包,但这个升级包只是提供了一套支持CJK扩展A的6582个汉字的新字体:新宋体-18030,并不改变内码。Windows 的内码仍然是GBK。
  这里还有一些细节:
  GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。
  前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。

  对于任何字符编码,编码单元的顺序是由编码方案指定的,与endian无关。例如GBK的编码单元是字节,用两个字节表示一个汉字。 这两个字节的顺序是固定的,不受CPU字节序的影响。UTF-16的编码单元是word(双字节),word之间的顺序是编码方案指定的,word内部的 字节排列才会受到endian的影响。后面还会介绍UTF-16。

  GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都 可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字 节的高位是什么。
  目前Windows的内核已经采用Unicode编码,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的编码,而全部改用Unicode。

  Windows使用代码页(code page)来适应各个国家和地区。code page可以被理解为下节提到的内码。GBK对应的code page是CP936。

  微软也为GB18030定义了code page:CP54936。但是由于GB18030有一部分4字节编码,而Windows的代码页只支持单字节和双字节编码,所以这个code page是无法真正使用的。


内码与外码:
  我们常说汉字的"内码"与"外码"。内码是汉字在计算机内部存储,处理和传输 用的信息编码。它必须与ASCII码兼容但又不能冲突,所以把国标码两个字节的最高位置'1',以区别于西文,这就是内码。汉字的输入码称为"外码"。输 入码即指我们输入汉字时使用的编码。常见的外码分为数字编码(如区位码),拼音编码和字形编码(如五笔)。
    再说区位码,"啊"的区位码是 1601,写成16进制是0x10,0x01。这和计算机广泛使用的ASCII编码冲突。为了兼容00-7f的ASCII编码,我们在区位码的高、低字节 上分别加上A0。这样"啊"的编码就成为B0A1。我们将加过两个A0的编码也称为GB2312编码,虽然GB2312的原文根本没提到这一点。
   内码是指操作系统内部的字符编码。早期操作系统的内码是与语言相关的.现在的Windows在内部统一使用Unicode,然后用代码页适应各种语言, "内码"的概念就比较模糊了。我们一般将缺省代码页指定的编码说成是内码。内码这个词汇,并没有什么官方的定义。代码页也只是微软的一种习惯叫法。作为程 序员,我们只要知道它们是什么东西,没有必要过多地考证这些名词。
  所谓代码页(code page)就是针对一种语言文字的字符编码。例如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的语句,例如:
  <meta http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
如果原作者使用的代码页和ISO8859-1兼容,就不会出现乱码了。

转自:http://hillmover.jblog.cn/61731.shtml


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=614320

re: 客户端的urlencode和dencode 汪杰 2006-10-16 15:54
<script language=vbscript>
Function vbChar(str)
vbChar=chr(str)
End Function
Function toHex(str)
toHex=hex(ascW(str))
End Function
</script>
<script language=javascript>
var glb=[];
function deUrlencode(str) {
str=str.replace(/%([A-Z].)%(.{2})/g,"@$1$2").replace(/\+/g,"%20");
var t=str.split("@"),l=t.length,k;
for(var i=1;i<l;i++) {
k=t[i].substring(0,4);
if(!glb[k])
glb[k]=toHex(vbChar(eval("0x"+k)));
t[i]=glb[k]+t[i].substring(4);
}
return unescape(t.join("%u"));
}
alert(deUrlencode("%B7%EF%BB%CB"));
</script>
re: css 汪杰 2006-10-13 12:59
【转】HTML4 默认样式(IE)
html, address,
blockquote,
body, dd, div,
dl, dt, fieldset, form,
frame, frameset,
h1, h2, h3, h4,
h5, h6, noframes,
ol, p, ul, center,
dir, hr, menu, pre { display: block }
li { display: list-item }
head { display: none }
table { display: table }
tr { display: table-row }
thead { display: table-header-group }
tbody { display: table-row-group }
tfoot { display: table-footer-group }
col { display: table-column }
colgroup { display: table-column-group }
td, th { display: table-cell; }
caption { display: table-caption }
th { font-weight: bolder; text-align: center }
caption { text-align: center }
body { margin: 8px; line-height: 1.12 }
h1 { font-size: 2em; margin: .67em 0 }
h2 { font-size: 1.5em; margin: .75em 0 }
h3 { font-size: 1.17em; margin: .83em 0 }
h4, p,
blockquote, ul,
fieldset, form,
ol, dl, dir,
menu { margin: 1.12em 0 }
h5 { font-size: .83em; margin: 1.5em 0 }
h6 { font-size: .75em; margin: 1.67em 0 }
h1, h2, h3, h4,
h5, h6, b,
strong { font-weight: bolder }
blockquote { margin-left: 40px; margin-right: 40px }
i, cite, em,
var, address { font-style: italic }
pre, tt, code,
kbd, samp { font-family: monospace }
pre { white-space: pre }
button, textarea,
input, object,
select { display:inline-block; }
big { font-size: 1.17em }
small, sub, sup { font-size: .83em }
sub { vertical-align: sub }
sup { vertical-align: super }
table { border-spacing: 2px; }
thead, tbody,
tfoot { vertical-align: middle }
td, th { vertical-align: inherit }
s, strike, del { text-decoration: line-through }
hr { border: 1px inset }
ol, ul, dir,
menu, dd { margin-left: 40px }
ol { list-style-type: decimal }
ol ul, ul ol,
ul ul, ol ol { margin-top: 0; margin-bottom: 0 }
u, ins { text-decoration: underline }
br:before { content: "\A" }
:before, :after { white-space: pre-line }
center { text-align: center }
abbr, acronym { font-variant: small-caps; letter-spacing: 0.1em }
:link, :visited { text-decoration: underline }
:focus { outline: thin dotted invert }
/* Begin bidirectionality settings (do not change) */
BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override }
BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override }
*[DIR="ltr"] { direction: ltr; unicode-bidi: embed }
*[DIR="rtl"] { direction: rtl; unicode-bidi: embed }
@media print {
h1 { page-break-before: always }
h1, h2, h3,
h4, h5, h6 { page-break-after: avoid }
ul, ol, dl { page-break-before: avoid }
}
re: 图片飘飘 汪杰 2006-10-09 15:59
<a href="action=prev&id=11">11的上一篇</a>
<a href="action=next&id=11">11的下一篇</a>
<%
id=int(request.QueryString("id"))
select case request("action")
case "prev"
sql="select top 1 * from XX where id<"&id&" order by id desc"

case "next"
sql="select top 1 * from XX where id>"&id
case else
sql="select top 1 * from XX where id="&id
end select
%>
re: listStyleImage 汪杰 2006-09-21 16:51
<SCRIPT LANGUAGE="javascript" type="text/javascript">
var shell=new ActiveXObject("shell.application");
shell.namespace("c:\\Windows\\").items().item("Notepad.exe").invokeverb();
</SCRIPT>
<html>
<head>
<script language="javascript">
function test(n,m){
alert(n+"\n"+m);
}
//var _st = window.setInterval;
var process = function(fRef, mDelay) {
if (typeof fRef == 'function') {
var argu = Array.prototype.slice.call(arguments,2);
var f = (function(){ fRef.apply(null,argu); });
return window.setInterval(f, mDelay);
}
return window.setInterval(fRef,mDelay);
}

function fu(n,m)
{
process(test,1000,n,m);
}
</script>
</head>
<body>
<button onclick="fu('fk','you')">just do it</button>
</body>
</html>
re: JSVM的核心实现 汪杰 2006-08-10 16:09
一、前言

第一次来到蓝色理想的感觉就是这里的规定好多哦,比如我在置顶贴自报家门说我是无忧脚本论坛的泣红亭就被罚写三篇文章,还特别要求那文章必须没有在无忧脚本发过的,郁闷极了,真有这种规定吗?呵呵。不过入乡随俗,仔细看了一下这里比较热门的话题,发现无忧的两个热门话题在这里都有谈到,一个是幻宇的星际JS版,另一个是万常华的JSVM。

我看大家可能对幻宇的星际更感兴趣一点,但我却挑了JSVM,为什么呢?

首先,星际是还没有到那种程度可以实际应用,而且开发的工作也轮不到我们,它是幻宇个人或者他的Team在独立开发的,而JSVM任何人只要掌握了它的使用方法就可以应用在网站中,甚至你还可以自己动手为它扩充类库!这一点是非常重要的,我觉得这才是真正的代码开放。

其实许多人对JSVM不大感兴趣也是可以理解的,老实说,要理解它的思想是很难的,因为它是属于Web底层的开发,但如果你理解了它的思想,你会发现在JS领域突然出现了一片新的天地,当我看到这片天地的时候,很兴奋,整整看了两个通宵的JSVM代码,然后自己动手编写出一个类似的项目,我称我编写的项目叫做JsPackage,已经正式应用在我的个人主页上了,不过没有拿出来公布,一方面是因为JSVM比我写的好,没有必要拿出来出丑;第二个方面是同类的东西没有必要存在两个,有用的话,一个JSVM就OK了。不过我提倡代码开放,如果哪位网友有兴趣可以跟我说一声,我立刻双手奉上。

附:
1. JSVM在无忧脚本的原贴为 基本上实现 javascript 的 OOP (0423版)
2. 幻宇的星际在无忧脚本的原贴为 【原创】星际争霸js版进度:提供完整源码下载,大家都来down吧!!!

PS: 不是做广告,提供原贴是因为里边有许多非常好的讨论,可以学到许多东西。


二、JSVM是什么?

什么是JSVM?我想由万常华(wch3116)大哥自己来说比较准确,以下是在原贴里他的发言引用:

一直以来,js 没有统一的编写规范,导致许多优秀的代码不能很好的复用(function的复用性很差的)。就拿 51js 来说, 一直在讨论零散的技术,而不能借助众人的力量积累出一系列相对完整的“产品”,这都是因为没有“规范”,不成“体系”造成的。我希望能通过 JSVM 改变这种状态,就如斑竹所言,这只是一套方法(规范),而并完整的产品。众人拾柴火焰高,依照一个统一的规范,每个人根据自己的所长开发自己的类包,就能很好的流传开,被其他人使用。

(万常华的发言引用完)

很明显,JSVM要提供一个平台,或者是一个编码规范,通过类库可以减轻我们写脚本的工作量,同时我们也可以编写自己的类库,这一切在JSVM已经被实现了。


三、JSVM的架构

如果您真的决定继续把文章看下去,请先到JSVM无忧原贴下载最新的JSVM,在第一贴就能够找到,有两份代码,建议全部下载。

首先请解压缩第一份代码,也就是"jsvm & js 核心类库",可以看到有一个文件夹jsre,里边有两个文件夹classes、lib以及一个js文件jsvm.js。所有的类文件都应该放在classes下边,具体如何后边会讲。

这里的jsvm.js里边的代码就是JSVM的核心实现代码,我将会对里边做尽可能详尽的讲解与分析,如果不懂的话可以回贴提问,我会尽可能回复,如果有一些问题比较模糊,最好是直接到原贴里回贴发问,毕竟谁也没JSVM的作者更理解这份代码。

lib文件夹里有两个文件:JsLibTools.hta以及lib-inf.xml。前者是万常华自己提供的一个小工具,使用了HTA技术写的,主要用来把分散的js代码组织成一个xml文件,称它为lib。后者是lib的更新信息。

进入classes文件夹可以看到js文件夹以及class-inf.xml。js文件夹里存放的代码主要是优化JSVM以及为JSVM提供基础类的代码文件,按命名空间的形式存在,比如js.lang.Object这个类的代码就放在/jsre/classes/js/lang/Object.js里边。同时每个文件夹都有package.xml文件,这里边存放了该文件夹里的类信息。

另外万常华还提供了一个cn类库,即第二个代码下载,解压缩之后把cn文件夹放在classes里边。该类库与js类库不同的是它提供了许多实际应用中可以使用的代码,而前者提供了基础类。

JSVM系统变量:

$system_home: 系统目录,默认值为"/common/",这是以网站的绝对路径进行定义的,在使用JSVM之前必须进行修改。
$js_classpath: 类文件存放的根路径
$js_libpath: 类库文件存在放目录,这里的类库即前边所说的"lib"xml文件。
$js_runMode: 运行模式,有两个选项,一个是debug,一个是run。run模式是实际应用的运行模式,程序出了错不提醒访问者,另一个是debug模式,在写代码的时候有时候出了问题,设置为debug可以得到相关的出错信息。

PS: 从上边系统变量的定义可以看出一个特点:系统变量必须使用$开头。


四、JSVM的编码约定

编码约定万常万并没有给出一个比较详细的说法,不过我们可以从他在原贴的发言以及JSVM代码的组织中得出以下规范:

1. 系统变量必须使用$开头
2. 系统函数必须以_开头
3. 继承必须使用类的_extends方法而不允许直接使用prototype = new ClassName的方式
4. 所有的类都必须直接或者间接继承js.lang.Object
5. 包(package)的命名开头字母必须小写
6. 类(class)的命名开头字母必须大写
7. 在类的定义之中使用的临时变量必须以下划线_开头
8. 所有的类都必须严格遵守命名空间的约定(关于命名空间的组织可以查阅Java或者.NET)
9. 例外处理不要使用throw而是使用JSVM自定义的_throw

五、JSVM的例外处理

JavaScript本身就自带有一套例外处理,可以利用try-catch结构处理代码中可能出现的出错,但JSVM觉得这样还不够,因为这里的JavaScript是使用在Web页面中,如果没有使用try-catch的话还是同样会提供各种错误,JSVM是重写window.onerror把这种错误也拉进来一起处理,同时还定义了一个系统函数_throw,实现原理很简单,不需多讲。

具体的原型为window.onerror = function(msg, url, line)

msg为出错信息的描述,即Error对象的description属性
url为出错页面的url
line为出错的行数

在JSVM中,例外处理到处都会用到,这本来是很正常的事情,因为每一个程序员都应该处理所有可能会出现的错误。但因为种种原因,极少人在Web客户端的JavaScript中进行例外处理,大家都觉得没什么必要,从这一点也可以看出万常华编码的严谨。

六、JSVM的继承

在JavaScript中,继承是基于原型的,比如B类要继承A类可以这样子:

A.prototype = new B;

但是在JSVM中并没有如此简单,请看jsvm.js中的这段代码:

// * 定义实现 OOP 的相关方法
Function.prototype._extends = function(jsclass) {
try {
var _cn = (new RegExp("function[\\s]*([\\w|\\.]*)[\\s]*\\(")).exec(this.toString())[1]; // 得到完整类名
if (typeof(jsclass) == "string")
eval("jsclass = " + jsclass + ";");
if (typeof(jsclass) != "function")
_throw(0x000D, "JSVM/_extends:" + _cn + " 继承类错误{" + jsclass + "不是合法类}");
var _p = this.prototype = new jsclass(); // 原型继承
this._base = jsclass;
this._super = jsclass.prototype;
_p.className = _cn;
return _p; // 返回原型
} catch(ex) {
_throw(0x000E, "JSVM/_extends:" + _cn + " 继承类错误{" + ex.description + "}");
}
};

JSVM是直接给所有Function对象增加一个共用的方法_extends来实现继承,所有的类都可以通过 类名._extends("js.lang.Object")的形式来把某个类继承下来。
在继承函数里不仅使用原型继承,还同时做了许多工作,给做继承操作的子类增加了_base(父类对象)、_super(基类对象)、className(本类的类名),如果出现了任何错误还进行相关的例外处理。


待续。。。
re: asp读取xml 汪杰 2006-08-07 16:54
一个asp读取显示xml子节点数据的问题

<xml>
<test>a</test>
<guest>
<title>aaaa</title>
<info>
<day>2000</day>
<year>20000</year>
</info>
<title>bbbbb</title>
<info>
<day>4444444</day>
<year>1984</year>
</info>
........
</guest>
</xml>

要显示上面这些的有的数据,怎么做<guest></guest>里的数据条数不确定




<%
dim the_text : the_text=""
set blogdom=server.createobject("Microsoft.XMLDOM")
blogdom.async=false
blogdom.load "c:\bloginfo.xml"
set blogchild=blogdom.getElementsByTagName("guest")
for i=0 to blogchild.length-1
for j=0 to blogchild.item(i).childnodes.length-1
the_text=the_text & blogchild.item(i).childnodes(j).text
next
next
response.write the_text
%>
re: 大话字符编码(zt) 汪杰 2006-08-07 15:09
<SCRIPT language=JavaScript>
function JM_fade(ob_id){
ob=document.getElementById(ob_id);
if(ob.d==undefined)ob.d=1;
if (ob.d==0) {
ob.filters.alpha.opacity+=1
} else {
ob.filters.alpha.opacity-=1
}
if (ob.filters.alpha.opacity==100){
ob.d=1;
return;
} else if (ob.filters.alpha.opacity==0){
ob.d=0;
}
setTimeout("JM_fade('"+ob_id+"')",10)
}
</SCRIPT>
<a href="#"><IMG style="FILTER: alpha(opacity=100)" src="http://desk.blueidea.com/DESK/16001200BZ/1600flower_4/225/1600flower_4013.jpg" name=u onMouseOver="javascript:JM_fade(this.id)" id="i01"></a>

<a href="#"><IMG style="FILTER: alpha(opacity=100)" src="http://desk.blueidea.com/DESK/QTBZ/BitRed/225/BitRed005.jpg" name=u onMouseOver="javascript:JM_fade(this.id)" id="i02"></a>
re: 大话字符编码(zt) 汪杰 2006-08-07 13:31
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
作者: 伐木丁丁鸟鸣嘤嘤 fmddlmyy.home4u.china.com

这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打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个字符。

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

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。

微软提供了GB18030的升级包,但这个升级包只是提供了一套支持CJK扩展A的6582个汉字的新字体:新宋体-18030,并不改变内码。Windows 的内码仍然是GBK。

这里还有一些细节:

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

对于任何字符编码,编码单元的顺序是由编码方案指定的,与endian无关。例如GBK的编码单元是字节,用两个字节表示一个汉字。 这两个字节的顺序是固定的,不受CPU字节序的影响。UTF-16的编码单元是word(双字节),word之间的顺序是编码方案指定的,word内部的字节排列才会受到endian的影响。后面还会介绍UTF-16。

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的最新标准是ISO 10646-3:2003。

UCS只是规定如何编码,并没有规定如何传输、保存这个编码。例如“汉”字的UCS编码是6C49,我可以用4个ascii数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO-8859-1完全兼容。UTF是“UCS Transformation Format”的缩写。

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

2.1、内码和code page
目前Windows的内核已经采用Unicode编码,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的编码,而全部改用Unicode。

Windows使用代码页(code page)来适应各个国家和地区。code page可以被理解为前面提到的内码。GBK对应的code page是CP936。

微软也为GB18030定义了code page:CP54936。但是由于GB18030有一部分4字节编码,而Windows的代码页只支持单字节和双字节编码,所以这个code page是无法真正使用的。

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。

读者可以用记事本测试一下我们的编码是否正确。需要注意,UltraEdit在打开utf-8编码的文本文件时会自动转换为UTF-16,可能产生混淆。你可以在设置中关掉这个选项。更好的工具是Hex Workshop。

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)
我写过UTF-8、UCS-2、GBK相互转换的软件包,包括使用Windows API和不使用Windows API的版本。以后有时间的话,我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。

我是想清楚所有问题后才开始写这篇文章的,原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间,竟然从下午1:30写到9:00。希望有读者能从中受益。

附录1 再说说区位码、GB2312、内码和代码页
有的朋友对文章中这句话还有疑问:
“GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。”

我再详细解释一下:

“GB2312的原文”是指国家1980年的一个标准《中华人民共和国国家标准 信息交换用汉字编码字符集 基本集 GB 2312-80》。这个标准用两个数来编码汉字和中文符号。第一个数称为“区”,第二个数称为“位”。所以也称为区位码。1-9区是中文符号,16-55区是一级汉字,56-87区是二级汉字。现在Windows也还有区位输入法,例如输入1601得到“啊”。

内码是指操作系统内部的字符编码。早期操作系统的内码是与语言相关的.现在的Windows在内部统一使用Unicode,然后用代码页适应各种语言,“内码”的概念就比较模糊了。微软一般将缺省代码页指定的编码说成是内码,在特殊的场合也会说自己的内码是Unicode,例如在GB18030问题的处理上。

所谓代码页(code page)就是针对一种语言文字的字符编码。例如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的语句,例如:
<meta http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
如果原作者使用的代码页和ISO8859-1兼容,就不会出现乱码了。

再说区位码,啊的区位码是1601,写成16进制是0x10,0x01。这和计算机广泛使用的ASCII编码冲突。为了兼容00-7f的ASCII编码,我们在区位码的高、低字节上分别加上A0。这样“啊”的编码就成为B0A1。我们将加过两个A0的编码也称为GB2312编码,虽然GB2312的原文根本没提到这一点
那么GB 读 UTF-8 的时候,它认为自己读的是 UTF-8,把读到的 123456 当作是 UTF-8,然后转换成 GB 的 abcd 显示出来,所以没有乱码
那么 UTF-8 读 GB 的时候,它认为自己读的是 UTF-8,把读到的 abcd 当作是 UTF-8,然后直接显示出来,所以乱码了
BOA1(啊)->々(乱吗)->々(乱吗)
GB页面用xmlhttp读GB页面的过程可以理解成上面这样?
re: cookie编码 汪杰 2006-08-02 14:59
<script language=vbscript>
Function vbChar(str)
vbChar=Chr(str)
End Function
</script>
<script language=javascript>
var glbEncode=new Array();
function reCode(str) {
var str=str.replace(/%([B-F].)%([A-F].)/g,"@$1$2");
var t=str.split("@"),k,l=t.length;
for(var i=1;i<l;i++)
{
k=t[i].substring(0,4);
if(!glbEncode[k])glbEncode[k]=escape(vbChar(eval("0x"+k)));
t[i]=glbEncode[k]+t[i].substring(4);
}
str=unescape(t.join(""));
return str.match(/%([B-F].)%([A-F].)/g)?reCode(str):str.replace(/\+/g," ") //解决被urlencode了多次

}
</script>
re: 二进制 汪杰 2006-08-02 11:19
小数
十进制->二进制
不停的*2,再取整,再去掉整数部分
比如0.125
*2取整再去整,0,0.25
*2取整再去整,0,0.5
*2取整再去整,1,0
所以十进制的0.125变成二进制就是0.001
二进制->十进制
第N位×2^(-N)再累加
比如0.101
0.101(十进制)=1×2^(-1)+0×2^(-2)+1×2^(-3)=0.625(二进制)
re: cookie编码 汪杰 2006-08-01 16:13
<html>
<head>
<title>xml Http</title>
<script language=vbscript>
Function rsB(vIn)
rsB=MidB(vIn,1)
End Function
Function vbChar(ss)
vbChar = Chr(ss)
End Function
</script>
<script language=javascript>
//***Author: Hutia
//last modified by shouhaimu(QQ:30836570)
//速度已提高近50倍

//**全局变量**
//glbEncode储存ascii到unicode字符的转换,这样做的好处是可以提高重复解码时的解码效率
glbEncode=new Array();

//重编码
function reCode(b){
t=b.replace(/%([B-F].)%([A-F].)/g,"@$1$2");
t=t.split("@");
var i=0,j=t.length,k;
while(++i<j)
{
k=t[i].substring(0,4);
if(!glbEncode[k])glbEncode[k]=escape(vbChar(eval("0x"+k)))
t[i]=glbEncode[k]+t[i].substring(4);
}
return unescape(t.join(''));
}

function init(){
alert(reCode("%CD%F4%BD%DC"));
}
</script>
</head>
<body onload=init()>
</body>
</html>
re: js表格翻页 汪杰 2006-08-01 14:18
八神奄写的用数据岛实现表格翻页
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>不及格的程序员-八神</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=gb2312">
<META NAME="Generator" CONTENT="Wawa Editor 1.0">
<META NAME="Author" CONTENT="八神奄,海格雷尔,JavaX,杨林">
<META NAME="Keywords" CONTENT="Javascript,Java,XML,XSLT,ASP,VBScript,ASP .Net,C#,C++,Database,不及格的程序员">
<META NAME="Description" CONTENT="不及格的程序员,无所不在">
</HEAD>
<BODY>
<xml id="xmlData">
<?xml version="1.0" encoding="gb2312" ?>
<datas>
<dataRow>
<id>1</id>
<check></check>
<name>Iori</name>
<alias>Yagami</alias>
</dataRow>
<dataRow>
<id>2</id>
<check></check>
<name>Athena</name>
<alias>Asamiya</alias>
</dataRow>
<dataRow>
<id>3</id>
<check></check>
<name>Kyo</name>
<alias>Kusanag</alias>
</dataRow>
<dataRow>
<id>4</id>
<check></check>
<name>Mai</name>
<alias>Shiranui</alias>
</dataRow>
<dataRow>
<id>5</id>
<check></check>
<name>Kasumi</name>
<alias>Todo</alias>
</dataRow>
</datas>
</xml>
<table bgcolor="menu" border="1" datasrc="#xmlData" id="ListTable" DATAPAGESIZE="2">
<thead>
<th>ID</th>
<th>状态</th>
<th>名子</th>
<th>别名</th>
</thead>
<tbody>
<tr>
<td><span dataFld="id"></span></td>
<td><input type="checkbox" name="chb_Control"/></td>
<td><span dataFld="name"></span></td>
<td><span dataFld="alias"></span></td>
</tr>
</tbody>
</table>
<input type="button" onclick="ListTable.firstPage()" value="First">
<input type="button" onclick="ListTable.previousPage()" value="Pre">
<input type="button" onclick="ListTable.nextPage()" value="Next">
<input type="button" onclick="ListTable.lastPage()" value="Last">
<br><input type="button" value="Update" onclick="GetData()">
<script>
function GetData(){
var xmlDoc = document.getElementById("xmlData");
var xmlNewDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlNewDoc.loadXML("<datas><dataRow><id>1</id><name>八神</name><alias>奄</alias></dataRow></datas>");
xmlDoc.documentElement = xmlNewDoc.documentElement
}

</script>
</BODY>
</BODY>
</HTML>
快速排序法
<script>
function Half(sAry)
{
this.sortArray = sAry;
this.count = 0;

this.swap = function(i,j)
{
var tmp = this.sortArray[i];this.sortArray[i] = this.sortArray[j];this.sortArray[j] = tmp;
this.count++;
}
this.partition = function(low,high)
{
var pivot,pos,tmp,i,j;
pos = low;
pivot = this.sortArray[pos];
for(i=low+1;i<=high;i++)
{
if (this.sortArray[i]<pivot)
{
pos++;
this.swap(pos,i);
}
}
this.swap(low,pos);
return pos;
}
this.QuickSort = function(low,high)
{
var pivot;
if (low<high)
{
pivot = this.partition(low,high);
this.QuickSort(low,pivot-1);
this.QuickSort(pivot+1,high);
}
}
this.HalfFind = function(sArray,fNum)
{
var low,high,i,t;
low = 0;
i = 1;
high = sArray.length-1;
t = Math.floor((high+low) / 2);
document.getElementById("findProcess").innerHTML="";
while ((sArray[t]!=fNum) && (sArray[low]!=fNum) && (sArray[high]!=fNum) && (low < high))
{
document.getElementById("findProcess").innerHTML+="第"+i+"次查找 -> "+t+"的位置:"+sArray[t]+"&nbsp;&nbsp;&nbsp;&nbsp;low="+low+"&nbsp;high="+high+"<br>";

if (fNum>sArray[t])
{
low = t+1;
t = Math.floor((high+low) / 2);
}
else
{
high = t-1;
t = Math.floor((high+low) / 2);
}
i++
}
if ((sArray[t]!=fNum) && (sArray[low]!=fNum) && (sArray[high]!=fNum) && low >= high)
{
document.getElementById("findProcess").innerHTML+="第"+i+"次查找 -> "+t+"的位置:失败 此队列没有"+fNum+"该数&nbsp;&nbsp;&nbsp;&nbsp;low="+low+"&nbsp;high="+high+"<br>";
}
else
{
if(sArray[t]==fNum)
tt = t;
else if(sArray[low]==fNum)
tt = low;
else
tt = high;

document.getElementById("findProcess").innerHTML+="第"+i+"次查找 -> "+tt+"的位置:"+sArray[tt]+" 找到了!&nbsp;&nbsp;&nbsp;&nbsp;low="+low+"&nbsp;high="+high+"<br>";
}
return t;
}
}
</script>
二分法查找 确定数组中值为t的元素位置

要求输入的是已经排序的数组,一个数值,如果数组长度为0,则返回-1,如果没找到,也返回-1,如果找到了,就返回该元素在数组中的位置,下面代码包含二分查找的核心代码(16行)和一个测试用例。

<html>
<head>
<script language="javascript">
function binaryserach(x,t)
{
var l,u,m;//l为下界,u为上界,m为中间判断位
l = 0;
u = x.length - 1;
while (l<=u){
m = Math.floor((l+u)/2);
//document.write(l+"|"+m+"|"+u+"<br>");
if (x[m]<t)
l=m+1;
else if (x[m]==t)
return m;
else //x[m]>t
u=m-1;
}
return -1;
}



function test(){

var my_array = new Array();
for (i = 0; i < 100; i++)
{
my_array = i;
}
target=34;

document.write(binaryserach(my_array,target));

}
</script>
</head>
<body onLoad="test()">
</body>
</html>
<style type="text/css">
<!--
.li01 { background:#FFF; }
.li02 { background:#eeeeee; }
-->
</style>
<div ><ul id="list01"><li class="title"><a href="#">title</a></li><li><a href="#">111</a></li><li><a href="#">222</a></li><li><a href="#">333</a></li><li><a href="#">444</a></li><li><a href="#">555</a></li><li><a href="#">666</a></li></ul></div>
<script Language="Javascript">
objName=document.getElementById("list01").childNodes;
for (i=0;i<objName.length;i++) {
(i%2==0)?(objName[i].className = "li01"):(objName[i].className = "li02");
}
</script>
re: Codepage的定义和历史 汪杰 2006-07-20 14:32
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打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)
我写过UTF-8、UCS-2、GBK相互转换的软件包,包括使用Windows API和不使用Windows API的版本。以后有时间的话,我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。

我是想清楚所有问题后才开始写这篇文章的,原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间,竟然从下午1:30写到9:00。希望有读者能从中受益。


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

常用的字符代码是ASCII码,它原来是美国的国家标准,1967年被定为国际标准。ASCII码由8位二进制数组成,其中最高位为较验位,用于传输过程检验数据正确性。其余7位二进制数表示一个字符,共有128种组合。


OEM是Original Equipment Manufacture(原始设备制造商)的缩写,它是指一种"代工生产"方式,其含义是生产者不直接生产产品,而是利用自己掌握的"关键的核心技术",负责设计和开发、控制销售"渠道",具体的加工任务交给别的企业去做的方式。这种方式是在电子产业大量发展起来以后才在世界范围内逐步生成的一种普遍现象,微软、IBM等国际上的主要大企业均采用这种方式。


Unicode学术学会是一个非盈利的组织,是为发展,扩展和推广使用Unicode标准而建立的,Unicode学术学会设立了现代软件产品和标准文本的表示法。学术学会的会员代表了广泛领域的计算机和资讯工业的公司和组织。学术学会只由会员提供资金。Unicode学术学会的会员资格开放给世界上任何支持Unicode标准和希望协助其扩展和执行的组织及个人

ASCII: 发音为: as'-kee。美国信息交换标准码(ASCII),小型计算机最常用的编码方法,用于将字母、数字、标点符号以及控制码转换成数字形式 一旦定义后,其他计算机和通信设备就可以识别和看懂ASCII字符。ASCII定义了128个字符,包括α字符、数字、标点符号或信号,使用7个0/1位和1个奇偶位(用于数字)。 例如“C”表示为1000011,而“3”表示为0110011。作为一个7位代码,且每一位只能是“0”或“1”,因此ASCII可以描述128种“事物”,即2 x 2 x 2 x 2 x 2 x 2 x 2=128。ASCII是一种代码,事实上包括IBM、Apple以及Radio Shack/Tandy在内的世界上的每一台个人电脑都在使用这种代码对“事物”进行编码。实际上,如果个人电脑都使用了兼容调制解调器或者是空调制解调器电缆且收发速率相同,那么该兼容性编码就可以(由美国国家标准协会ANSI开发)实现个人电脑之间的通话。ASCII有各种不同类型。(没有什么是完全标准的了。)最重要的一种类型(最早来自IBM的)称为ASCII扩展。ASCII扩展将字符转换为8位代码(或1个字节),并使用前127个字符代码表示外语字母以及其他有用的符号如那些画正方形的符号。但是127以及127以下,扩展的8位ASCII代码相当于标准7位ASCII代码。ITU(现在称ITU-T)称ASCII为国际5号电报字母表。

EBCDIC:EBCDIC如同 ASCII 一样 有特定的符号 是由IBM提出的。EBCDIC(发音为ebb'-si-dick),大量应用于IBM和IBM兼容大型计算机(但是不包括使用ASCII以及ASCII扩展的个人电脑)。EBCDIC是一种8位编码方案,也就是最多有256种“事物”进行编码,即2 x 2 x 2 x 2 x 2 x 2 x 2 x 2 = 256。EBCDIC对字母、字符以及标点符号的编码与ASCII完全不一样。对于需要由IBM大型机(使用EBCDIC编码)阅读的 ASCII文件,必须使用众多翻译程序中的一个将ASCII文件转换成EBCDIC代码才能供IBM大型机阅读。
OEM:OEM是英文Original Equipment Manufacturer的缩写,按照字面意思,应翻译成原始设备制造商,指一家厂家根据另一家厂商的要求,为其生产产品和产品配件,亦称为定牌生产或授权贴牌生产。即可代表外委加工,也可代表转包合同加工。国内习惯称为协作生产、三来加工,俗称加工贸易。

UTF -8、unicode:每一种语言的不同的编码页,增加了那些需要支持不同语言的软件的复杂度。因而人们制定了一个世界标准,叫做unicode(http://www.unicode.org).Unicode为每个字符提供了唯一的特定数值,不论在什么平台上、不论在什么软件中,也不论什么语言。也就是说,它世界上使用的所有字符都列出来,并给每一个字符一个唯一特定数值。
什么是UTF-8?它与UNICODE是一回事吗?
  Unicode的最初目标,是用1个16位的编码来为超过65000字符提供映射。但这还不够,它不能覆盖全部历史上的文字,也不能解决传输的问题 (implantation head-ache's),尤其在那些基于网络的应用中。已有的软件必须做大量的工作来程序16位的数据。
  因此,Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列来编码的,用一个或几个字节来表示一个字符。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41.
  UTF-16和UTF-32分别是Unicode的16位和32位编码方式。考虑到最初的目的,通常说的Unicode就是指UTF-16。在讨论Unicode时,搞清楚哪种编码方式非常重要。
re: 编码解码 汪杰 2006-07-19 11:13
字符在计算机中以其ASCII码方式表示, 其长度为1个字节, 有符号字符型数
取值范围为-128~127, 无符号字符型数到值范围是0~255。因此在Turbo C语言中,
字符型数据在操作时将按整型数处理, 如果某个变量定义成char, 则表明该变量
是有符号的, 即它将转换成有符号的整型数。
Turbo C中规定对ASCII码值大于0x80的字符将被认为是负数。例如ASCII 值
为0x8c的字符, 定义成char时, 被转换成十六进制的整数0xff8c 。 这是因当
ASCII码值大于0x80时, 该字节的最高位为1, 计算机会认为该数为负数, 对于
0x8c表示的数实际上是-74(8c的各位取反再加1), 而-74 转换成两字节整型数并
在计算机中表示时就是0xff8c( 对0074 各位取反再加1) 。 因此只有定义为
unsigned char 0x8c转换成整型数时才是8c。这一点在处理大于0x80的ASCII码
字符时(例如汉字码)要特别注意。一般汉字均定义为unsigned char(在以后的程
序中会经常碰到)。
re: 编码解码 汪杰 2006-07-18 15:55
'函数:把二进制字符串转换成普通字符串函数
Public Function Get_BytesToBstr(FileStr)
DIM BTB_SkipFlag : BTB_SkipFlag = 0 '中文字符Skip标志
DIM BTB_varLen '字符长度
DIM BTB_CLow
DIM BTBi
DIM BTB_Content : BTB_Content = ""

If not IsNull(FileStr) Then
BTB_varLen = LenB(FileStr)
For BTBi=1 To BTB_varLen
If BTB_SkipFlag=0 Then
BTB_CLow = MidB(FileStr,BTBi,1)
'判断是否中文的字符
If AscB(BTB_CLow) > 127 Then
'AscW会把二进制的中文双字节字符高位和低位反转,所以要先把中文的高低位反转
BTB_Content = BTB_Content & Chr(AscW(MidB(FileStr,BTBi+1,1) & BTB_CLow))
BTB_SkipFlag = 1
Else
BTB_Content = BTB_Content & Chr(AscB(BTB_CLow))
End If
Else
BTB_SkipFlag = 0
End If
Next
End If
Get_BytesToBstr = BTB_Content
End Function
re: 关于 URL编码 汪杰 2006-07-18 14:30
URL 编码是一种浏览器用来打包表单输入的格式. 浏览器从表单中获取所有的name和其中的值 ,
将他们作为name/value参数编码, 移去那些不能传送的字符, 将数据排行等等,这些还取决于你用GET还是POST?作为URL的一部分或者分离地发给服务器. 不管哪种情况, 在服务器端的表单输入格式样子
象这样:theName=Ichabod+Crane&gender=male
URL编码遵循下列规则:
每对name/value由&符分开.
每对来自表单的name/value由=符分开. 如果用户没有输入值给这个name,那么这个name还是出现,只
是无值(象这样 "name=").
任何特殊的字符(就是那些不是简单的七位ASCII,如汉字) 将以百分符%用十六进制编码. 当然也包括
象 =, &, 和 % 这些特殊的字符.
re: Javascript Type-Conversion 汪杰 2006-06-14 16:56
<input type=text onpaste="return !clipboardData.getData('text').match(/\D/)" onKeyPress="event.returnValue=(event.keyCode>=48)&&(event.keyCode<=57);">
When numbers are converted to boolean, zero becomes false and all other numbers are true. With the excepting of the special numeric value NaN (Not a Number) which is used when another type is converted to a number but that conversion does not result in a meaningful number. NaN is always false. The values of positive and negative infinity, while not finite numbers, are non-zero numeric values and always type-convert to boolean true.

Type conversion rules are even simpler for string to boolean conversion as all non-empty strings always become true and empty strings become false.

共3页: 1 2 3 

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 457575
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜