8月 19

Linux 暴力破解rar密码 性能查看

python使用自带的性能分析工具。
生成报告
# python -m cProfile -o test1.out decRAR.py tt.rar passwd.txt
tt.rar pass is 123

查看报告
# python -c “import pstats; p=pstats.Stats(‘test1.out’); p.print_stats()”
Sat Jul 30 10:07:38 2016 test1.out

305 function calls in 2.922 seconds

Random listing order was used

ncalls tottime percall cumtime percall filename:lineno(function)
50 0.001 0.000 0.001 0.000 {method ‘close’ of ‘file’ objects}
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/site.py:357(__call__)
49 0.000 0.000 0.000 0.000 {method ‘find’ of ‘str’ objects}
49 0.006 0.000 2.919 0.060 /usr/lib64/python2.7/commands.py:56(getstatusoutput)
49 0.001 0.000 2.920 0.060 /usr/lib64/python2.7/commands.py:48(getoutput)
49 0.012 0.000 0.012 0.000 {posix.popen}
49 2.900 0.059 2.900 0.059 {method ‘read’ of ‘file’ objects}
1 0.000 0.000 0.000 0.000 {open}
2 0.000 0.000 0.000 0.000 {method ‘split’ of ‘str’ objects}
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/warnings.py:14(warnpy3k)
1 0.000 0.000 2.922 2.922 decRAR.py:8()
1 0.000 0.000 0.000 0.000 /usr/lib64/python2.7/commands.py:20()
1 0.000 0.000 0.000 0.000 {method ‘disable’ of ‘_lsprof.Profiler’ objects}
1 0.000 0.000 0.000 0.000 {method ‘readlines’ of ‘file’ objects}
1 0.002 0.002 2.922 2.922 decRAR.py:13(main)

结论,密码有49个,所以调用解密命令49次,时间用在读文件上,就是解密部分。这样单进程单线程的结果应该已经是最佳了。

golang
不用协程部分,把main修改如下。

func main() {
    start()
    fmt.Println("not find password")
}

# time go run decRAR.go
tt.rar pass is 123
exit status 1

real 0m3.462s
user 0m3.117s
sys 0m0.291s
golang性能分析软件暂时没有用到。

8月 18

Linux 暴力破解rar密码

制作一个有简单密码的rar。简单密码表49行,正确密码在最后一行。暴力破解代码如下。
rar密码吗测试使用命令调用rarlinux方式测试,http://www.simonzhang.net/?p=2980

python部分

#!/bin/env python
# -*- coding:utf-8 -*-
# Date:        2016-07-29
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
import os
import sys
import commands


def main(rarName, passwd):
    try:
        passFile = open(passwd, 'rb').readlines()
    except:
        print "read password error"
    #
    num = 0
    for one in passFile:
        num += 1
        if num%1000 == 0:
            print "test %s" % num
        if one[-1] == '\n':
            one = one[:-1]
        getContext = commands.getoutput('rar t %s -p"%s"' % (rarName, one))
        if getContext.find("OK") > -1:
            print "%s pass is %s" % (rarName, one)
            exit()

if __name__ == "__main__":
    try:
        if sys.argv[1].split('.')[1] == "rar":
            rarName = sys.argv[1]
        else:
            print "rar name error"
            print "python devRAR.py xx.rar pass.txt"
            exit()
        if sys.argv[2].split('.')[1] == "txt":
            passwd = sys.argv[2]
        else:
            print "password error"
            print "python devRAR.py xx.rar pass.txt"
            exit()
    except:
        print "python devRAR.py xx.rar pass.txt"
        exit()
    main(rarName, passwd)

golang部分

/*
# Date:        2016-07-29
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
*/
package main

import (
   "os"
   "io"
   "fmt"
   "strings"
   "bufio"
   "os/exec"
   "runtime"
)

func checkRAR(passwd string) {
    var tmpPass string = "-p"+passwd
    cmd := exec.Command("rar", "t", "tt.rar", tmpPass)
    status := cmd.Run()
    if (status == nil){ 
        fmt.Println("tt.rar pass is ", passwd)
        os.Exit(1)
    }
}

func start(c chan string){
    // 读密码文件
    passFile := "passwd.txt"
    pf,err := os.Open(passFile)
    if err != nil {
        fmt.Println(passFile,err)
        os.Exit(1)
    }
    defer pf.Close()
    //
    rd := bufio.NewReader(pf)
    for {
        //以'\n'为结束符读入一行
        line, err := rd.ReadString('\n')
        if err != nil || io.EOF == err {
            break
        }
        tmpPass := strings.Replace(line, "\n", "", -1)
        /* 如果是Linux上编辑的密码文件下步不需要。
           如果密码文本是在windows下编辑的可能会带^M
           不可见字符。应用vim -v 或者cat -A 可以看到。
        */
        tmpPass = strings.Replace(tmpPass, "\r", "", -1)
        checkRAR(tmpPass) 
    } 
}

func main() {
    //计算cpu核数
    var loopnum int = runtime.NumCPU()
    //设置协程cpu核数
    runtime.GOMAXPROCS(loopnum)
    c := make(chan string)
    for i:=0; i<=loopnum; i++ {
        go start(c)
    }
    <- c
    fmt.Println("not find password")
}

源码部分

# time python decRAR.py tt.rar passwd.txt
tt.rar pass is 123

real 0m2.861s
user 0m2.535s
sys 0m0.279s

# time ./decRAR
tt.rar pass is 123

real 0m5.736s
user 0m5.151s
sys 0m0.452s

参数输入部分还没有开发,如果全部实现,golang应该超出python代码一倍多。
python运行时使用cpu 2%,可以改为多线程,这样开30个线程效果应该不错。
golang速度慢稍后再做性能分析,看看具体问题。

7月 05

学习开发自己的api框架

学习开发api部分。按照自己的想法开发个自用框架。
目的是只要写出sql,通过简单代码就能完成api开发。
主要用于api的查询部分,返回json格式数据。

开发步骤(修改好配置文件):
1)example.py为例子文件。拼接一个sql取出值,调用函数将数据整理成json。
2)在route.py文件中导入例子from example import *。
3)在route.py文件中写好路由(r”/test”, exampleHandler)。
开发完成。

已经实现的功能
1)数据库读写分离
2)数据库多库
3)redis认证存储session
4)账户密码加盐存在mysql中,加密加盐
5)mysql中查出的二维表转json
6)支持将多次查询(select)数据组成一个json

git地址
https://github.com/simon-zzm/meapi

2月 26

iPhone 手机控制linux服务器,swift2语言使用pickerview控件源码

之前的写的“iPhone 手机控制linux服务器程序源码”(http://www.simonzhang.net/?p=2861 )。开启时间使用textfidld,太麻烦了。就保留常用的几个时间即可。所以改为使用pickerview控件。控制没有使用故事板,直接代码控制位置。源码如下,其他部分使用之前的代码。iphone6调试正常。

//
//  door.swift
//  mydoor
//
//  Created by zhangzimeng on 16/1/6.
//  Copyright © 2016年 com. All rights reserved.
//

import UIKit
import Alamofire
import Crypto

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
    var timePicker:UIPickerView!
    var buildString = ["3秒", "30分钟" , "1小时", "2小时", "3小时", "4小时"]
    var buildInt = ["3", "1800" , "7200", "7200", "10800", "14400"]
    let kk = "09999999999999"
    let url = "http://www.simonzhang.net/door?"
    
    @IBAction func dangdang(sender: AnyObject) {
        // 获取要开发的时间
        let row:Int = self.timePicker.selectedRowInComponent(0)
        let getSec=buildInt[row]
        // 获取当前两位小时和分
        let Hour:NSDate = NSDate()
        let Min:NSDate = NSDate()
        let dateForm=NSDateFormatter()
        dateForm.dateFormat="HH"
        let getHour=dateForm.stringFromDate(Hour)
        dateForm.dateFormat="mm"
        let getMin=dateForm.stringFromDate(Min)
        // 拼接要加密的穿
        let ss=kk+getHour+getMin
        let authMd5 = ss.MD5
        // 拼接要访问的字符串
        let doorUrl = url+"se="+getSec+"&au="+authMd5!
        // 开始访问
        var returnText = ""
        Alamofire.request(.GET, doorUrl)
            .responseString{ openStatus in
                if openStatus.result.value == "成功"{
                    returnText="成功"
                }else{
                    returnText="失败"
                }
                UIAlertView(title: "敲门结果", message: returnText,
                    delegate: nil, cancelButtonTitle: "确定").show()
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        timePicker=UIPickerView()
        // 定义位置
        self.timePicker.frame = CGRectMake(120, 100, 150, 200)
        // 绑定数据
        self.timePicker.delegate=self
        self.timePicker.dataSource=self
        //设置选择框的默认值
        timePicker.selectRow(3,inComponent:0,animated:true)
        //添加到界面中
        self.view.addSubview(timePicker)
    }
    
    //设置选择框的列数为1列,继承于UIPickerViewDataSource协议
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    
    // 返回要显示文字的列表
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if (pickerView.tag == 1){
            return buildString.count
        }else{
            return buildString.count
        }
    }
    
    // 返回显示内容
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if (pickerView.tag == 1){
            return "\(buildString[row])"
        }else{
            return "\(buildString[row])"
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

1月 24

python调用golang编译的动态链接库

当前任务:抓取页面,然后删除回车,tab和空格,然后打印出来。
最初是在raspberry上做的测试。使用新浪作为测试网站。

python部分文件名 gradAndDel.py

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Date:        2016-01-21
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------
import urllib

url = "http://www.sina.com.cn/"

data = rullib.urlopen(url).read()
data = data.replace('\n', '')
data = data.replace('\t', '')
data = data.replace(' ', '')
print data

使用时间如下
real 0m2.878s
user 0m1.910s
sys 0m0.240s

golang文件名gradAndDel.go

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

func main() {
    resp, err := http.Get("http://www.sina.com.cn")

    if err != nil {
        fmt.Println("http get error.")
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("http read error")
    }

    src := string(body)

    src = strings.Replace(src, "\n","",-1)
    src = strings.Replace(src, "\t","",-1)
    src = strings.Replace(src, " ","",-1)
    fmt.Println(strings.TrimSpace(src))
}

使用时间如下:
real 0m0.718s
user 0m0.290s
sys 0m0.090s

使用golang比python快差不多4倍(使用requests模块抓取显示中文乱码,暂时没有找原因)。

golang1.5后可以将go语言编译为动态链接库。
这样使用python处理业务逻辑,然后调用golang的动态链接库加速执行速度。
但是在raspberry pi上调用的时候报段错误。没有细查,直接放到64位Linux服务器上测试。

要产生动态的链接库的golang代码gradAndDelso.go

/*
# Date:        2016-01-21
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
*/
package main

import ("C"
        "fmt"
        "net/http"
        "io/ioutil"
        "strings"
       )


//export Deltr
func Deltr(webdata *C.char) *C.char {
    var src string
    url := C.GoString(webdata)
    src = string(grad(url))
    src = strings.Replace(src, "\n","",-1)
    src = strings.Replace(src, "\t","",-1)
    src = strings.Replace(src, " ","",-1)
    data := C.CString(src)
    return data
}

//export grad
func grad(url string) string{
    resp,err := http.Get(url)
    if err != nil {
        fmt.Println("http get error.")
    }
    defer resp.Body.Close()
    body,_ := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("http eee error.")
    }
    goback := string(body)
    return goback
}

func main() {}

编译命令
go build -buildmode=c-shared -o gradAndDelso.so gradAndDelso.go

编译完成会产生两个文件,一个so和一个h文件。
使用python调用golang动态链接库部分,代码文件userGoSo.py

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Date:        2016-01-21
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------
import ctypes

lib = ctypes.CDLL("./gradAndDelso.so")
url = "http://www.sina.com.cn"
re = lib.Deltr
re.argtypes = [ctypes.c_char_p]
re.restype = ctypes.c_char_p
print re(url)

使用时间
real 0m0.893s
user 0m0.068s
sys 0m0.024s

在64位的服务器上python、golang和python调用golang的动态链接库速度基本上一样没有区别。
如果是处理复杂的运算golang应该比python快很多,实际项目中可以试试。
golang开发的代码量比python还是大不少,编译后的文件有6M,动态链接库8M,个人感觉这部分太大了。

本文源码打包pythonUserGolangLib