(总结)Linux的chattr与lsattr命令详解

PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了。chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,不过现在生产绝大部分跑的linux系统都是2.6以上内核了。通过chattr命令修改属性能够提高系统的安全性,但是它并不适合所有的目录。chattr命令不能保护/、/dev、/tmp、/var目录。lsattr命令是显示chattr命令设置的文件属性。
这两个命令是用来查看和改变文件、目录属性的,与chmod这个命令相比,chmod只是改变文件的读写、执行权限,更底层的属性控制是由chattr来改变的。

chattr命令的用法:chattr [ -RVf ] [ -v version ] [ mode ] files…
最关键的是在[mode]部分,[mode]部分是由+-=和[ASacDdIijsTtu]这些字符组合的,这部分是用来控制文件的属性。

  • :在原有参数设定基础上,追加参数。
  • :在原有参数设定基础上,移除参数。
    = :更新为指定参数设定。
    A:文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生。
    S:硬盘I/O同步选项,功能类似sync。
    a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性。
    c:即compresse,设定文件是否经压缩后再存储。读取时需要经过自动解压操作。
    d:即no dump,设定文件不能成为dump程序的备份目标。
    i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助。
    j:即journal,设定此参数使得当通过mount参数:data=ordered 或者 data=writeback 挂 载的文件系统,文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为 data=journal,则该参数自动失效。
    s:保密性地删除文件或目录,即硬盘空间被全部收回。
    u:与s相反,当设定为u时,数据内容其实还存在磁盘中,可以用于undeletion。
    各参数选项中常用到的是a和i。a选项强制只可添加不可删除,多用于日志系统的安全设定。而i是更为严格的安全设定,只有superuser (root) 或具有CAP_LINUX_IMMUTABLE处理能力(标识)的进程能够施加该选项。

应用举例:
1、用chattr命令防止系统中某个关键文件被修改:

1
# chattr +i /etc/resolv.conf

然后用 mv /etc/resolv.conf 等命令操作于该文件,都是得到 Operation not permitted 的结果。vim 编辑该文件时会提示 W10: Warning: Changing a readonly file 错误。要想修改此文件就要把i属性去掉:

1
2
chattr -i /etc/resolv.conf
# lsattr /etc/resolv.conf

会显示如下属性

1
----i-------- /etc/resolv.conf

2、让某个文件只能往里面追加数据,但不能删除,适用于各种日志文件:

1
# chattr +a /var/log/messages

转载自 http://www.ha97.com/5172.html

使用 aria2 搭建自己的离线下载服务器

先上两个项目的最新版下载地址:

完整操作:

1
2
3
4
5
6
wget "https://github.com/aria2/aria2/releases/download/release-1.31.0/aria2-1.31.0.tar.gz" -O aria2-1.31.0.tar.gz
tar zxvf aria2-1.31.0.tar.gz
cd aria2-1.31.0
./configure
make && make install
vi /root/aria2.conf

/root/aria2.conf 内容(更多配置项见 aria2配置示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#设置下载目录
dir=/home/wwwroot/***/downloads
disable-ipv6=true
enable-rpc=true
rpc-allow-origin-all=true
rpc-listen-all=true
#设置下载端口
rpc-listen-port=2333
#设置密码
rpc-secret=qwertyuiop1
continue=true
input-file=/root/aria2.session
save-session=/root/aria2.session
save-session-interval=60
max-concurrent-downloads=3

添加自启动:

1
echo '/usr/local/bin/aria2c --conf-path=/root/aria2.conf' >> /etc/init.d/rc.local

然后布置 web 端(基于 lnmp 1.2):

1
2
3
4
5
6
7
8
9
10
11
lnmp vhost add
cd /home/wwwroot/*** #设置下载目录
wget https://github.com/binux/yaaw/zipball/master
unzip master
mv binux-yaaw-8c8d226/* .
rm -rf binux-yaaw-8c8d226/ master
mkdir downloads
chown -R www .
chmod -R 755 .
chmod -R 777 downloads
reboot

之后打开你配置的域名,设置 JSON-RPC Path 为 http://token:你的密码@域名:端口/jsonrpc 即可

jquery事件重复绑定解决办法

  1. $.fn.live 重复绑定
    解决:使用die()方法,在live()方法绑定前,将此元素上的前面被绑定的事件统统解除,然后再通过live()方法绑定新的事件。

    1
    2
    3
    4
    //先通过die()方法解除,再通过live()绑定
    $(“#selectAll”).die().live(“click”,function(){
    //事件运行代码
    });
  2. click等事件
    解决:使用unbind(“click”)方法先解除绑定的事件再绑定新事件,即在给对象绑定事件之前先移除该对象上的原有事件
    完整测试代码:

    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
    <div class="box">
    <button id="test">重复绑定触发按钮</button>(点击此按钮两次及以上,即可触发重复绑定,再点击下面的按钮就可看到结果)
    <br/><br/>
    <button id="test1">click重复绑定测试按钮</button>
    <button id="test2">click绑定一次测试按钮</button>
    <button id="test3">live重复绑定测试按钮</button>
    <button id="test4">live绑定一次测试按钮</button>
    </div>
    <script type="text/javascript" src="../static/jquery-1.6.1.min.js"></script>
    <script type="text/javascript">
    $(function(){
    var i = 1,j=1,k=1,h=1,n=1;
    var triggerBind = function(){
    $("#test1").click(function() {
    alert("click未解除绑定重复绑定执行第" + j++ + "次");
    });
    $("#test2").unbind('click').click(function() {
    alert("click解除绑定执行" + k++ + "次");
    });

    $("#test3").live("click",function() {
    alert("live未解除绑定重复执行第" + h++ + "次");
    });
    $("#test4").die().live("click",function() {
    alert("live解除绑定后执行" + n++ + "次");
    });
    }
    $("#test").click(function() {
    triggerBind();
    alert("触发绑定点击第" + i++ + "次");
    });
    });
    </script>

转载自 http://www.cnblogs.com/heiniuhaha/archive/2011/08/07/jquery-event-repeat-bind.html

MySQL中函数CONCAT及GROUP_CONCAT

一、CONCAT()函数
CONCAT()函数用于将多个字符串连接成一个字符串。
使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为

1
2
3
4
5
+----+--------+
| id | name |
+----+--------+
| 1 | BioCyc |
+----+--------+

1、语法及使用特点:
CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。可以有一个或多个参数。

2、使用示例:
SELECT CONCAT(id, ‘,’, name) AS con FROM info LIMIT 1; 返回结果为

1
2
3
4
5
+----------+
| con |
+----------+
| 1,BioCyc |
+----------+

SELECT CONCAT(‘My’, NULL, ‘QL’); 返回结果为

1
2
3
4
5
+--------------------------+
| CONCAT('My', NULL, 'QL') |
+--------------------------+
| NULL |
+--------------------------+

3、如何指定参数之间的分隔符
使用函数CONCAT_WS()。使用语法为:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。但是CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。

SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1; 返回结果为

1
2
3
4
5
+----------+
| con_ws |
+----------+
| 1_BioCyc |
+----------+

SELECT CONCAT_WS(',','First name',NULL,'Last Name'); 返回结果为

1
2
3
4
5
+----------------------------------------------+
| CONCAT_WS(',','First name',NULL,'Last Name') |
+----------------------------------------------+
| First name,Last Name |
+----------------------------------------------+

二、GROUP_CONCAT()函数
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。
使用表info作为示例,其中语句 SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764'); 的返回结果为

1
2
3
4
5
6
7
8
+----------+----+--------------------------+
| locus | id | journal |
+----------+----+--------------------------+
| AB086827 | 1 | Unpublished |
| AB086827 | 2 | Submitted (20-JUN-2002) |
| AF040764 | 23 | Unpublished |
| AF040764 | 24 | Submitted (31-DEC-1997) |
+----------+----+--------------------------+

1、使用语法及特点:

1
2
3
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]]
[SEPARATOR str_val])

在 MySQL 中,你可以得到表达式结合体的连结值。通过使用 DISTINCT 可以排除重复值。如果希望对结果中的值进行排序,可以使用 ORDER BY 子句。
SEPARATOR 是一个字符串值,它被用于插入到结果值中。缺省为一个逗号 (“,”),可以通过指定 SEPARATOR “” 完全地移除这个分隔符。
可以通过变量 group_concat_max_len 设置一个最大的长度。在运行时执行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大长度被设置,结果值被剪切到这个最大长度。如果分组的字符过长,可以对系统参数进行设置:SET @@global.group_concat_max_len=40000;

2、使用示例:
语句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus; 的返回结果为

1
2
3
4
5
6
+----------+------------------+
| locus | GROUP_CONCAT(id) |
+----------+------------------+
| AB086827 | 1,2 |
| AF040764 | 23,24 |
+----------+------------------+

语句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回结果为

1
2
3
4
5
6
+----------+----------------------------------------------------------+
| locus | GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') |
+----------+----------------------------------------------------------+
| AB086827 | 2_1 |
| AF040764 | 24_23 |
+----------+----------------------------------------------------------+

语句 SELECT locus,GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus; 的返回结果为

1
2
3
4
5
6
+----------+--------------------------------------------------------------------------+
| locus | GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') |
+----------+--------------------------------------------------------------------------+
| AB086827 | 2, Submitted (20-JUN-2002). 1, Unpublished |
| AF040764 | 24, Submitted (31-DEC-1997) . 23, Unpublished |
+----------+--------------------------------------------------------------------------+

转载自 http://www.cnblogs.com/appleat/archive/2012/09/03/2669033.html

curl不使用文件存取cookie php使用curl获取cookie示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
/*-----保存COOKIE-----*/
$url = 'www.xxx.com'; //url地址
$post = "id=user&pwd=123456"; //POST数据
$ch = curl_init($url); //初始化
curl_setopt($ch,CURLOPT_HEADER,1); //将头文件的信息作为数据流输出
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //返回获取的输出文本流
curl_setopt($ch,CURLOPT_POSTFIELDS,$post); //发送POST数据
$content = curl_exec($ch); //执行curl并赋值给$content
preg_match('/Set-Cookie:(.*);/iU',$content,$str); //正则匹配
$cookie = $str[1]; //获得COOKIE(SESSIONID)
curl_close($ch); //关闭curl
/*-----使用COOKIE-----*/
curl_setopt($ch,CURLOPT_COOKIE,$cookie);

转载自 http://www.jb51.net/article/46222.htm

使用nsenter进入Docker容器

Docker容器运行后,如何进入容器进行操作呢?起初我是用SSH。如果只启动一个容器,用SSH还能应付,只需要将容器的22端口映射到本机的一个端口即可。当我启动了五个容器后,每个容器默认是没有配置SSH Server的,安装配置SSHD,映射容器SSH端口,实在是麻烦。
我发现很多Docker镜像都是没有安装SSHD服务的,难道有其他方法进入Docker容器?
浏览了Docker的文档,我没有找到答案。还是要求助于无所不能的Google,万能的Google告诉我用nsenter吧。
在大多数Linux发行版中,util-linux包中含有nsenter.如果没有,你需要安装它.

1
2
3
4
5
6
7
cd /tmp
curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz \
| tar -zxf-
cd util-linux-2.24
./configure --without-ncurses
make nsenter
cp nsenter /usr/local/bin

使用shell脚本 docker-enter,将如下代码保存为 docker-enter, chomod +x docker-enter

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
#!/bin/sh

if [ -e $(dirname "$0")/nsenter ]; then
# with boot2docker, nsenter is not in the PATH but it is in the same folder
NSENTER=$(dirname "$0")/nsenter
else
NSENTER=nsenter
fi

if [ -z "$1" ]; then
echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]"
echo ""
echo "Enters the Docker CONTAINER and executes the specified COMMAND."
echo "If COMMAND is not specified, runs an interactive shell in CONTAINER."
else
PID=$(docker inspect --format "{{.State.Pid}}" "$1")
if [ -z "$PID" ]; then
exit 1
fi
shift

OPTS="--target $PID --mount --uts --ipc --net --pid --"

if [ -z "$1" ]; then
# No command given.
# Use su to clear all host environment variables except for TERM,
# initialize the environment variables HOME, SHELL, USER, LOGNAME, PATH,
# and start a login shell.
"$NSENTER" $OPTS su - root
else
# Use env to clear all host environment variables.
"$NSENTER" $OPTS env --ignore-environment -- "$@"
fi
fi

运行 docker-enter ,这样就进入到指定的容器中

关于nsenter更详细的使用方法见这里 https://github.com/jpetazzo/nsenter

转载自 http://www.tuicool.com/articles/eYnUBrR

希腊神话(人物名字)和他们的强弱排名

前段时间,蜻蜓 FM 数据造假事件闹得沸沸扬扬(如何评价蜻蜓 FM 伪造用户活跃度等数据?),其中的命名方式颇有新意,于是找了以下这篇文章,实在想不出临时变量名的可以用这来代替:

在希腊神话中,一切皆从混沌(Chaos)开始。。。
下面是希腊神话的十二主神:

(1)宙斯(zeus):
★宙斯是克洛诺斯之子,万神之王,主管天空.希腊神话中的至高神,掌握雷电,所以又被称为雷神。在母亲蕾亚的支持下,杀了父亲克洛诺斯,成为了第三代神王。性格极为好色,常背着妻子赫拉与其他女神 和凡人私通,私生子无数。
★宙斯的象征物是雄鹰、橡树和山峰;他最爱的祭品是母山羊和牛角涂成金色的白色公牛。
★发迹史
宙斯出生时,正值他父亲克洛诺斯当权,母亲瑞亚害怕宙斯被其父吞掉【注:由于某些原因, 克洛诺斯不能让他的子女生存】,因此将他藏到克里特岛交给三位女仙抚养——在岛上,一只母山羊为他提供神圣的乳汁,一只雄鹰则给他带来仙酒;每当他哭叫时,瑞亚的仆人们就到摇篮边为宙斯跳舞, 并用短剑敲击铜盾掩盖他的哭声,因此克洛诺斯一直未发现这一秘密。
宙斯在岛上一天天茁壮成长。一天,他和母山羊玩耍时不小心推倒了她,摔断了一支美丽的羊角。仙女阿玛尔忒亚赶忙为她治伤,宙斯则拾起这只羊角,赋予它神奇的魔力,并将它赠给了这名善良的仙女。这只羊角从此被称为“丰饶之角”,因它能出产各种美味的食物。
宙斯成年之后,用计救出了被父亲吞下的五个兄弟姐妹,并合力推翻了克洛诺斯,最后登上王位。
(发帖时间:2004-7-10 21:44:49)

(2)天后赫拉(Hera):
★赫拉是克洛诺斯之女,宙斯的姐姐和妻子;她主管婚姻和生育,是妇女的保护神;赫拉气质高雅, 容颜美丽,且对伴侣忠贞不渝,无愧于天后的地位,但她的善妒亦闻名于世,因此,赫拉和宙斯经常发生激烈争吵,不过,通常宙斯的花言巧语又总能让他们和好如初.
★赫拉的象征是孔雀,因为这种有着五彩缤纷羽毛、体现着满心星斗的鸟是美丽壮观的夜空的象征,而天空正是天后赫拉光彩照人的脸庞。

(3)海神波塞冬(Poseidon):
★ 海之皇,宙斯的二哥,手持巨大三叉戟,统领海中所有生物。有被描写为半人半鱼的模样,能呼风唤雨。性格凶暴残忍。
★ 马和牛是他的圣物.

(4)冥王哈帝斯(hades):
★宙斯,波塞冬,得墨忒尔的兄长,主管冥界,力量很强,但性格平和。除了抢夺丰收女神得墨忒尔之女春之女神玻尔塞富涅为妻外,无它恶行。
★最喜爱黑色,最爱的祭品是全身裹着黑纱的黑母羊或黑公牛。
★冥府简介
人们死后,由引导之神赫尔墨斯将他们接到冥界。在这里,汹涌奔流着一条黑色的大河,阿刻戎河——即痛苦之河。大河阻住前进的道路,只有一个满面胡须的船夫卡隆可以将亡灵们摆渡到对岸。但是,亡灵必须交纳一定的过河费方可上船,否则将在痛苦之河的沿岸流浪,找不到归宿。
过河之后是一片广阔的灰色平原,这里叫做真理田园,此处连接着两条路,分别通往幸福之所——爱丽舍乐园和痛苦之所——地狱。亡灵们在真理田园前的审判台前接受冥界三大判官弥诺斯、剌达曼达斯和埃阿科斯的审判。有罪之人根据他们的罪行在地狱接受轻重不一的惩罚, 而那些无罪的人们将可以在美丽祥和的爱丽舍乐园过着衣食无忧、吟风弄月的幸福生活。
在爱丽舍乐园和地狱之间,建造着一座雄伟庞大的宫殿,这就是冥王哈得斯和冥后珀耳塞福涅的住所

(5)灶神赫斯提亚(Hestia):
她是宙斯的姐姐,掌万民的家事。三位处女神明之一。在希腊神话中,并没有显著的个性。她是位贞洁处女女神。

(6)战神阿瑞斯(Ares):
★ 战神,是凶残,狡诈,非理性的,为战争而战争的神。曾与工匠之神的妻子爱与美之神阿佛洛狄忒私通,被装进一张工匠之神特制的大网中而无法脱身。(维纳斯原为罗马神诋,后为希腊神话所吸收。)
★ 兀鹰是他的圣鸟,宠兽是狗狗.

(7)智慧女神雅典娜(Athene):
★智慧女神和正义战争女神,是宙斯与女泰坦美狄斯的女儿,她是智慧女神兼和平女神(或称女战神),她勇敢、强大而又善良、仁慈,不过有时略有些小心眼,不愿别人比她强.她出生时宙斯头部剧烈疼痛,之后用大斧劈开后,雅典娜手持长枪,身披战甲从中跳出。是很受欢迎的神。因失手杀死好友帕拉斯而改名为帕拉斯·雅典娜。
★眼睛在夜里发亮的猫头鹰,还有公鸡和毒蛇, 对于眸子明亮的女神雅典娜来说,均为她的象征。

(8)神使(偷窥之神)赫耳墨斯(Hermes):
★ 宙斯与阿特拉斯的女儿迈亚所生的儿子。脚生双翼,速度如飞,成为天界众神传令的使者,后为旅人,商人,盗贼的保护神,经常化为凡人下界帮助保护者.是最聪明狡猾的神.
★ 他动作敏捷幽雅,脚穿带翼凉鞋,头戴有翅膀的低冠帽,手握双蛇盘绕的魔仗。

(9)火神赫淮斯托斯(Hephaestus):
宙斯和赫拉之子。长的奇丑,坡足,是美丽神界的一大败笔!可人虽长的丑,却很温柔,热爱和平,是天庭人间都很受欢迎。

(10)太阳神阿波罗(Apollo):
★ 太阳神,宙斯和勒托之子,月神和狩猎女神阿尔忒弥斯的兄长,希腊十二大神诋之一,又名赫利俄斯。主掌光明,医药,文学,诗歌,音乐等。每天架天马拉乘的的黄金车巡游天上一周。
★ 月桂树是他的圣木,最喜欢的宠物是海豚和乌鸦.

(11)爱与美之神阿佛洛狄忒Aphrodite):
★ 爱情女神,宙斯与迪俄涅的女儿。 她的甜言蜜语能骗倒所有神和人。她很爱笑,魅力无边,智者也会乱了分寸。
★ 桃金娘是她的圣树,鸽子是她的爱鸟。天鹅和麻雀也很受宠。

(12)月亮女神阿耳忒弥斯(Artemis):
★ 阿尔特弥斯是阿波罗的孪生姐妹,三位处女神明之一。月神,狩猎女神,纯洁之神。所以也被称为处女的保护神。她是野生物的主人,神界的主要猎手。身为三体女神的她,在空中是西伦,地上是阿尔特弥斯,阴间和黑暗阳间是海卡蒂。
★丝柏是她的圣木,鹿是她最喜欢的宠兽。

【希腊神话中的其他神位及其职务】
帕尔塞福涅(Persephone) 冥后,宙斯和得墨忒尔的女儿。
狄俄尼索斯(Dionysus) 酒神,宙斯和塞墨勒的儿子。
阿尔忒尼斯(Artemis) 月亮和狩猎女神,宙斯和勒托之女。
赫淮斯托斯(Hephaestus) 火神,宙斯和赫拉之子。
赫尔墨斯(Hermes) 宙斯和迈亚的儿子,众神的使者,亡灵的接引神。
厄俄斯(Eos) 黎明女神
艾莉斯(Eris) 纷争女神
厄洛斯(Eros) 爱神
耐得斯(Naiads) 江河水泉中的女神
卡吕普索(Calypso) 女神
西摩伊斯(Simois) 河神
阿科洛厄斯(Achelous) 河神
阿克西厄斯(Axius) 派厄尼亚河神
格劳克斯(Glaucus) 海神,善作预言
特里同(Triton) 海神
琉科忒亚(Leucothea) 海中女神
涅锐伊得斯(Nereids) 海中女神
该亚(Gaea) 地之女神
塞勒涅(Selene) 月亮女神
塔那托斯(Thanatus) 死神
许普诺斯(Sleep) 睡神
赫卡忒(hecate) 夜和下界女神,亦是幽灵和魔法女神
绪任克斯(Syrinx) 山林女神
潘(Pan) 山林之神
时序三女神 欧诺尼亚(秩序)、狄克(公正)、厄瑞涅(和平)
命运三女神 克洛托(纺织生命之线)、拉克西斯(决定生命之线的长短)、阿特洛波斯(切断生命之线)
美惠三女神 欧佛洛绪涅、塔利亚、阿洛来亚
复仇三女神 总称为厄利尼厄斯

强弱排名
宙斯(Zeus) 天神,希腊神话中最高的神,克洛诺斯和瑞亚的儿子。
赫拉(Hera) 天后,克洛诺斯和瑞亚的长女,宙斯的姐姐和妻子。
哈迪斯(Hades) 冥王,克洛诺斯和瑞亚的儿子,宙斯的兄弟。
帕尔塞福涅(Persephone) 冥后,宙斯和得墨忒尔的女儿。
波塞冬(Poseidon) 海皇,克洛诺斯和瑞亚的儿子,宙斯的兄弟。

雅典娜(Athene) 智慧女神,女战神,从宙斯的头颅中诞生。
阿波罗(Apollo) 太阳神,宙斯和勒托之子。
阿瑞斯(Ares) 战神,宙斯和赫拉之子。
阿佛洛狄忒(Aphrodite) 爱情女神,宙斯与迪俄涅的女儿。
狄俄尼索斯(Dionysus) 酒神,宙斯和塞墨勒的儿子。
阿尔忒尼斯(Artemis) 月亮和狩猎女神,宙斯和勒托之女。
赫淮斯托斯(Hephaestus) 火神,宙斯和赫拉之子。
赫尔墨斯(Hermes) 宙斯和迈亚的儿子,众神的使者,亡灵的接引神。

厄俄斯(Eos) 黎明女神
艾莉斯(Eris) 纷争女神
厄洛斯(Eros) 爱神
耐得斯(Naiads) 江河水泉中的女神
卡吕普索(Calypso) 女神
西摩伊斯(Simois) 河神
阿科洛厄斯(Achelous) 河神
阿克西厄斯(Axius) 派厄尼亚河神
格劳克斯(Glaucus) 海神,善作预言
特里同(Triton) 海神
琉科忒亚(Leucothea) 海中女神
涅锐伊得斯(Nereids) 海中女神
该亚(Gaea) 地之女神
塞勒涅(Selene) 月亮女神
塔那托斯(Thanatus) 死神
许普诺斯(Sleep) 睡神
赫卡忒(Hecaba) 夜和下界女神,亦是幽灵和魔法女神
绪任克斯(Syrinx) 山林女神
潘(Pan) 山林之神

时序三女神 欧诺尼亚(秩序)、狄克(公正)、厄瑞涅(和平)
命运三女神 克洛托(纺织生命之线)、拉克西斯(决定生命之线的长短)、阿特洛波斯(切断生命之线)
美惠三女神 欧佛洛绪涅、塔利亚、阿洛来亚
复仇三女神 总称为厄利尼厄斯

转载自 http://blog.sina.com.cn/s/blog_490d277f01000407.html

识别真假搜索引擎(搜索蜘蛛)方法(baidu,google,Msn,sogou,soso等)

最近工作中遇到个问题,就是有一些资源,不希望别人很派发的抓取,这样会占用我们带宽还有资源。因此,我们对页面访问做了频率限制。这样一来,又怕搜索蜘蛛给限制了。 因此,我们有个需求,就是除了常见搜索蜘蛛,其它都要做频率限制。 工作就变成了,首先我们怎么样正确表示搜索蜘蛛。

怎么样识别搜索蜘蛛
搜索引擎基本上由最先google,和国内的baidu统一了。刚开始比较混乱,后期有很多规则协议,可以遵循。基本上一些新兴的搜索引擎在访问站点时候,都会延用google制定的一些规则。它们一般都会有特定的user-agent,但是,如果我们只通过user-agent去识别搜索蜘蛛的话,那样第三方抓取程序,都会去伪造个user-agent。变成搜索蜘蛛的,如:Googlebot/2.1 (+http://www.googlebot.com/bot.html) %C2%A0)是,google蜘蛛的值。

现在一般搜索引擎都提供一个DNS 反向IP查询功能,只需要把访问来的IP 通过反向查询域名,看是不是搜索引擎域名。这样伪造的爬虫工具,就会被很容易识别了。 具体识别真假蜘蛛只需要:1,判断user-agent是否满足蜘蛛格式 2,然后进一步确定IP 反解析域名是否属于该搜索引擎域名.

搜索引擎 user-agent(包含) 是否PTR 备注
google Googlebot host ip 得到域名:googlebot.com主域名
baidu Baiduspider host ip 得到域名:.baidu.com 或 .baidu.jp
yahoo Yahoo! host ip 得到域名:inktomisearch.com主域名
Sogou Sogou × Sogou web spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07″)
Sogou Push Spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07″)
网易 YodaoBot × *Mozilla/5.0 (compatible; YodaoBot/1.0; http://www.yodao.com/help/webmaster/spider/”; )
MSN MSNBot host ip 得到域名:live.com主域名
360 360Spider × Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.0.11) Firefox/1.5.0.11; 360Spider
soso Sosospider × Sosospider+(+http://help.soso.com/webspider.htm)
bing bingbot host ip 得到域名:msn.com主域名

以上是我整理一些常用搜索引擎的user-agent特征码,以及IP反向解析情况。保证准确识别搜索引擎,我们通过IP反解析是最为准确方法。好在google,baidu,bing都有做反向解析。基本上占用了80%搜索市场了。下面,我是我检测方法。

PHP反解析IP方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function check_spider($ip,$ua) {
static $spider_list=array(
'google'=>array('Googlebot','googlebot.com'),
'baidu'=>array('Baiduspider','.baidu.'),
'yahoo'=>array('Yahoo!','inktomisearch.com'),
'msn'=>array('MSNBot','live.com'),
'bing'=>array('bingbot','msn.com')
);

if(!preg_match('/^(\d{1,3}\.){3}\d{1,3}$/',$ip)) return false;
if(empty($ua)) return false;

foreach ($spider_list as $k=>$v) {
if(stripos($ua,$v[0])!==false) {
$domain = gethostbyaddr($ip);

if($domain && stripos($domain,$v[1])!==false) {
return $k;
}
}
}
return false;
}

目前只加入几个搜索引擎检测,这些是可以做反解析查询的。不能做反解析查询的,最好做速度限制,用户会使用它们来伪造搜索引擎来抓取你的资源。欢迎大家交流,先写到这里了。

转载自 http://blog.chacuo.net/147.html

将 func uc_authcode 翻译成了 node 版,留备用

原版 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
function uc_authcode($str, $operation = 'DECODE', $key = '', $expiry = 0) {

$ckey_length = 4;

$key = md5($key);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($str, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);

$str = $operation == 'DECODE' ? base64_decode(substr($str, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($str.$keyb), 0, 16).$str;
$str_length = strlen($str);

$result = '';
$box = range(0, 255);

$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}

for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $str_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($str[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc.str_replace('=', '', base64_encode($result));
}
}

node:

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
var Buffer = require("buffer").Buffer;
var crypto = require("crypto");

String.prototype.md5=function () {
return crypto.createHash("md5").update(this.toString(),'utf8').digest("hex");
}

var microtime=function() {
var d=new Date();
return (d.getMilliseconds()/1000).toFixed(8)+" "+Math.floor(d.getTime()/1000);
}

var uc_authcode=function(str,operation,key,expiry) {

var operation=operation || 'DECODE';
var key=key?key.md5():'d41d8cd98f00b204e9800998ecf8427e';
var expiry=expiry?expiry:0;

var ckey_length=4;
var keya=key.substr(0,16).md5();
var keyb=key.substr(16,16).md5();
var keyc=ckey_length ? (operation === 'DECODE' ? str.substr(0, ckey_length): microtime().md5().substr(-ckey_length)) : '';

var cryptkey=keya+(keya+keyc).md5();
var key_length=cryptkey.length;
str = (operation === 'DECODE' ? new Buffer(str.substr(ckey_length),'base64') : (("000000000"+( expiry ? parseInt(expiry) + Math.floor(new Date().getTime()/1000) : 0)).substr(-10)+(str+keyb).md5().substr(0, 16)+str));
var str_length=str.length;

var box=[];
for (var i=0;i<256;i++) {
box[i]=i;
}
var rndkey=[];
for (var i = 0; i <= 255; i++) {
rndkey[i]=cryptkey[i % key_length].charCodeAt();
}


for (var j=i=0;i<256;i++) {
j = (j + box[i] + rndkey[i]) % 256;
tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}

var result = new Buffer(str_length);
for (var a = j = i = 0; i < str_length; i++) {
a = (a + 1) % 256;
j = (j + box[a]) % 256;
tmp = box[a];
box[a] = box[j];
box[j] = tmp;
var charcode = operation === 'DECODE' ? str[i] ^ (box[(box[a] + box[j]) % 256]) : str[i].charCodeAt() ^ (box[(box[a] + box[j]) % 256]);
result[i] = charcode;
}



if (operation === 'DECODE') {
result = result.toString();
if ((parseInt(result.substr(0, 10)) === 0 || parseInt(result.substr(0, 10)) - Math.floor(new Date().getTime()/1000) > 0) && result.substr(10, 16) == (result.substr(26)+keyb).md5().substr(0, 16)) {
return result.substr(26);
} else {
return '';
}
} else {
return (keyc+result.toString("base64").replace(/=/g,""));
}
};

console.log(uc_authcode("aaaaaa", 'ENCODE', 'testkey'));
console.log(uc_authcode("950ewo3CtcO9wrzCpsKBwrnChQbCgcOPwrJCe1Jow5LCnzJawrvCvcOzwpXDn8OqZcKFwpA8w7LCqg", 'DECODE', 'testkey'));

另附一个前端用的:js版uc_authcode例子,by zhengshuiguang

mysql按照网段分类IP

数据库里面取出来是IP地址,需要用sql来给IP段地址分类

1
SELECT INET_NTOA(CONVERT(INET_ATON('192.168.35.11'),SIGNED)&0xFFFFFF00) AS tt

QQ图片20151216223458

命令解释:

  1. inet_aton(‘192.168.35.11’)这个函数是将IP地址转化为一个序列.
  1. convert是将序列类型定义成整数.
  1. &0xFFFFFF00的意思是与FFFFFF00这个16进制数进行与操作.这步操作相当于掩码.可以过滤网段.
  1. inet_ntoa这个函数是将整理好的序列转化成IP地址的形式.

转载自 http://blog.csdn.net/a105421548/article/details/45224843