使用Python Crypto.Cipher 测试AES 加密速度

Crypto 提供AES 加/解密。有几点需要注意:

  1. 密钥key 长度必须为16(AES-128),24(AES-192),或者32 (AES-256)Bytes 长度
  2. 每次使用encrypt( ) 方法加密的内容必须为16 Bytes 长度
  3. Crypto AES加密模式有ECB/CBC/CFB 等模式,ECB 不需要使用iv 参数,CBC 等链式模式需要iv 参数
  4. ECB 是最简单的分块加密方式,CBC 当前加密结果和之前所有加密块都有关系,抗频率分析
  5. iv 是用于链式加密的参数,加密时长度必须等于AES.block_size,解密时长度为block_size+2 Bytes

继续阅读

Python 之ConfigParser

一、ConfigParser简介

ConfigParser 是用来读取配置文件的包。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。

   1: [db]

   2: db_host = 127.0.0.1

   3: db_port = 22

   4: db_user = root

   5: db_pass = rootroot

   6:  

   7: [concurrent]

   8: thread = 10

   9: processor = 20

中括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。

 

二、ConfigParser 初始工作

使用ConfigParser 首选需要初始化实例,并读取配置文件:

   1: cf = ConfigParser.ConfigParser()

   2: cf.read("配置文件名")

 

三、ConfigParser 常用方法

1. 获取所有sections。也就是将配置文件中所有“[ ]”读取到列表中:

   1: s = cf.sections()

   2: print 'section:', s

将输出(以下将均以简介中配置文件为例):

   1: section: ['db', 'concurrent']

2. 获取指定section 的options。即将配置文件某个section 内key 读取到列表中:

   1: o = cf.options("db")

   2: print 'options:', o

将输出:

   1: options: ['db_host', 'db_port', 'db_user', 'db_pass']

3. 获取指定section 的配置信息

   1: v = cf.items("db")

   2: print 'db:', v

将输出:

   1: db: [('db_host', '127.0.0.1'), ('db_port', '22'), ('db_user', 'root'), ('db_pass', 'rootroot')]

4. 按照类型读取指定section 的option 信息

同样的还有getfloat、getboolean。

   1: #可以按照类型读取出来

   2: db_host = cf.get("db", "db_host")

   3: db_port = cf.getint("db", "db_port")

   4: db_user = cf.get("db", "db_user")

   5: db_pass = cf.get("db", "db_pass")

   6:  

   7: # 返回的是整型的

   8: threads = cf.getint("concurrent", "thread")

   9: processors = cf.getint("concurrent", "processor")

  10:  

  11: print "db_host:", db_host

  12: print "db_port:", db_port

  13: print "db_user:", db_user

  14: print "db_pass:", db_pass

  15: print "thread:", threads

  16: print "processor:", processors

将输出:

   1: db_host: 127.0.0.1

   2: db_port: 22

   3: db_user: root

   4: db_pass: rootroot

   5: thread: 10

   6: processor: 20

5. 设置某个option 的值。(记得最后要写回)

   1: cf.set("db", "db_pass", "zhaowei")

   2: cf.write(open("test.conf", "w"))

6.添加一个section。(同样要写回)

   1: cf.add_section('liuqing')

   2: cf.set('liuqing', 'int', '15')

   3: cf.set('liuqing', 'bool', 'true')

   4: cf.set('liuqing', 'float', '3.1415')

   5: cf.set('liuqing', 'baz', 'fun')

   6: cf.set('liuqing', 'bar', 'Python')

   7: cf.set('liuqing', 'foo', '%(bar)s is %(baz)s!')

   8: cf.write(open("test.conf", "w"))

7. 移除section 或者option 。(只要进行了修改就要写回的哦)

   1: cf.remove_option('liuqing','int')

   2: cf.remove_section('liuqing')

   3: cf.write(open("test.conf", "w"))

四、其他

  1. 以 # 和 ; 开头的行将作为注释

python 的双下划线

“单下划线”“_”开始的成员为保护成员,只有类对象和子类对象可以访问到这些变量/方法。

“双下划线”“__”开始的是私有成员,只有类对象能够访问,子类对象都不可以访问。

“from xxx import ”不可以导入“_”开始的变量/方法

私有变量/方法在代码生成前会被转化成为长格式(变为保护类型),转换机制为:变量/方法前加上类名,再将前端加上下划线字符。

比如A 类中有方法和变量 __private 会在代码解释前替换为 _A__private(类似于C 中的宏替换)

上面的如果明白了,可以到这里测试下。

“__xxxx__”这类双下划线开始,双下划线结束的变量为python 特殊变量,常见的有“__name__”“__file__”“__loader__”“__package__”。如果一个文件是作为主程序调用的,其值就会设为__main__,如果是作为模块被其他文件导入,它的值就是其文件名,常可用于模块内置测试。在python 的官方文档中有这样的解释:

 

The special global variables __name__, __file__, __loader__ and __package__are set in the globals dictionary before the module code is executed (Note that this is a minimal set of variables – other variables may be set implicitly as an interpreter implementation detail).

__name__ is set to run_name if this optional argument is not None, to mod_name + '.__main__' if the named module is a package and to the mod_nameargument otherwise.

__file__ is set to the name provided by the module loader. If the loader does not make filename information available, this variable is set to None.

__loader__ is set to the PEP 302module loader used to retrieve the code for the module (This loader may be a wrapper around the standard import mechanism).

__package__ is set to mod_name if the named module is a package and to mod_name.rpartition('.')[0]otherwise.

If the argument alter_sys is supplied and evaluates to True, then sys.argv[0] is updated with the value of __file__and sys.modules[__name__] is updated with a temporary module object for the module being executed. Both sys.argv[0] andsys.modules[__name__] are restored to their original values before the function returns.

如何开发一个chrome 插件

一、新建一个空文件夹,创建manifest.json 文件

新建文件夹名字是应用的名称,manifest.json 是应用的一些信息,我们以插件scholarsea为例,文件夹名为scholarsea,对应的的manifest.json 如下所示,具体内容参考chrome 扩展文档。

   1: {

   2: "name": "Google Scholar \u641c\u7d22",

   3: "version": "0.1",

   4: "description": "use Google Scholar to find the paper you selected",

   5: "icons": { "48": "4848.png" }, 

   6: "page_action": { "default_icon": "1919.png" },

   7: "background_page": "background.html",

   8: "permissions": [ "contextMenus","tabs" ],

   9: "background_page":"background.html"

  10: }

 

二、为你的应用找一个好看的图标

在文件夹下放你的图标,和manifest 中属性相同。我是的19×19 和48×48 大小的png,还不错吧!自己PS的哦

  1919这个是右键时显示的图标   4848这个是插件介绍用

 

三、新建一个html 文件和manifest 中html 属性一致

内容很简单包含一个后面要用的js 文件,这个js 文件名可以随意

   1: <script src="js.js"></script>

 

四、新建js 文件

这里js 文件名和上面html 内js 文件名一致,用于执行插件的核心工作。scholarsea 将所选的文字作为关键字在Google scholar 进行搜索。内容如下:

   1: //open new tab to search

   2: function searchdblp(info,tab){

   3:     var url="http://scholar.google.com/scholar?hl=en&q=

   4: "+info.selectionText+"&btnG=&hl=en&as_sdt=0%2C5"

   5:     window.open(url);

   6: }

   7:  

   8: //add right button click

   9: var menutitle="Google Scholar \u5e2e\u4f60\u641c"

  10: var parent= chrome.contextMenus.create({"title": menutitle,

  11: "contexts":["selection"],"onclick":searchdblp,});

chrome.contextMenus.create 在浏览器邮件添加一个选项,名称为“Google Scholar 帮你搜”,当点击后调用函数searchdblp ,info.selectionText 是我们在浏览器所选的内容。

 

五、发布插件

看看我们这个名为scholarsea 的文件夹下有了哪些内容:

image

最后只需要在chrome 中发布即可,在chrome 的菜单中选择“工具/扩展程序”,然后打包扩展程序即可。这样会生成一个crx 类型的插件安装文件,和一个pem 的密钥文件(用于管理你的插件)。因为所有插件都是源码开放的,需要确认这个插件是你所有的只有这个密钥了。

 

六、一点注意

在上面没有提到重要一点是manifest 和js 内都不支持中文,采用的是unicode 编码,如果你需要写中文的话,请用unicode 编码,有个简单的中文转unicode 的编码方法,如果你装了python 的话就好办了,看看我怎么解决的

   1: >>> u"帮我搜"

   2: u'\u5e2e\u6211\u641c'

   3: >>> u"搜索此人"

   4: u'\u641c\u7d22\u6b64\u4eba'

看到了吧,很方便哦~~

最后提供两个插件,用于搜索作者的文章dblpsea,和google scholar 搜索文章的插件:

dblpsea】  【scholarsea

批量下载同类型文件脚本

有时候想将整个会议的论文下载下来,手动太麻烦,应该浏览器插件完成的,没有去搜,写了个python 脚本来解决。 将url 页面的指定类型文件下载下来!

红玫瑰格式:python xx.py url file_type

参数一:url 地址;参数二:文件类型

   1: #!/usr/bin/env python

   2: #encoding=utf-8

   3:  

   4: import urllib, urllib2

   5: import re

   6: import os,sys

   7:  

   8: def get_files(ourl,file_type):

   9:     print "The URL is "+ourl

  10:     print "The File Type is "+file_type

  11:     path="E:\\temp\\"

  12:     if os.path.exists(path):

  13:         pass

  14:     else:

  15:         os.mkdir(path)

  16:     print "accessing "+ourl

  17:     print "===>>>href<<<==="

  18:     tempstr='href=\"(\S{3,50}\.'+file_type+'\w{0,2})\"'

  19:     htmldata=urllib2.urlopen(ourl).read()

  20:     fileslist=re.findall(tempstr,htmldata)

  21:     if len(fileslist)==0:

  22:         print "no"+" ."+file_type+" files"

  23:     else:

  24:         for app in fileslist:

  25:             if (ourl[-1]=='/'):

  26:                 pass

  27:             else:

  28:                 ourl=ourl[:ourl.rindex("/")+1]

  29:             if (app[0:7]=='http://'):

  30:                 url=app

  31:             else:

  32:                 url=ourl+app

  33:             filedata=app

  34:             try:

  35:                 print url+"\tdownloading ......"

  36:                 filedata=urllib2.urlopen(url).read()

  37:                 print "read "+url

  38:                 filestr=path+url[url.rindex("/")+1:]

  39:                 print "file is "+filestr

  40:                 fp=open(filestr,'wb')

  41:                 fp.write(filedata)

  42:                 fp.close()            

  43:             except: 

  44:                 print "cann't get "+url

  45:     print "===>>>src<<<==="                

  46:     tempstr='src=\"(\S{3,50}\.'+file_type+'\w{0,2})\"'

  47:     htmldata=urllib2.urlopen(ourl).read()

  48:     fileslist=re.findall(tempstr,htmldata)

  49:     if len(fileslist)==0:

  50:         print "no"+" ."+file_type+" files"

  51:     else:

  52:         for app in fileslist:

  53:             if (app[0:7]=='http://'):

  54:                 url=app

  55:             else:

  56:                 url=ourl+app

  57:             filedata=app

  58:             try:

  59:                 print url+"\tdownloading ......"

  60:                 filedata=urllib2.urlopen(url).read()

  61:                 print "read "+url

  62:                 filestr=path+url[url.rindex("/")+1:]

  63:                 print "file is "+filestr

  64:                 fp=open(filestr,'wb')

  65:                 fp.write(filedata)

  66:                 fp.close()            

  67:             except: 

  68:                 print "cann't get >> "+url    

  69:  

  70: if __name__ == "__main__":

  71:     ourl=sys.argv[1];

  72:     file_type=sys.argv[2];

  73:     get_files(ourl,file_type)

Consistent hashing 的python 实现

部分代码参考之前的“写一个分布式存储系统有多简单?”,保持数据服务器端不变,修改客户端节点选择方式即可。

修改:1、添加HashRing 类,进行一致性哈希环的管理,保存在客户端client ,因此节点/数据服务器端可以不做任何修改(添加hello 测试)。2、客户端修改节点选择方式,使用consistent hashing。

接受一致性哈希的国内的也比较多了,可以参考这里

继续阅读