Python多线程生产者消费者模式
1 | from Queue import Queue |
1 | from Queue import Queue |
apache日志分析可以获得很多有用的信息,现在来试试最基本的,获取最多访问的前10个IP地址及访问次数。
既然是统计,那么awk是必不可少的,好用而高效。
命令如下:
awk '{a[$1] += 1;} END {for (i in a) printf("%d %s\n", a[i], i);}' 日志文件 | sort -n | tail
首先用awk统计出来一个列表,然后用sort进行排序,最后用tail取最后的10个。
以上参数可以略作修改显示更多的数据,比如将tail加上-n参数等,另外日志格式不同命令也可能需要稍作修改。
当前WEB服务器中联接次数最多的ip地址
1 | #netstat -ntu |awk '{print $5}' |sort | uniq -c| sort -nr |
查看日志中访问次数最多的前10个IP
1 | #cat access_log |cut -d ' ' -f 1 |sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 |less |
查看日志中出现100次以上的IP
1 | #cat access_log |cut -d ' ' -f 1 |sort |uniq -c | awk '{if ($1 > 100) print $0}'|sort -nr |less |
查看最近访问量最高的文件
1 | #cat access_log |tail -10000|awk '{print $7}'|sort|uniq -c|sort -nr|less |
查看日志中访问超过100次的页面
1 | #cat access_log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less |
统计某url,一天的访问次数
1 | #cat access_log|grep '12/Aug/2009'|grep '/images/index/e1.gif'|wc|awk '{print $1}' |
前五天的访问次数最多的网页
1 | #cat access_log|awk '{print $7}'|uniq -c |sort -n -r|head -20 |
从日志里查看该ip在干嘛
1 | #cat access_log | grep 218.66.36.119| awk '{print $1"\t"$7}' | sort | uniq -c | sort -nr | less |
列出传输时间超过 30 秒的文件
1 | #cat access_log|awk '($NF > 30){print $7}' |sort -n|uniq -c|sort -nr|head -20 |
列出最最耗时的页面(超过60秒的)
1 | #cat access_log |awk '($NF > 60 && $7~/\.php/){print $7}' |sort -n|uniq -c|sort -nr|head -100 |
纯文本验证码、图形验证码、声音验证码、JS验证码,以下主要讲简单的图形验证码的识别。
在破解验证码中需要用到的知识一般是 像素,线,面等基本2维图形元素的处理和色差分析。常见工具为:
识别验证码需要充分利用图片中的信息,才能把验证码的文字和背景部分分离,一张典型的jpeg图片,每个像素都可以放在一个5维的空间里,这5个维度分别是,X,Y,R,G,B,也就是像素的坐标和颜色,在计算机图形学中,有很多种色彩空间,最常用的比如RGB,印刷用的CYMK,还有比较少见的HSL或者HSV,每种色彩空间的维度都不一样,但是可以通过公式互相转换。

RGB色彩空间构成的立方体,每个维度代表一种颜色

HSL(色相饱和度)色彩空间构成的锥体,可以参考:
https://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4
HSL和HSV都是一种将RGB色彩模型中的点在圆柱坐标系中的表示法。这两种表示法试图做到比RGB基于笛卡尔坐标系的几何结构更加直观。
HSL即色相、饱和度、亮度(英语:Hue, Saturation, Lightness),又称HSL。HSV即色相、饱和度、明度(英语:Hue, Saturation, Value),又称HSB,其中B即英语:Brightness。
了解到色彩空间的原理,就可以用在该空间适用的公式来进行像素的色差判断,比如RGB空间里判断两个点的色差可以用3维空间中两坐标求距离的公式:
distance=sqrt[(r1-r2)^2+(g1-g2)^2+(b1-b2)^2]
更加直观的图片,大家感受一下:

随便把一张图片的每个像素都映射到RGB色彩空间里就能获得一个这样的立方体。
通过对像素颜色进行统计和区分,可以获得图片的颜色分布,在验证码中,一般来说使用近似颜色最多的像素都是背景,最少的一般为干扰点,干扰线和需要识别文字本身。
所谓二值化就是把不需要的信息通通去除,比如背景,干扰线,干扰像素等等,只剩下需要识别的文字,让图片变成2进制点阵。

为了能识别出字符,需要对要识别的文字图图片进行分割,把每个字符作为单独的一个图片看待。

对于部分特殊的验证码,需要对分割后的图片进行标准化处理,也就是说尽量把每个相同的字符都变成一样的格式,减少随机的程度
最简单的比如旋转还原,复杂点的比如扭曲还原等等
这一步可以用很多种方法,最简单的就是模板对比,对每个出现过的字符进行处理后把点阵变成字符串,标明是什么字符后,通过字符串对比来判断相似度。
在文章的后半部分会详细解释每步的各种算法

直方图

这是一张图像的亮度(Luminosity)+RGB三通道的直方图。
直方图的观看规则就是“左黑右白”,左边代表暗部,右边代表亮部,而中间则代表中间调。亮度从0–255,0表示黑,255表示白。如果某个地方的峰越高,表示在这个亮度下的像素越多。这个相片的直方图说明图片整体是偏亮的。
纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多。


先建立一个图像中的颜色直方图,通过把所有像素按颜色分组实现

1 | from PIL import Image |
输出
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0
, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 0, 1, 0, 0, 1,
0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 1, 3, 3, 0,
0, 0, 0, 0, 0, 1, 0, 3, 2, 132, 1, 1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0
, 1, 0, 1, 0, 0, 8, 1, 0, 0, 0, 0, 1, 6, 0, 2, 0, 0, 0, 0, 18, 1, 1, 1, 1, 1, 2,
365, 115, 0, 1, 0, 0, 0, 135, 186, 0, 0, 1, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 21,
1, 1, 0, 0, 0, 2, 10, 2, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 1, 0, 625]
1 | from PIL import Image |
1 | 255 625 |
第一列是颜色的ID,第二列是相对应的颜色的数量,图片中可见白色最多,其次是灰色和红色
上面显示一共有10个颜色在这个图片中,红色应该是第三个常见颜色220,但是上面中227与220非常接近,把它也包含进去。这张图中220 与227应该是红色部分,也就是我们想保留的验证码部分,其它颜色可以去掉, 创建一个新的二色图像,只有白黑。
1 | from PIL import Image |

上面这个黑白图片便是我们成功提取到的只有字母数字的图像,正是我们需要的,如果图片中的验证码是多个颜色,判断上面会相应复杂一些。
1 | for each binary image: |
1 | #!/usr/bin/env python |

主要代码
1 | from PIL import Image |
1 | [(6, 14), (15, 25), (27, 35), (37, 46), (48, 56), (57, 67)] |
这些是每个字符在图片水平方向的开始位置与结束位置,如果验证码的每个字符的位置是固定的就不需要上面这种方法,可以直接指定。
1 | #!/usr/bin/env python |
接下来需要比对每个字符与模板的相似度,我们使用一种最简单的方法。但前提是我们需要生成比对的模板匹配库,可以通过以下代码生成。
1 | # New code is here. We just extract each image and save it to disk with |
上面的代码会在同一目录下生成一组图像组合,每个图像都是切割出来的单个字符,每个图像都有一个唯一的哈希值命名,你可以选择你需要的字符集。

从这些字模之中,每个数字或字母,我们只需要一个看上去比较标准的就够了。

上面是我生成的模板。
为了实现匹配库,需要批量下载一些验证码。
1 | import sys, base64 |
1 | import os, Image |
1 | #!/usr/bin/env python |

● 用户体验不高,故意对用户复杂但对机器不一定复杂
● 容易被枚举,题库太弱,毕竟是人采集的图片,总有上限,不如字符组合可能性多
● 破解门槛不一定高于字符型Captcha
● 任何的验证码都抵不过分布式人工打码方案
先看下网上有人试图破解的


验证码(CAPTCHA)或者叫做全自动区分计算机和人类的图灵测试(Completely Automated Public Turing test to tell Computers and Humans Apart),使我们上网的人每天都可以见到的,而它的作用除了防止垃圾注册或者评论以外还有别的吗?来自Google的reCAPTCHA(上图)告诉我们,你其实还可以为人类做贡献。
如果我们想电子化一些从前的文档,比如 19 世纪的纽约时报,我们要不得依靠人力,手动地一个一个字地输入电脑,要不然就直接扫描,然后用软件识别。但是软件识别的准确率不能保证,尤其是扫描或者文档本身质量很差的时候,比如:

reCAPTCHA 做的,简单来说就是把上图的单词切割抽取出来,然后与一组自动生成的字符混合,生成验证码,发送到各各网站上,像这样:

reCAPTCHA 默认如果电脑产生的字符你输入正确,那么从文档中抽取的字符你的输入也将是正确的,然后通过交叉验证,重复验证,各种算法保证准确率。于是坐在电脑前上网的我们,每次输入验证码的时候,就可能顺便为某个图书馆的文档录入做出了贡献。详细点的介绍可看:关于 reCAPTCHA 验证码 。
一个经常被提到的实例就是,借助广大网民之手,纽约时报从 1851 年到现在的所有报纸,总共超过 1 千 3 百万篇文章都已经成功录入计算机。如果依靠手工输入,人力,资金,时间都将是巨大的,然而借助 reCAPTCHA, 以及每天上网的我们,这项工作短时间内已经完成了。
09 年 reCAPTCHA 被谷歌收购了,大家可能也都注意到了,谷歌更进一步利用验证码来帮助它们识别门牌号,路牌等等,用来修正谷歌地图的精度。这样谷歌地图的准确度,以及用户的体验都得到了提升。


尽管验证码在阻止垃圾邮件发送者和数字化传统文本方面非常有效,但是也有局限性。验证码没有音频选项,无法让视障人群进入被保护网站。没有视力问题的用户也抱怨,因为有些文字太难认。四年前,斯坦福大学的一群研究者收集了 30 多万个谷歌、雅虎和微软使用过的验证码,进行了一项研究。研究者在
caption-bypass.com 和亚马逊土耳其机器人系统让用户辨别验证码。研究人员向三个不同的人展示验证码,但是他们都同意正确答案的几率只有 71%。
另一个问题是利用多种多样的算法验证码也能遭到破解。今年早些时候,谷歌街景和 reCAPTCHA 团队的成员发表了一篇论文,论文内容是他们用于破解自家的验证码的一种算法。谷歌在一篇博文中表示:「我们最近的研究说明,现在的人工智能技术能以 99.8% 的正确率识别最扭曲最有难度的验证码文字。因此扭曲文字不再是一种可靠的测试方法了。」验证码还有很大的改进空间。因此诞生了 No CAPTCHA reCAPTCHA。
谷歌最近发布了一种新的应用程序界面(API),叫做 No CAPTCHA reCAPTCHA,它大大简化了判断用户是人类与否的步骤。通过 No CAPTCHA reCAPTCHA,用户只需要简单的点击「我不是机器人」这句话边上的复选框就可以确定他们是人类了。No CAPTCHA reCAPTCHA 已经整合到了 WordPress,Snapchat 和 Humble Bundle 等服务中了。No CAPTCHA ReCAPTCHA 可能看起来更容易被垃圾邮件发送者破解,但是谷歌开发了一套复杂的高级风险分析后端在决定用户是人类的过程中分析用户参与识别的情况。

大多数用户可能很容易就点击复选框然后继续了,但是可疑的人类或者机器人可能会强制回答电脑屏幕上的验证码或者移动设备上的动物配对测试:

http://drops.wooyun.org/tips/141
http://blog.csdn.net/shuifa2008/article/details/45692823
http://xiaoxia.org/2011/05/31/boring-entry-the-fabled-verification-code-recognition-technology-learning-notes/
http://www.codeproject.com/Articles/106583/Handwriting-Recognition-Revisited-Kernel-Support-V
首先,在/etc/my.cnf中,找到[mysqld],添加一行:
skip-grant-tables
重启MySQL:
/etc/init.d/mysql restart
进入MySQL的命令行,并依次执行如下命令:
1 | mysql> use mysql; |
其中的newpwd是更改后的新密码,需要用户重新指定。
重新打开/etc/my.cnf,将刚才修改的地方改回初始状态。
再次重启MySQL:/etc/init.d/mysql restart
When adding new virtual hosts in your nginx configuration file, you can experience this error message:
1 | # nginx -t |
server_names_hash_bucket_size controls the maximum length of a virtual host entry (ie the length of the domain name).
In other words, if your domain names are long, increase this parameter.
You need to add this flag in the _http_ context:
1 | http { |
After increasing the value, test your configuration file and reload nginx:
1 | # nginx -t |
1 | RewriteEngine on |
impressjs就是仿照prezi,它可以实现比较炫的PPT效果,不同于一般的PPT,它的展示更好看。
如果你想展示一些效果,类似于PPT的,可以使用它。
Impress JS 介绍
ImpressJS 的github地址为 https://github.com/impress/impress.js
Windows本身命令行支持配置端口映射,条件是已经安装了IPV6,启不启用都无所谓,我在win7和server2008上是可以的。xp,2003装了ipv6协议也是可以的。
CMD下操作
增加端口映射,将10.10.10.10的11111映射到10.10.10.11的80端口
1 | netsh interface portproxy add v4tov4 listenport=11111 listenaddress=10.10.10.10 connectport=80 connectaddress=10.10.10.11 |
删除端口映射
1 | netsh interface portproxy del v4tov4 listenport=11111 listenaddress=10.10.10.10 |
查看已存在的端口映射
1 | netsh interface portproxy show v4tov4 |
可以通过命令 netstat -ano|find “11111” 查看端口是否已在监听
1 | telnet 10.10.10.10 11111 测试端口是否连通 |
首先在命令行下输入 python 以查看你的python版本,默认应该是2.6以上的,比如我的是2.7
安装python3.4之前建议先安装以下软件包:
1 | yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make |
其中sqlite-devel如果不安装,python3.4安装后sqlalchemy会有些问题,比如import sqlite3会有问题。
1 | wget https://www.python.org/ftp/python/3.4.2/Python-3.4.2.tgz |
安装完之后可以在/usr/local/src/python3.4/bin 目录下看到python3.4
1 | mv /usr/bin/python /usr/bin/python.bak |
然后在命令行下输入 python 查看下版本,如果是3.4.2就正常了
安装好python3后,yum无法使用了,解决办法
按照提示编辑/usr/bin/yum文件,把开头的/usr/bin/python 改为 /usr/bin/python2
这主要是因为yum使用的还是python2的代码,所以需要注明使用哪个python版本
编辑 ~/.bash_profile,将:
1 | PATH=$PATH:$HOME/bin |
改为:
1 | PATH=$PATH:$HOME/bin:/usr/local/python34/bin |
使 python3.4 环境变量生效:
1 | . ~/.bash_profile |
1 | [root@leadscloud]# yum install tmux |
修改 /usr/libexec/urlgrabber-ext-down, 同样把 /usr/bin/python 和前面一样改为python2 /usr/bin/python2
升级后 还有一个问题,gnome-tweak-tool 也就是优化工具打不开
1 | [root@leadscloud]# whereis yum-config-manager |
vim /usr/bin/yum-config-manager , 解决方法同上,修改为python2即可。
我们来玩个找茬儿,看看下面这段代码,找找 md5 函数的定义在哪里:
1 | <!DOCTYPE html> |
太棒了,我知道难不倒你,10 秒钟就找出来了是不是?好吧,可能我举了一个不是很好的例子,因为它一点用处都没有。
标题里的“短”字加了引号,只是因为它看起来短,实际并不短,因为字节还是在的,在 unicode 里有一种神奇的字符叫零宽空白,它的特点是字型的显示宽度为 0,无论堆了多少个零宽字符,你都看不见它。
就像上面我写的例子中,Function("<这里>".repla... 藏了大量的零宽字符,实际看起来就好像是一个空字符串 "",这个“空”字串即是 md5 的函数定义经过编码转换后得到的全零宽字符串,此创意最初源自一个叫 z.js 的库。
每个字符都有一个唯一的编码,将编码以 2 进制表示得到 01.. 的字串,把 1 替换成 U+200C,把 0 替换成 U+200D 就得到一个全零宽空白的字符串,每 8 位零宽字符可用于表示 1 个 ascii 字符,所以例子当中,理论上是变长的,不算解码程序的 129 个字符,仅空白就占了原文 8 倍的体积,如果出现中文,那就更不止了,因为中文已经超过了 ascii 的范围,需要先转成纯 ascii (如以 \uxxxx 表示)后再处理。
在 unicode 里,至少有 U+200B, U+200C, U+200D 和 U+FEFF 四个零宽字符,如果把这 4 个字符全用上,上面的例子又可以减少 1 半的体积,感兴趣的同学自己折腾下。
最后,隐藏代码是不科学的,零宽字符有其它更多更有意义的使用场景,比如用于本地存贮的敏感数据等,游戏里面应该会有需求,就看你的发挥了。
附上一时心血来潮写的 Code Hider v0.1alpha。