nginx再次优化记录贴

nginx指令中的优化(配置文件)

worker_processes 8;

nginx进程数,建议按照cpu数目来指定,一般为它的倍数。

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

为每个进程分配cpu,上例中将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

worker_rlimit_nofile 102400;

这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

use epoll;

使用epoll的I/O模型,这个不用说了吧。

worker_connections 102400;

每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes*worker_connections。

keepalive_timeout 60;

keepalive超时时间。

client_header_buffer_size 4k;

客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。

open_file_cache max=102400 inactive=20s;

这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。

open_file_cache_valid 30s;

这个是指多长时间检查一次缓存的有效信息。

open_file_cache_min_uses 1;

open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。

内核参数的优化

net.ipv4.tcp_max_tw_buckets = 6000

timewait的数量,默认是180000。

net.ipv4.ip_local_port_range = 1024    65000

允许系统打开的端口范围。

net.ipv4.tcp_tw_recycle = 1

启用timewait快速回收。

net.ipv4.tcp_tw_reuse = 1

开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_syncookies = 1

开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。

net.core.somaxconn = 262144

web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。

net.core.netdev_max_backlog = 262144

每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

net.ipv4.tcp_max_orphans = 262144

系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。

net.ipv4.tcp_max_syn_backlog = 262144

记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。

net.ipv4.tcp_timestamps = 0

时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种”异常”的数据包。这里需要将其关掉。

net.ipv4.tcp_synack_retries = 1

为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。

net.ipv4.tcp_syn_retries = 1

在内核放弃建立连接之前发送SYN包的数量。

net.ipv4.tcp_fin_timeout = 1

如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。

net.ipv4.tcp_keepalive_time = 30

当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时。

一个完整的内核优化配置

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096        87380   4194304
net.ipv4.tcp_wmem = 4096        16384   4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024    65000

一个简单的nginx优化配置文件

user  www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000;
error_log  /www/log/nginx_error.log  crit;
pid        /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 204800;

events
{
  use epoll;
  worker_connections 204800;
}

http
{
  include       mime.types;
  default_type  application/octet-stream;

  charset  utf-8;

  server_names_hash_bucket_size 128;
  client_header_buffer_size 2k;
  large_client_header_buffers 4 4k;
  client_max_body_size 8m;

  sendfile on;
  tcp_nopush     on;

  keepalive_timeout 60;

  fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
                keys_zone=TEST:10m
                inactive=5m;
  fastcgi_connect_timeout 300;
  fastcgi_send_timeout 300;
  fastcgi_read_timeout 300;
  fastcgi_buffer_size 16k;
  fastcgi_buffers 16 16k;
  fastcgi_busy_buffers_size 16k;
  fastcgi_temp_file_write_size 16k;
  fastcgi_cache TEST;
  fastcgi_cache_valid 200 302 1h;
  fastcgi_cache_valid 301 1d;
  fastcgi_cache_valid any 1m;
  fastcgi_cache_min_uses 1;
  fastcgi_cache_use_stale error timeout invalid_header http_500;

  open_file_cache max=204800 inactive=20s;
  open_file_cache_min_uses 1;
  open_file_cache_valid 30s;

  tcp_nodelay on;

  gzip on;
  gzip_min_length  1k;
  gzip_buffers     4 16k;
  gzip_http_version 1.0;
  gzip_comp_level 2;
  gzip_types       text/plain application/x-javascript text/css application/xml;
  gzip_vary on;

  server
  {
    listen       8080;
    server_name  ad.test.com;
    index index.php index.htm;
    root  /www/html/;

    location /status
    {
        stub_status on;
    }

    location ~ .*\.(php|php5)?$
    {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fcgi.conf;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
    {
      expires      30d;
    }

    log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '
              '$status $body_bytes_sent "$http_referer" '
              '"$http_user_agent" $http_x_forwarded_for';
    access_log  /www/log/access.log  access;
      }
}

关于FastCGI的几个指令

fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;

这个指令为FastCGI缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。

fastcgi_connect_timeout 300;

指定连接到后端FastCGI的超时时间。

fastcgi_send_timeout 300;

向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。

fastcgi_read_timeout 300;

接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。

fastcgi_buffer_size 16k;

指定读取FastCGI应答第一部分需要用多大的缓冲区,这里可以设置为fastcgi_buffers指令指定的缓冲区大小,上面的指令指定它将使用1个16k的缓冲区去读取应答的第一部分,即应答头,其实这个应答头一般情况下都很小(不会超过1k),但是你如果在fastcgi_buffers指令中指定了缓冲区的大小,那么它也会分配一个fastcgi_buffers指定的缓冲区大小去缓存。

fastcgi_buffers 16 16k;

指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答,如上所示,如果一个php脚本所产生的页面大小为256k,则会为其分配16个16k的缓冲区来缓存,如果大于256k,增大于256k的部分会缓存到fastcgi_temp指定的路径中,当然这对服务器负载来说是不明智的方案,因为内存中处理数据速度要快于硬盘,通常这个值的设置应该选择一个你的站点中的php脚本所产生的页面大小的中间值,比如你的站点大部分脚本所产生的页面大小为256k就可以把这个值设置为16 16k,或者4 64k 或者64 4k,但很显然,后两种并不是好的设置方法,因为如果产生的页面只有32k,如果用4 64k它会分配1个64k的缓冲区去缓存,而如果使用64 4k它会分配8个4k的缓冲区去缓存,而如果使用16 16k则它会分配2个16k去缓存页面,这样看起来似乎更加合理。

fastcgi_busy_buffers_size 32k;

这个指令我也不知道是做什么用,只知道默认值是fastcgi_buffers的两倍。

fastcgi_temp_file_write_size 32k;

在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍。

fastcgi_cache TEST

开启FastCGI缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU负载,并且防止502错误。但是这个缓存会引起很多问题,因为它缓存的是动态页面。具体使用还需根据自己的需求。

fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;

为指定的应答代码指定缓存时间,如上例中将200,302应答缓存一小时,301应答缓存1天,其他为1分钟。

fastcgi_cache_min_uses 1;

缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数,如上例,如果在5分钟内某文件1次也没有被使用,那么这个文件将被移除。

fastcgi_cache_use_stale error timeout invalid_header http_500;

不知道这个参数的作用,猜想应该是让nginx知道哪些类型的缓存是没用的。 以上为nginx中FastCGI相关参数,另外,FastCGI自身也有一些配置需要进行优化,如果你使用php-fpm来管理FastCGI,可以修改配置文件中的以下值:

<value name="max_children">60</value>

同时处理的并发请求数,即它将开启最多60个子线程来处理并发连接。

<value name="rlimit_files">102400</value>

最多打开文件数。

<value name="max_requests">204800</value>

每个进程在重置之前能够执行的最多请求数。

php数组排序与查找算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
//冒泡排序(数组排序)
function bubble_sort($array)
{
   $count = count($array);
   if ($count <= 0) return false;

   for($i=0; $i<$count; $i++){
   for($j=$count-1; $j>$i; $j--){
   if ($array[$j] < $array[$j-1]){
   $tmp = $array[$j];
   $array[$j] = $array[$j-1];
   $array[$j-1] = $tmp;
   }
   }
   }
   return $array;
}

//快速排序(数组排序)
function quick_sort($array) {
   if (count($array) <= 1) return $array;

   $key = $array[0];
   $left_arr = array();
   $right_arr = array();

   for ($i=1; $i<count($array); $i++){
   if ($array[$i] <= $key)
   $left_arr[] = $array[$i];
   else
   $right_arr[] = $array[$i];
   }

   $left_arr = quick_sort($left_arr);
   $right_arr = quick_sort($right_arr);

   return array_merge($left_arr, array($key), $right_arr);
}

//二分查找(数组里查找某个元素)
function bin_sch($array, $low, $high, $k){
   if ($low <= $high){
   $mid = intval(($low+$high)/2);
   if ($array[$mid] == $k){
   return $mid;
   }elseif ($k < $array[$mid]){
   return bin_sch($array, $low, $mid-1, $k);
   }else{
   return bin_sch($array, $mid+1, $high, $k);
   }
   }
   return -1;
}

//顺序查找(数组里查找某个元素)
function seq_sch($array, $n, $k){
   $array[$n] = $k;
   for($i=0; $i<$n; $i++){
   if($array[$i]==$k){
   break;
   }
   }
   if ($i<$n){
   return $i;
   }else{
   return -1;
   }
}
?>

thinkphp官方cms左侧菜单部分乱码问题解决

后台模板public 文件夹下面的memu.html文中的{$Think.get.title}改为{$Think.get.title|iconv=”gb2312″,”utf-8″,###}

支持js加密码php解密或是php加密js解密的算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
class EncryptUtil{
    protected  static function long2str($v, $w) {
        $len = count($v);
        $n = ($len - 1) << 2;
        if ($w) {
            $m = $v[$len - 1];
            if (($m < $n - 3) || ($m > $n)) return false;
            $n = $m;
        }
        $s = array();
        for ($i = 0; $i < $len; $i++) {
            $s[$i] = pack("V", $v[$i]);
        }
        if ($w) {
            return substr(join('', $s), 0, $n);
        }
        else {
            return join('', $s);
        }
    }

    protected  static function str2long($s, $w) {
        $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3));
        $v = array_values($v);
        if ($w) {
            $v[count($v)] = strlen($s);
        }
        return $v;
    }
    protected  static function int32($n) {
        while ($n >= 2147483648) $n -= 4294967296;
        while ($n <= -2147483649) $n += 4294967296;
        return (int)$n;
    }

    protected static function my_encrypt($str, $key) {
        if ($str == "") {
            return "";
        }
        $v = self::str2long($str, true);
        $k = self::str2long($key, false);
        if (count($k) < 4) {
            for ($i = count($k); $i < 4; $i++) {
                $k[$i] = 0;
            }
        }
        $n = count($v) - 1;

        $z = $v[$n];
        $y = $v[0];
        $delta = 0x9E3779B9;
        $q = floor(6 + 52 / ($n + 1));
        $sum = 0;
        while (0 < $q--) {
            $sum = self::int32($sum + $delta);
            $e = $sum >> 2 & 3;
            for ($p = 0; $p < $n; $p++) {
                $y = $v[$p + 1];
                $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
                $z = $v[$p] = self::int32($v[$p] + $mx);
            }
            $y = $v[0];
            $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $z = $v[$n] = self::int32($v[$n] + $mx);
        }
        return self::long2str($v, false);
    }

    protected static function xxtea_decrypt($str, $key) {
        if ($str == "") {
            return "";
        }
        $v = self::str2long($str, false);
        $k = self::str2long($key, false);
        if (count($k) < 4) {
            for ($i = count($k); $i < 4; $i++) {
                $k[$i] = 0;
            }
        }
        $n = count($v) - 1;

        $z = $v[$n];
        $y = $v[0];
        $delta = 0x9E3779B9;
        $q = floor(6 + 52 / ($n + 1));
        $sum = self::int32($q * $delta);
        while ($sum != 0) {
            $e = $sum >> 2 & 3;
            for ($p = $n; $p > 0; $p--) {
                $z = $v[$p - 1];
                $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
                $y = $v[$p] = self::int32($v[$p] - $mx);
            }
            $z = $v[$n];
            $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $y = $v[0] = self::int32($v[0] - $mx);
            $sum = self::int32($sum - $delta);
        }
        return self::long2str($v, true);
    }
    public static function encrypt($string,$key){
        $string=self::my_encrypt($string,$key);
        if($string){
            $string=base64_encode($string);
        }
        return $string;
    }
    public static function decrypt($string,$key){
        $string=self::my_decrypt(base64_decode($string),$key);
        return $string;
    }
}

hash算法总结

经常会用到的hash算法总结.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/**
* Hash算法大全
* 推荐使用FNV1算法      
* @editDetail Create  
*/
 
public class HashAlgorithms    
{    
/**  
* 加法hash  
* @param key 字符串  
* @param prime 一个质数  
* @return hash结果  
*/
 
public static int additiveHash(String key, int prime)    
{    
   int hash, i;    
   for (hash = key.length(), i = 0; i < key.length(); i++)    
    hash += key.charAt(i);    
   return (hash % prime);    
}    
   
/**  
* 旋转hash  
* @param key 输入字符串  
* @param prime 质数  
* @return hash值  
*/
 
public static int rotatingHash(String key, int prime)    
{    
   int hash, i;    
   for (hash=key.length(), i=0; i<key.length(); ++i)    
     hash = (hash<<4)^(hash>>28)^key.charAt(i);    
   return (hash % prime);    
//   return (hash ^ (hash>>10) ^ (hash>>20));    
}    
   
// 替代:    
// 使用:hash = (hash ^ (hash>>10) ^ (hash>>20)) & mask;    
// 替代:hash %= prime;    
   
   
/**  
* MASK值,随便找一个值,最好是质数  
*/
 
static int M_MASK = 0x8765fed1;    
/**  
* 一次一个hash  
* @param key 输入字符串  
* @return 输出hash值  
*/
 
public static int oneByOneHash(String key)    
{    
   int   hash, i;    
   for (hash=0, i=0; i<key.length(); ++i)    
   {    
     hash += key.charAt(i);    
     hash += (hash << 10);    
     hash ^= (hash >> 6);    
   }    
   hash += (hash << 3);    
   hash ^= (hash >> 11);    
   hash += (hash << 15);    
//   return (hash & M_MASK);    
   return hash;    
}    
   
/**  
* Bernstein's hash  
* @param key 输入字节数组  
* @param level 初始hash常量  
* @return 结果hash  
*/
 
public static int bernstein(String key)    
{    
   int hash = 0;    
   int i;    
   for (i=0; i<key.length(); ++i) hash = 33*hash + key.charAt(i);    
   return hash;    
}    
   
//    
//// Pearson's Hash    
// char pearson(char[]key, ub4 len, char tab[256])    
// {    
//   char hash;    
//   ub4 i;    
//   for (hash=len, i=0; i<len; ++i)    
//     hash=tab[hash^key[i]];    
//   return (hash);    
// }    
   
//// CRC Hashing,计算crc,具体代码见其他    
// ub4 crc(char *key, ub4 len, ub4 mask, ub4 tab[256])    
// {    
//   ub4 hash, i;    
//   for (hash=len, i=0; i<len; ++i)    
//     hash = (hash >> 8) ^ tab[(hash & 0xff) ^ key[i]];    
//   return (hash & mask);    
// }    
   
/**  
* Universal Hashing  
*/
 
public static int universal(char[]key, int mask, int[] tab)    
{    
   int hash = key.length, i, len = key.length;    
   for (i=0; i<(len<<3); i+=8)    
   {    
     char k = key[i>>3];    
     if ((k&0x01) == 0) hash ^= tab[i+0];    
     if ((k&0x02) == 0) hash ^= tab[i+1];    
     if ((k&0x04) == 0) hash ^= tab[i+2];    
     if ((k&0x08) == 0) hash ^= tab[i+3];    
     if ((k&0x10) == 0) hash ^= tab[i+4];    
     if ((k&0x20) == 0) hash ^= tab[i+5];    
     if ((k&0x40) == 0) hash ^= tab[i+6];    
     if ((k&0x80) == 0) hash ^= tab[i+7];    
   }    
   return (hash & mask);    
}    
   
/**  
* Zobrist Hashing  
*/
   
public static int zobrist( char[] key,int mask, int[][] tab)    
{    
   int hash, i;    
   for (hash=key.length, i=0; i<key.length; ++i)    
     hash ^= tab[i][key[i]];    
   return (hash & mask);    
}    
   
// LOOKUP3    
// 见Bob Jenkins(3).c文件    
   
// 32位FNV算法    
static int M_SHIFT = 0;    
/**  
* 32位的FNV算法  
* @param data 数组  
* @return int值  
*/
 
    public static int FNVHash(byte[] data)    
    {    
        int hash = (int)2166136261L;    
        for(byte b : data)    
            hash = (hash * 16777619) ^ b;    
        if (M_SHIFT == 0)    
            return hash;    
        return (hash ^ (hash >> M_SHIFT)) & M_MASK;    
    }    
    /**  
     * 改进的32位FNV算法1  
     * @param data 数组  
     * @return int值  
     */
 
    public static int FNVHash1(byte[] data)    
    {    
        final int p = 16777619;    
        int hash = (int)2166136261L;    
        for(byte b:data)    
            hash = (hash ^ b) * p;    
        hash += hash << 13;    
        hash ^= hash >> 7;    
        hash += hash << 3;    
        hash ^= hash >> 17;    
        hash += hash << 5;    
        return hash;    
    }    
    /**  
     * 改进的32位FNV算法1  
     * @param data 字符串  
     * @return int值  
     */
 
    public static int FNVHash1(String data)    
    {    
        final int p = 16777619;    
        int hash = (int)2166136261L;    
        for(int i=0;i<data.length();i++)    
            hash = (hash ^ data.charAt(i)) * p;    
        hash += hash << 13;    
        hash ^= hash >> 7;    
        hash += hash << 3;    
        hash ^= hash >> 17;    
        hash += hash << 5;    
        return hash;    
    }    
   
    /**  
     * Thomas Wang的算法,整数hash  
     */
   
    public static int intHash(int key)    
    {    
      key += ~(key << 15);    
      key ^= (key >>> 10);    
      key += (key << 3);    
      key ^= (key >>> 6);    
      key += ~(key << 11);    
      key ^= (key >>> 16);    
      return key;    
    }    
    /**  
     * RS算法hash  
     * @param str 字符串  
     */
 
    public static int RSHash(String str)    
    {    
        int b    = 378551;    
        int a    = 63689;    
        int hash = 0;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = hash * a + str.charAt(i);    
          a    = a * b;    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of RS Hash Function */  
   
    /**  
     * JS算法  
     */
 
    public static int JSHash(String str)    
    {    
       int hash = 1315423911;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of JS Hash Function */  
   
    /**  
     * PJW算法  
     */
 
    public static int PJWHash(String str)    
    {    
        int BitsInUnsignedInt = 32;    
        int ThreeQuarters     = (BitsInUnsignedInt * 3) / 4;    
        int OneEighth         = BitsInUnsignedInt / 8;    
        int HighBits          = 0xFFFFFFFF << (BitsInUnsignedInt - OneEighth);    
        int hash              = 0;    
        int test              = 0;    
   
       for(int i = 0; i < str.length();i++)    
       {    
          hash = (hash << OneEighth) + str.charAt(i);    
   
          if((test = hash & HighBits) != 0)    
          {    
             hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));    
          }    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of P. J. Weinberger Hash Function */  
   
    /**  
     * ELF算法  
     */
 
    public static int ELFHash(String str)    
    {    
        int hash = 0;    
        int x    = 0;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = (hash << 4) + str.charAt(i);    
          if((x = (int)(hash & 0xF0000000L)) != 0)    
          {    
             hash ^= (x >> 24);    
             hash &= ~x;    
          }    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of ELF Hash Function */  
   
    /**  
     * BKDR算法  
     */
 
    public static int BKDRHash(String str)    
    {    
        int seed = 131; // 31 131 1313 13131 131313 etc..    
        int hash = 0;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = (hash * seed) + str.charAt(i);    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of BKDR Hash Function */  
   
    /**  
     * SDBM算法  
     */
 
    public static int SDBMHash(String str)    
    {    
        int hash = 0;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of SDBM Hash Function */  
   
    /**  
     * DJB算法  
     */
 
    public static int DJBHash(String str)    
    {    
       int hash = 5381;    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = ((hash << 5) + hash) + str.charAt(i);    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }    
    /* End Of DJB Hash Function */  
   
    /**  
     * DEK算法  
     */
 
    public static int DEKHash(String str)    
    {    
        int hash = str.length();    
   
       for(int i = 0; i < str.length(); i++)    
       {    
          hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);    
       }    
   
       return (hash & 0x7FFFFFFF);    
    }