学习:人工智能-机器学习-深度学习概念的区别

2019年1月20日 12:36

 

一图胜千言

 
 

Tags: 机器学习 深度学习
评论(0) 阅读(68)

使用numba的姿势不正确反而导致性能下降

2019年1月20日 09:24

numba能够极大的提高python在计算方面的性能。是不是所有的python代码上,都可以加上numba.jit装饰器?答案是否定的。
 
 

Tags: python 性能
评论(0) 阅读(66)

numba加速python学习与尝试

2019年1月20日 09:20

 简介

 
探索python性能优化工具,发现了numba. 只需要给函数加上装饰器就可以。比cython和pypy方便多了。
 

numba是什么

 
numba是为了提高numpy速度而开发的,使用llvm将python代码翻译为bitcode,并在bitcode外面做了一层包装,让python可以调用
 
通过numba翻译的代码由于经过llvm优化并可在机器上直接执行,效率将有所提高,对海量数据处理非常有帮助
 
 

评论(0) 阅读(68)

用最简单方法解决api接口安全问题,几乎无法破解

2019年1月01日 11:45

 

 场景描述

 
项目需要为第三方提供api服务接口。接口涉及到核心功能,如何保证接口安全。防止伪造身份、篡改数据?
 

思路

 
保障数据安全最好的方法,当然是加密了。无法解析内容,自然无法伪造,篡改。

可是使用https证书需要收费的。有其它方法么?

有的。

消息哈希认证(hmac)。
 
 

 算法描述

 
*  访问者
 
1. 当访问接口时, 将参数按key值排序,组成key1=value1&key2=value2&....&secret_key=...
2. 然后对上面结果做md5,生成签名sign
3. 将sign放到加入请求的参数
 
* 被访问者
 
密钥是被访问者提供了,它也有访问者的secret_key.
1.根据app_id查到secret_key
2.处理请求参数,按规则组成key1=value1&key2=value2....&secret_key=...
3.对上一步结果做md5,生成sign。比较两个sign,相等则身份验证通过
 

效果

 
1. 密钥只存在双方机器上,不可能被截取
2. 签名无法伪造,同样身份无法伪造、消息无法被篡改
 
使用了hmac认证,接口被破解基本是不可能的
 

python实现

 
import md5

app_id=123
secret_key="xxxxxxxx"

request_param = dict(
    key1="value1",
    key2="value2",
    key3="value3"
)

def sign():
    params = ["%s=%s" % (key, value) for key, value in sorted(request_param.items(), key=lambda item: item[0])]
    params.append("secret_key=%s" % secret_key)
    str_param = "&".join(params)
    print str_param
    md = md5.md5()
    md.update(str_param)
    return md.hexdigest()

if __name__ == '__main__':
    print(sign())
 
 
来源
 

 

Tags: web python
评论(0) 阅读(512)

没有契合的数据库迁移工具,用pymysql实现一个

2019年1月01日 11:21

版本迭代少不了数据迁移,python有自己的数据库迁移工具migrate。如果有的是其它开发语言,或者没有契合的迁移工具。
 
怎么自己做一个?
 

环境说明

项目开发语言:java
数据库: mysql
迁移脚本: python
python工具包: pymysql
 

实现思路

 
目标是将老版本的数据转为新版本的数据。
 
1. show tables 查询所有的表  ---得到所有表名
2. 注意trancate table_name 保证新表干净  -- 清环境
3. python在执行sql后可以在游标的属性cursor.description中看到表的字段信息  -- 得到所有字段名、类型
4. 查询数据生成insert语句。版本之间有变化的做特殊处理  --数据映射
5. 每生成500条commit一次到新库   -- 批量commit
6. mysqldump一份数据,在开发环境做好测试,没问题就可以用了。
 

前方有坑

 
留意数据精度问题
 

示例

 
import pymysql

FROM_DB = dict(
    ip="xxxxxxxxxx",
    username="xxxx",
    password="xxxx",
    db_name= "db1"
)

TO_DB = dict(
    ip="xxxxxxxxxx",
    username="xxxx",
    password="xxxx",
    db_name="db2"
)


class WebDB:
    def __init__(self, ip, username, password, db_name='xxx'):
        self.ip = ip
        self.username = username
        self.password = password
        self.db_name = db_name
        self.conn = None
        self.cursor = None

    def __enter__(self):
        self.conn = pymysql.connect(self.ip, self.username, self.password, self.db_name)
        self.cursor = self.conn.cursor()
        return self

    def __exit__(self, exctype, excvalue, traceback):
        if self.cursor:
            self.cursor.close()

        if self.conn:
            self.conn.close()



class MigrateDB(object):
    def start(self):
        self.clean()
        self.import_data()

    def clean(self):
        with WebDB(**TO_DB)as db:
            db.cursor.execute("show tables;")
            for tables in db.cursor.fetchall():
                table_name = tables[0]
                db.cursor.execute("truncate %s;" % table_name)

    def import_data(self):
        with WebDB(**FROM_DB) as from_db:
            with WebDB(**TO_DB) as to_db:
                #所有表
                from_db.cursor.execute("show tables;")
                for from_tables in from_db.cursor.fetchall():
                    from_table_name = from_tables[0]
                    from_db.cursor.execute("select * from %s;" % from_table_name)
                    items = self.to_dict(from_db.cursor.fetchall(), from_db.cursor.description)
                    print("import table: %s" % from_table_name)
                    to_table_name = from_table_name
                    for i, item in enumerate(items):
                        # 需要映射转换的表,生成专门的sql
                        if from_table_name == "xxxx":
                            to_table_name = "xxxxx"
                            item = self.gen_insert_sql_for_xxx(item)

                        sql = self.gen_insert_sql(to_table_name, item)
                        to_db.cursor.execute(sql, args=item)
                        # 每500条commit一次
                        if i != 0 and i % 500 == 0:
                            to_db.conn.commit()
                    to_db.conn.commit()


    def to_dict(self, rows, description):
        """
        记录转为字典
        :param rows:
        :param description:
        :return:
        """
        for row in rows:
            item = dict()
            for i, field in enumerate(description):
                field_name = field[0]
                item[field_name] = row[i]
            yield item

    def gen_insert_sql(self, table_name, item):
        sql = "insert into %s(%s) values(%s)"
        keys = item.keys()
        key_str = ",".join(keys)
        value_str = ",".join(["%%(%s)s" % k for k, v in item.items()])

        return sql % (table_name, key_str, value_str)


if __name__ == "__main__":
    m = MigrateDB()
    m.start()
 
来源
 
 
 

评论(0) 阅读(467)

nginx运行php的终极方法,可避免许多不必要的坑

2018年12月28日 00:56

 

 说明

 
php有许多开源项目比较好像,在自己的机器上用docker搭建了很多。
 
每个docker都是跑了个apache,每个docker里面都有apache。
 
这样好像有点浪费资源,而平时都是用nginx,所以研究了用nginx运行php
 
中间竟然碰到许多坑,而回过头来看,其实都很简单。
 

nginx运行php的原理

 
nginx不能解析php,要和php-fpm配置使用。nginx负责将php的请求转给php-fpm解析处理,然后返回响应结果
 

nginx运行php会遇到哪些坑

 
错误的提示有很多,最基本有"File not found"、"403"、"404"、"nginx no input file specified"等等
 
总之能试出许多错误。**而归结到底,只有一个根本原因“权限”**
 
而最好的方法是,直接把nginx和php-fpm设置为root用户运行
 

测试环境

 
|对象|版本|
|--|--|
| 操作系统 | fedora27 |
| nginx    | 1.12.1   |
| php-fpm  | php7     |
 
 

配置方法

 
* 安装nginx
 
yum install nginx
 
* 安装php-fpm
 
yum install php-fpm
经过上面两步, php-fpm会自动将nginx配置好,只要将php放到/usr/share/nginx/html目录就可以运行。但是我不想放在这个目录。
 
 
* 设置php-fpm以root用户运行
 
1.打开文件 /usr/lib/systemd/system/php-fpm.service


2.在ExecStart 最后面加上参数-R标识可以用root身份运行(php-fpm默认不能用root运行)
(有可能改了php-fpm.server文件不能运行,请运行systemctl reload重新加载)


[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=notify
ExecStart=/usr/sbin/php-fpm --nodaemonize -R
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target


3.打开文件/etc/php-fpm.d/www.conf

4.将修改user和group为root
user=root
group=root
 
* 设置nginx以root身份运行
 
1.打开/etc/nginx/nginx.conf

2.将user改为root
 
* 配置自己的php项目
 
将下面内容放到/etc/nginx/conf.d/目录下
server {
        listen 8080;
        server_name  localhost;

        root  /home/xxxxx;      #改成自己的地址
        index  /_h5ai/public/index.php;   #改成自己的php首页
        include /etc/nginx/default.d/*.conf;    #使用已经配置好的location

        location / {
        }
}
 

排错方法

 
如果在配置过程中,遇到了错误。用什么方法调试呢?
 
* nginx调试方法
 
nginx的任务是把php的路径调对。可以先把php-fpm注释掉,专门调nginx,当能从浏览器下载php文件,说明配置正确。
 
* php-fpm调试方法
 
用命令运行php-fpm会有清晰的输出
 
/usr/sbin/php-fpm --nodaemonize -R
 

总结

 
nginx运行php总的说来很简单,由于权限问题,会导致遇到许多的坑。
 
实际很多情况下,都是给内部用,直接用root就可以。当然这样方法在正式环境不安全。
 
来源
 

 

Tags: php nginx php-fpm
评论(0) 阅读(546)

frp内网穿透基本用法

2018年12月27日 23:55

 

思考评价

 
由于路由器推荐使用frp进行内网穿透,所以我稍微了解了下。
 
平时我更新喜欢用ssh进行内网穿透。似乎并没有必要使用frp。
 
更方便的方法是,直接用vpn将两台机器连载一起,也比端口穿透好多了。
 
一般说来它比较适合普通人,使用比较简单。
 
不打算深入研究,下面比较水
 

基本用法

 
* 下载
 
 
一般是amd64
 
* 解压
 
tar -zxvf xxx
 
* 启动server
 
./frps -c frps_full.ini
 
* server控制台
 
访问 http://server-ip:7500
 
* 配置说明
 
中文帮助
 
 

示例

 
* server
 
[common]
bind_addr=0.0.0.0
bind_port = 30202
token=密码
 
 
* client
[common]
server_addr = xxx
server_port = xx
token=密码

[web]
type = tcp
local_ip = 192.168.50.1
local_port = 99
remote_port=82
 
来源
 
 

Tags: linux vps
评论(0) 阅读(559)

rclone报错NewFs: couldn't initialise SFTP: EOF

2018年12月27日 23:27

rclone将路由器挂载到vps,出现下面错误。
 
原因是路由的ssh不支持sftp。
[root@izwzxxxxxxxqre9xrhvz ~]# rclone lsd homedata:
2018/12/24 13:57:24 Failed to create file system for "homedata:": NewFs: couldn't initialise SFTP: EOF

来源

rclone报错NewFs: couldn't initialise SFTP: EOF

 

Tags: rclone
评论(0) 阅读(122)

entware嵌入到移动硬盘,在路由器重启后不生效

2018年12月27日 23:14

环境说明

 
在路由器r6400上挂载了一个移动硬盘,然后在移动硬盘中安装了entware。
 
如果重启了路由器,entware会失效。如何让它在重启时生效呢?
 

 梅林r6400开机启动原理

 
路由器中的操作系统比较特殊
 
1. /etc/profile: 系统做了限制不能修改,所以不可以加脚本
 
2. /jffs/scripts目录: 里面的脚本名固定不可以随便修改,但是可以加自己的内容。
 
| 脚本名         | 作用                   |
|--|--|
| post-mount     | 在挂载磁盘后调用       |
| nat-start      | 在nat配置后调用        |
| services-start | 在系统服务启动后调用   |
| services-stop  | 在系统服务器停止前调用 |
| wan-start      | 在wan网卡启动后调用    |
 

设置entware开机生效

 
entware生效的方法很简单,只需要把u盘中的entware挂载到opt,它就会生效。
 
现在我们把在加到开机启动脚本中
 
打开/jffs/scripts/post-mount把下面内容加到文件末尾。
 
ln -s /tmp/mnt/sda1/entware  /tmp/opt
 

entware服务的开机启动

 
entware服务在/opt/etc/init.d/目录,将自己的shell加到这个目录就可以
 

entware启动参数说明

https://github.com/RMerl/asuswrt-merlin/wiki/User-scripts
 
来源
 

 

Tags: 路由器 vps
评论(0) 阅读(103)

让梅林R6400支持sftp协议

2018年12月25日 02:29

说明

 
通常linux中ssh默认支持sftp,梅林路由器中的ssh是精简版,不支持sftp协议。
 
自带的配置不支持,是否有有办法呢?我们可以先装entware-setup.sh,然后用opkg安装sftp。
 
有了ssh和sftp,我们可以做很多事。
 
 

环境(前置条件)

 
  • * r6400路由器
  • * entware-setup.sh已安装好系统,可以使用opkg
  • * 路由器启动了ssh登录
 

 ssh登录到路由器

安装sftp

 
opkg install openssh-sftp-server
 

启动

 
sftp是由ssh触发运行,只需重启路由器,它会自动启动。看到sftp-server表示,它已经运行了
 
 
 

测试

 
使用xshell的xftp进行链接测试
 
 

 总结

 
让梅林支持sftp并不复杂,复杂的地方在于将entware-setup安装调好。
 
来源
 
 

 

Tags: 路由器 梅林 r6400
评论(0) 阅读(57)