Cache-Control

January 15, 2010 by 王 超 · Leave a Comment
Filed under: LAMP开发 

The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain. The directives specify behavior intended to prevent caches from adversely interfering with the request or response. These directives typically override the default caching algorithms. Cache directives are unidirectional in that the presence of a directive in a request does not imply that the same directive is to be given in the response. Note that HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache (see section 14.32). Cache directives MUST be passed through by a proxy or gateway application, regardless of their significance to that application, since the directives might be applicable to all recipients along the request/response chain. It is not possible to specify a cache- directive for a specific cache. Cache-Control = “Cache-Control” “:” 1#cache-directive cache-directive = cache-request-directive | cache-response-directive cache-request-directive = “no-cache” ; Section 14.9.1 | “no-store” ; Section 14.9.2 | “max-age” “=” delta-seconds ; Section 14.9.3, 14.9.4 | “max-stale” [ "=" delta-seconds ] ; Section 14.9.3 | “min-fresh” “=” delta-seconds ; Section 14.9.3 | “no-transform” ; Section 14.9.5 | “only-if-cached” ; Section 14.9.4 | cache-extension ; Section 14.9.6 cache-response-directive = “public” ; Section 14.9.1 | “private” [ "=" <"> 1#field-name <"> ] ; Section 14.9.1 | “no-cache” [ "=" <"> 1#field-name <"> ]; Section 14.9.1 | “no-store” ; Section 14.9.2 | “no-transform” ; Section 14.9.5 | “must-revalidate” ; Section 14.9.4 | “proxy-revalidate” ; Section 14.9.4 | “max-age” “=” delta-seconds ; Section 14.9.3 | “s-maxage” “=” delta-seconds ; Section 14.9.3 | cache-extension ; Section 14.9.6 cache-extension = token [ "=" ( token | quoted-string ) ] When a directive appears without any 1#field-name parameter, the directive applies to the entire request or response. When such a directive appears with a 1#field-name parameter, it applies only to the named field or fields, and not to the rest of the request or response. This mechanism supports extensibility; implementations of future versions of the HTTP protocol might apply these directives to header fields not defined in HTTP/1.1. The cache-control directives can be broken down into these general categories: – Restrictions on what are cacheable; these may only be imposed by the origin server. – Restrictions on what may be stored by a cache; these may be imposed by either the origin server or the user agent. – Modifications of the basic expiration mechanism; these may be imposed by either the origin server or the user agent. – Controls over cache revalidation and reload; these may only be imposed by a user agent. – Control over transformation of entities. – Extensions to the caching system.

汉字编码问题

December 29, 2009 by 王 超 · Leave a Comment
Filed under: C/C++ 

由于常常要和汉字处理打交道,因此,我常常受到汉字编码问题的困扰。在不断的打击与坚持中,也积累了一点汉字编码方面的经验,想和大家一起分享。

一、汉字编码的种类

汉字编码中现在主要用到的有三类,包括GBK,GB2312和Big5。

1、GB2312又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。它是一个简化字的编码规范,当然也包括其他的符号、字母、日文假名等,共7445个图形字符,其中汉字占6763个。我们平时说6768个汉字,实际上里边有5个编码为空白,所以总共有6763个汉字。

GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。GB2312中汉字的编码范围为,第一字节0xB0-0xF7(对应十进制为176-247),第二个字节0xA0-0xFE(对应十进制为160-254)。

GB2312将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。

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

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

表1 汉字编码范围

名称

第一字节

第二字节

GB2312

0xB0-0xF7(176-247)

0xA0-0xFE(160-254)

GBK

0×81-0xFE(129-254)

0×40-0xFE(64-254)

Big5

0×81-0xFE(129-255)

0×40-0×7E(64-126)

0xA1-0xFE(161-254)

二、对汉字进行hash

为了处理汉字的方便,在查找汉字的时候,我们通常会用到hash的方法,那怎么来确定一个汉字位置呢?这就和每种编码的排列有关了,这里主要给出一种hash函数的策略。

对于GB2312编码,设输入的汉字为GBword,我们可以采用公式(C1-176)*94 + (C2-161)确定GBindex。其中,C1表示第一字节,C2表示第二字节。具体如下:

GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) – 161;

之所以用unsigned char类型,是因为char是一个字节,如果用unsigend int,因为int是4个字节的,所以会造成扩展,导致错误。

对于GBK编码,设输入的汉字为GBKword,则可以采用公式 index=(ch1-0×81)*190+(ch2-0×40)-(ch2/128),其中ch1是第一字节,ch2是第二字节。

具体的,

GBKindex = ((unsigned char)GBKword[0]-129)*190 +

((unsigned char)GBKword[1]-64) – (unsigned char)GBKword[1]/128;

三、怎样判断一个汉字的是什么编码

直接根据汉字的编码范围判断,对于GB2312和GBK可用下面两个程序实现。

1、判断是否是GB2312

bool isGBCode(const string& strIn)

{

unsigned char ch1;

unsigned char ch2;

if (strIn.size() >= 2)

{

ch1 = (unsigned char)strIn.at(0);

ch2 = (unsigned char)strIn.at(1);

if (ch1>=176 && ch1<=247 && ch2>=160 && ch2<=254) return true; else return false; } else return false; }

2、判断是否是GBK编码 bool isGBKCode(const string& strIn) { unsigned char ch1; unsigned char ch2; if (strIn.size() >= 2)

{

ch1 = (unsigned char)strIn.at(0);

ch2 = (unsigned char)strIn.at(1);

if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)

return true;

else return false;

}

else return false;

}

3、对于Big5

它的范围为:高字节从0xA0到0xFE,低字节从0×40到0×7E,和0xA1到0xFE两部分。判断一个汉字是否是BIG5编码,可以如上对字符的编码范围判断即可。如何定位呢?那么也想象所有编码排列为一个二维坐标,纵坐标是高字节,横坐标是低字节。这样一行上的汉字个数:(0×7E-0×40+1)+(0xFE-0xA1+1)=157。那么定位算法分两块,为:

if 0×40<=ch2<=0×7E: #is big5 char

index=((ch1-0xA1)*157+(ch2-0×40))*2

elif 0xA1<=ch2<=0xFE: #is big5 char

index=((ch1-0xA1)*157+(ch2-0xA1+63))*2

对于第二块,计算偏移量时因为有两块数值,所以在计算后面一段值时,不要忘了前面还有一段值。0×7E-0×40+1=63。

四、如果判断一个字符是西文字符还是中文字符

大家知道西文字符主要是指ASCII码,它用一个字节表示。且这个字符转换成数字之后,该数字是大于0的,而汉字是两个字节的,第一个字节的转化为数字之后应该是小于0的,因此可以根据每个字节转化为数字之后是否小于0,判断它是否是汉字。

例如,设输入字为strin,则,

If (strin.at(0) < 0)

cout << ”是汉字” << endl;

else cout << ”不是汉字” << endl;

PHP中GBK和UTF8编码处理

December 29, 2009 by 王 超 · Leave a Comment
Filed under: PHP 

一、编码范围

1. GBK (GB2312/GB18030)
\x00-\xff GBK双字节编码范围
\x20-\x7f ASCII
\xa1-\xff 中文
\x80-\xff 中文

2. UTF-8 (Unicode)
\u4e00-\u9fa5 (中文)
\x3130-\x318F (韩文
\xAC00-\xD7A3 (韩文)
\u0800-\u4e00 (日文)
ps: 韩文是大于[\u9fa5]的字符

正则例子:
preg_replace(”/([\x80-\xff])/”,”",$str);
preg_replace(”/([u4e00-u9fa5])/”,”",$str);

二、代码例子


//判断内容里有没有中文-GBK (PHP)
function check_is_chinese($s){
    return preg_match('/[\x80-\xff]./', $s);
}

//获取字符串长度-GBK (PHP)
function gb_strlen($str){
    $count = 0;
    for($i=0; $i 127) {
            $count++;
            if($value >= 192 && $value <= 223) $i++;
            elseif($value >= 224 && $value <= 239) $i = $i + 2;
            elseif($value >= 240 && $value <= 247) $i = $i + 3;
            else die('Not a UTF-8 compatible string');
        }
        $count++;
    }
    return $count;
}

//截取字符串-UTF8(PHP)
function utf8_substr($str,$position,$length){
    $start_position = strlen($str);
    $start_byte = 0;
    $end_position = strlen($str);
    $count = 0;
    for($i = 0; $i < strlen($str); $i++){
        if($count >= $position && $start_position > $i){
            $start_position = $i;
            $start_byte = $count;
        }
        if(($count-$start_byte)>=$length) {
            $end_position = $i;
            break;
        }
        $value = ord($str[$i]);
        if($value > 127){
            $count++;
            if($value >= 192 && $value <= 223) $i++;
            elseif($value >= 224 && $value <= 239) $i = $i + 2;
            elseif($value >= 240 && $value <= 247) $i = $i + 3;
            else die('Not a UTF-8 compatible string');
        }
        $count++;

    }
    return(substr($str,$start_position,$end_position-$start_position));
}

//字符串长度统计-UTF8 [中文3个字节,俄文、韩文占2个字节,字母占1个字节] (Ruby)
def utf8_string_length(str)
    temp = CGI::unescape(str)
    i = 0;
    j = 0;
    temp.length.times{|t|
        if temp[t] < 127
            i += 1
        elseif temp[t] >= 127 and temp[t] < 224
            j += 1
            if 0 == (j % 2)
                i += 2
                j = 0
            end
        else
            j += 1
            if 0 == (j % 3)
                i +=2
                j = 0
            end
        end
    }
    return i
}

//判断是否是有韩文-UTF-8 (JavaScript)
function checkKoreaChar(str) {
    for(i=0; i 0x3130 && str.charCodeAt(i) < 0x318F) || (str.charCodeAt(i) >= 0xAC00 && str.charCodeAt(i) <= 0xD7A3))) {
            return true;
        }
    }
    return false;
}

//判断是否有中文字符-GBK (JavaScript)
function check_chinese_char(s){
    return (s.length != s.replace(/[^\x00-\xff]/g,"**").length);

三、参考文档

http://www.unicode.org/
http://examples.oreilly.com/cjkvinfo/doc/cjk.inf
http://www.ansell-uebersetzungen.com/gbuni.html
http://www.haiyan.com/steelk/navigator/ref/gbk/gbindex.htm
http://baike.baidu.com/view/40801.htm
http://www.chedong.com/tech/hello_unicode.html

另:


/*
* 中文截取,支持gb2312,gbk,utf-8,big5
*
* @param string $str 要截取的字串
* @param int $start 截取起始位置
* @param int $length 截取长度
* @param string $charset utf-8|gb2312|gbk|big5 编码
* @param $suffix 是否加尾缀
*/
public function csubstr($str, $start=0, $length, $charset="utf-8", $suffix=true)
{
if(function_exists("mb_substr"))
return mb_substr($str, $start, $length, $charset);
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("",array_slice($match[0], $start, $length));
if($suffix) return $slice."…";
return $slice;
}

校内网的服务器推技术初探

December 25, 2009 by 王 超 · Leave a Comment
Filed under: WebServices 

最近对服务器推有点感兴趣,今天测试了一下校内网的服务器推技术。
首先感谢下,帮我测试的同学。虽然他们不知道我在做什么。

首先,发出一个GET请求来获取到在线好友列表,

选择了一个好友发送一句话(POST)(iframe里面有个input来实现这个功能)。

好友返回一句话,这时,调用ajax请求 GET到校内网的服务器数据的变化,这个时候ajax是一直处于状态3,当服务器有数据更新的时候,返回数据,此时ajax的状态为4,同时开始下一个ajax请求。

这个过程就这么完成了,现在这种服务器推技术在SNS中应用还是挺广泛的,由于他解决了,HTTP协议的无状态连接。加强了web application 的时效性。并且不用定时去调用ajax请求了,减轻了服务器的负担。其应用更是加快了SNS的发展。对传统的IM也起到了冲击作用。

PHP解析器代号分析

December 9, 2009 by 王 超 · Leave a Comment
Filed under: PHP 

当我们运行的php程序出现错误,警告,提示的时候,我们会看到有T_ERROR,T_NOTICE 之类的代码,其实这些是php的解析器的代码
在ZE中的zend_language_parser.h这个文件中定义了这些代码所对应的数字代码。并且在ext/tokenizer.c中定义了相关的两个函数,分别为
token_get_all和token_name

SOAP

December 8, 2009 by 王 超 · Leave a Comment
Filed under: 名词解释 

SOAP is a simple XML-based protocol to let applications exchange information over HTTP.

In our SOAP tutorial, you will learn what SOAP is, and how it uses XML to exchange information between applications.

接口和抽象类的区别

December 3, 2009 by 王 超 · Leave a Comment
Filed under: PHP 

接口和抽象类真的有时候很难分开,他们很相似,方法都没有定义逻辑,都是提过子类实现或者继承的。但是要区别二者只要记住一句话就行:接口是规范,类是实现。
具体来看一个例子。
假设有一个Animal类,有两个子类,Dog和Pig类,二者都有两个方法:run()和speak();
假定Dog类和Pig类的run()方法在业务逻辑上是相同的,但是speak()方法不同,那么给这两个类定义一个接口规范IAmimal的话,就必须包括这两个方法,如<错误的定义方法>


interface IAnimal{
    public function run () ;//接口中的方法都是public的,以方便子类继承。
   public function speak();
}

Animail 类来实现这个接口


class Animal implements IAnimal{
    public function run(){ //方法的可见性可以不为public
    //业务逻辑
    }
    public function speak(){ //方法的可见性可以不为public
    //业务逻辑
    }
}

class Dog extends Animal{
    public function speak(){ //方法的可见性可以不为public
    //业务逻辑
    }
}

class Pigextends Animal{
    public function speak(){ //方法的可见性可以不为public
    //业务逻辑
    }
}

在类Animal中也为speak()方法定义了业务逻辑实现,这不符合“面向对象开发是描述真实世界的一种方法论”这个基本内涵,因为其每个子类都有该方法的不同的业务逻辑,一个抽象的基类本身是从子类抽象,概括出来的,不能定义自己子类的具体行为,因此这种方法是错误的,应该将speak()方法留给子类去实现,无需在Anmial中定义。所以正确的方法应该是


interface IAnimal{
    public function run();
    public function speak();
}
abstract class Animal implements IAnmal{
    public function run(){
         //业务逻辑
    }
}
class Dog extends Animal{
    public function speak(){
    //业务逻辑
    }
class Pig extends Animal{
    public function speak(){
        //业务逻辑
    }
}
}

HTTP 1.1状态代码及其含义

November 25, 2009 by 王 超 · Leave a Comment
Filed under: 名词解释 

下表显示了常见的HTTP 1.1状态代码以及它们对应的状态信息和含义。

应当谨慎地使用那些只有HTTP 1.1支持的状态代码,因为许多浏览器还只能够支持HTTP 1.0。如果你使用了HTTP 1.1特有的状态代码,最好能够检查一下请求的HTTP版本号。

php 数据自动转义

November 20, 2009 by 王 超 · Leave a Comment
Filed under: PHP 

在php.ini中关于自动转义的配置参数:
magic_quotes_gpc
magic_quotes_runtime
magic_quotes_sybase

具体配置含义如下:
magic_quotes_gpc
作用范围是:WEB客户服务端;
作用时间:请求开始是,例如当脚本运行时.

magic_quotes_runtime
作用范围:从文件中读取的数据或执行exec()的结果或是从SQL查询中得到的;
作用时间:每次当脚本访问运行状态中产生的数据.

所以
magic_quotes_gpc的设定值将会影响通过Get/Post/Cookies获得的数据
magic_quotes_runtime的设定值将会影响从文件中读取的数据或从数据库查询得到的数据
(当参数设置成on的时候生效)
在大多数情况下是设置成关闭的即设置成OFF
这个时候要用自动转义功能可以先得到系统的参数,如果是关闭的,就可以调用转义函数来进行转义。

下面提供一个函数给参考:


if (get_magic_quotes_gpc()) {
$in = array(& $_GET, & $_POST, & $_COOKIE, & $_REQUEST);
while (list($k,$v) = each($in)) {
foreach ($v as $key => $val) {
if (!is_array($val)) {
$in[$k][$key] = stripslashes($val);
continue;
}
$in[] =& $in[$k][$key];
}
}
unset($in);

查看手册相关的函数有:

set_magic_quotes_runtime():
设置magic_quotes_runtime值. 0=关闭.1=打开.默认状态是关闭的.可以通过 echo phpinfo(); 查看magic_quotes_runtime

get_magic_quotes_gpc():
查看magic_quotes_gpc值.0=关闭.1=打开.

get_magic_quotes_runtime():
查看magic_quotes_runtime值。0=关闭.1=打开.

注意的是没有 set_magic_quotes_gpc()这个函数,就是不能在程序里面设置magic_quotes_gpc的值

js短路计算

November 19, 2009 by 王 超 · Leave a Comment
Filed under: js/js框架 

JavaScript有三个逻辑运算符:两个二元运算符和一个一元运算符。(&& || !)
对于两个逻辑运算符,JavaScript引擎有一种被称作第一表达式短路的计算方法。如果逻辑运算符是与(&&)运算,而第一个表达式为假,就不会计算第二个,因为整个表达式的值只能为假。
在使用逻辑或运算符时,如果第一个表达式的值为真,第二个表达式就不用计算了。运算数中有一个为真,那么或表达式的值就会为真。

Next Page »