12月 21

goalng获取分钟级别unixtime

数据需要按照分钟级别分类,所以需要产生当前分钟的unixtime。
最初写法:

strTime, _:= time.Parse("2006-01-02 15:04", time.Now().Format("2006-01-02 15:04"))
 nowTime := strTime.Unix()-3600*8

效率比较低,还有时区问题。后来修改为当前时区unixtime减去秒。

package main

import (
	"fmt"
	"time"
)

func main() {
        var nowMinUnixTime int64
	nowMinUnixTime = time.Now().Unix() -int64(time.Now().Second())
	fmt.Println(nowMinUnixTime)
}
11月 10

raspberry pi 2用golang 控制GPIO

raspberry pi2散热量并不大,但是长时间高运算量运行还是装个小风扇比较好,所以做个自动开关的风扇。本次使用go 1.7。
硬件:4针热敏传感器模块,宝上买的1块5,采用NTC热敏电阻传感器。小风扇还没有到,用led实验。
首先安装需要库
go get github.com/stianeikeland/go-rpio
查看源码可以对Linux的文件系统有更好的了解,推荐要好好看看。
代码部分:

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

import (
    "os"
    "github.com/stianeikeland/go-rpio"
    "time"
)

var (
    aio = rpio.Pin(14)
    fio = rpio.Pin(4)
    alertCount int = 0
)

// 风扇端口
func fWrite(status string){
    fio.Output()
    if status == "high"{
        fio.High()
    }else if status == "low"{
        fio.Low()
    }
}

// 监控端口
func aRead() int{
    aio.Input()
    return int(aio.Read())
}

func main() {
    err := rpio.Open()
    if err != nil {
        os.Exit(1)
    }
    defer rpio.Close()
    // 因为没有while 直接用for
    for {
        // 数字不能太大
        // 1是内存问题,2是停止风扇范围
        if aRead() == 1 {
            if alertCount > 0{
                alertCount -= 1
            }
        }else{
            if alertCount <= 10{
                alertCount += 1
            }
        }
        //print(alertCount, "   ", aRead(), "\n")
        //
        if alertCount > 3{
            fWrite("high")
        } else {
            fWrite("low")
        }
        // 每次次循环等待一秒钟
        time.Sleep(1000 * time.Millisecond)
    }
}

imhot20161110
运行后实验,用手加热
qidong20161101
放开手
tingzhi20161110
raspberry pi2 接口图

raspberry pi2

raspberry pi2

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速度慢稍后再做性能分析,看看具体问题。

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