且行善举,莫问前程。

0%

疯狂的是数字货币,随之是区块链,与后者相比前者疯狂到无法形容,这是我的人生经历中让我咋舌的事件。我没经历过郁金香事件,也没有领略过股灾的残酷,但是身在数字货币前沿,作为一个数字货币从业者,我却感受到了他的疯狂。

2016年末,我加入到比特别中国,曾经的比特币价格大概8000元,我没有币圈信仰也不能预测今后比特币是跌是涨,所以一直没买入比特币,因此将公司发的比特币都直接兑现了。因为比特币升值过快,政府也约见了三大交易所的管理层,这才稍稍降温。

但是人们的疯狂是压不住的,这也只是政府的缓兵之计。而这个缓兵之计把比特币推上各大媒体,让资本开始关注比特币。马克思曾说过:资本如果有百分之五十的利润,它就会铤而走险;如果有百分之百的利润,它就敢践踏人间一切法律;如果有百分之三百的利润,它就敢犯下任何罪行,甚至被绞死的危险。然而比特币利润远远高于百分之三百。

大概17年中旬币价飞涨,政府和媒体更加关注了,于此同时以太坊以及山寨币趁着东飞连涨一波。

资本靠买卖套利,收益更高的还有圈钱,以太坊的ERC20为圈钱提供了更好的工具,只要写一个白皮书就可以做到一本万利,也是这波ICO让政府放弃了监管数字货币,而是直接宣布ICO是犯法的,交易所也紧接着被关停。比特币从此去中国化,也是在此我卖出了所有的数字货币。这之后也是让人感觉到疯狂的是,比特币连涨到10万人民币,这也是币圈在去中国化时坚信的。

如果你看一下比特币的价格曲线,你会为此感到震惊。人民会为了资本变得疯狂。进来的还想投入更多,没进来的疯狂挤入。然而庄家一波波的割着韭菜,一些不贪心的赚到了满意的钱早早离场。有入场后悔的,有没入场后悔的。我也后悔,后悔币卖早了,后悔没有买更多,心是会红的,明明知道是骗局也想要进去,无非是还没有财务自由,还得努力多打拼几年,可是最终我能得到是不浮躁心。怎么说,算是安慰自己吧。所以在去中国化后,就再也没有买过,虽然已经有很多c2c平台。

资本主义,财富不能共享。社会主义困苦一起分担。大道之行也,天下为公。这世界就是还真是有趣。

有钱很好,还是脚踏实地的走比较好,一生一辈子做不了多少事情。

0x00

我说,如果想操纵时间那肯定要操纵空间。两量车,出发时间间隔20分钟,那么两车之间距离是是一定的,如果想超过前面的车就要加速度。追上前面车时,可以说空间相同,这时时间是否相同?我想不出来,也不知道该怎么研究,相对论、穿越时间太深奥了,不过相信有一天会做到的。

0x01

搞些区块链的东西,比如做个区块链象棋,发个代币,没给人初始都有一些代币,可以来下象棋,输的人要给赢的人一些代币,而且象棋的棋谱永远保存在区块链上,不会被篡改丢失。也可以搞搞区块链抽奖,用代币买随机号码,每天抽出幸运号码,给幸运者发奖励等等。总之这是个机会。

0x02

你能想多远就能走多远,比如我下象棋只能像后想三步,我看数字货币只能看到眼前的涨跌,自主思考才是最重要啊。走路走多了,停下来思考思考。

0x03

观察力还是很重要的,这个和个人脑力也有关,有的人一篇文章要看十分钟,有些人只要看五分钟,还比前者提取到到信息多,主要是人家还思考了呢。

0x04

羡慕那些有梦想的人。

0x05

羡慕那些有梦想,而且仍然在努力的人。

0x06

羡慕那些已经深陷梦想,而且仍然努力着的人。

有一个很经典的故事,斯坦门次为福特公司画了一条线,收了1000美元,其中画一条线的价值是1美元,知道在哪里画条线值999美元。这个故事让我深有感触。

前些天和同时排查一个问题数据库问题,我们staging环境有一个服务总是卡死,导致一些api超时无法访问,最终排查是数据库死锁,又经过一系列排查,具体到了一个函数内,这个函数中会先去获取一个数据库的advisory lock,然后再执行SQL,这一系列操作都在try cache中,也是为了方便回滚数据库,一切看起来都没问题。

为了复现这种情况,我们手动获取advisory lock,然后触发该函数,结果卡死。找不到具体原因,另一个同事看我们讨论激烈,过来询问并一语道破,这个数据库驱动是C写的,Python并不能抓取到C中的异常,所以会一直等待释放。

真是直接命中问题所在,和这个同事相比,不是经验问题,和我同岁,工作年限比我少,为什么他可以很快解决,而我并不能。

这是一个值得思考反思的问题。

偌大的上海繁华的不着边际,随便找出个的地方也能比我家强一些。

毕业两年,加上实习也有两年半了,待过北京跑过上海,浑浑噩噩的,我也许是在互联网圈子的朋友中混的最差的了,有过太多的错误决定,不成熟也不稳重。时间推移,急躁的心也变得平静。

没有例外,只能默默自许,还年轻,急躁不得。人生不公平,理想奢侈,遥不可及。

偌大的上海,在繁华的中心,来来往往的人,不知要走向何方。记不起当初的理想,也不知该走向何方。

最后只剩

低落

低落

低落。

然后又抬起头微笑。

人生公平,有失有得。人生苦短,唯有珍惜。何必羡慕,唯有努力,即便没有方向。

2016年的最后一篇文章,势必赶在最后的两小时前写完这篇文章。

ARP 欺诈

ARP 欺诈主要是在局域网内,通过伪造 IP 地址和 MAC 地址来达到欺诈的目的,并且会在网络中产生大量的 ARP 通讯,使网络瘫痪。攻击者只要持续不断的发出伪造的 ARP 响应包就能更改目标主机 ARP 缓存中的 IP-MAC 条目,造成网络中断或中间人攻击。

怎么实现 ARP 欺诈

在网络上搜索还是能搜到具体的方法的,在此只做总结,具体实现目前也没有研究过。仅供娱乐切勿违法。

欺诈前准备

一台接入路由器的电脑,路由器会分配给你内网 IP。电脑系统最好是 Linux ,如果是 windows 大概软件会更多。

一些软件

  • ettercaps,ARP 欺诈发包软件
  • driftnet,数据包图片显示软件

在 Ubuntu 下可以直接使用 apt 来安装

使用方法

ettercaps ARP欺骗之会话劫持

加入你连接路由的网卡是 eth0,网关为 10.0.0.1,那么

1
2
ettercap -i eth0 -T -M arp:remote /10.0.0.1/ // # 欺骗局域网内所有主机
ettercap -i eth0 -T -M arp:remote /10.0.0.1/ /10.0.0.12/ # 欺骗IP为10.0.0.12的主机

这是可以使用 tcpdump 对欺诈成功后发过来的包进行抓取,使用 tcpdump

1
tcpdump -i eth0

也可以使用 driftnet 实时显示图片。

如何防御

防御还是比较棘手的,造成网络拥堵的情况下只能找到发包的主机,还有就是要绑定自己电脑的网关地址。

Python解释器

有时候我们会把 Python 的 REPL (命令行下Python的交互环境)当作解释器,它会将源代码编译为字节码并执行。Python 解释器是一个模拟堆栈机器的虚拟机,仅使用多个栈来完成操作。也可以看看 500行实现一个解释器

在解释器接手之前,Python 会执行其他3个步骤:词法分析,语法解析和编译。这三步合起来把源代码转换成 code object,它包含着解释器可以理解的指令。而解释器的工作就是解释 code object 中的指令。

code object

Python字节码

在我们导入 python 脚本时在目录下会生成个一个相应的 pyc 文件,这是 python 解释器生成的字节码,是为了加速下一次的装载。

我们写一个简单的函数,并打印其字节码

dis

1
2
3
4
5
def sample(n:int) -> bool:
if n >= 1: return True
return False

print(sample.__code__.co_code)

sample.__code__ 是与其关联的 code object,而 sample.__code__.co_code 就是它的字节码。

输出:

b’|\x00\x00d\x01\x00k\x05\x00r\x10\x00d\x02\x00Sd\x03\x00S’

这是字节码组成的字节串,让我们把它转换成二进制

list(bytearray(sample.__code__.co_code)) [124, 0, 0, 100, 1, 0, 107, 5, 0, 114, 16, 0, 100, 2, 0, 83, 100, 3, 0, 83]

看,这写依然无法理解,这时我们借助标准库 dis(自节码反汇编器) 来查看字节码

dis.dis(sample)

1
2
3
4
5
6
7
8
9
10
2           0 LOAD_FAST                0 (n)
3 LOAD_CONST 1 (1)
6 COMPARE_OP 5 (>=)
9 POP_JUMP_IF_FALSE 16

3 12 LOAD_CONST 2 (True)
15 RETURN_VALUE

4 >> 16 LOAD_CONST 3 (False)
19 RETURN_VALUE

总共分为五列,分别是

  • 字节码对应的在源代码中的行号
  • 该字节码在字节码串中的第几个字节,也就是该字节码的索引
  • 字节码的人类可读的名字
  • 字节码参数
  • 字节码参数的内容提示

再看

dis.opname[124] ‘LOAD_FAST’ dis.opname[100] ‘LOAD_CONST’

这样我们就可以和之前的字节码对应了。当然这还没有完,我们还不理解这些操作码代表什么含义,打开 python文档 搜索 LOAD_FAST,你可以看到是将 co_varnames[var_num] 放进堆栈中(更高级的目前我也是看不懂),

Python 使用两个字节表示指令参数,如果Python使用一个字节,每个 code object 你只能有256个,而用两个字节,就增加到了256的平方,65536个

Frame

Frame 包含了一段代码运行所需要的信息与上下文环境。Frame 在代码执行时被动态地创建与销毁,每一个 Frame 的创建对应一次函数调用,所以每一个 Frame 都有一个 code object 与其关联,同时一个code object 可以拥有多个 Frame,因为一个函数可以递归调用自己多次。

比如你有一个函数递归的调用自己10次,这时有11个 frame。总的来说 Python 程序的每个作用域有一个 frame,比如每个 module、每个函数调用、每个类定义。这跟数据栈是不同的。

未完待续

It’s interesting

Python 扩展

Python 和 C 粘合性很好,用 C 给 Python 添加扩展一般是性能问题,另外就是想要加密部分可以编译成二进制,保证源码不会泄露。

C Extending Moudle

C 扩展大概就是使用 Python 提供的方法将 C 代码在封装一遍。Python 提供了 Python.h 头文件,使用这些接口将 C 进行包装,最后编译成 so 文件(在windows下是dll)

编写 C 扩展需要三部分,缺一不可。

  • 导出函数
  • 方法列表
  • 初始化函数

Example

最主要的是先封装C函数,接下来举个例子,我的系统是 Ubuntu 14.04,Python2.7

定义函数

比方用 C 写一个两数相加的方法 plus,文件名为 sample.c

1
2
3
4
int plus(int n, int m)
{
return n + m;
}

导出函数

将该方法使用 Python 提供的API封装,首先导入头文件 Python.h

1
2
3
4
5
6
7
8
9
10
#include <Python.h>

static PyObject* wrap_plus(PyObject* self, PyObject* args)
{
int n, m, result;
if (!PyArg_ParseTuple(args, "ii:plus", &n, &m))
return NULL;
result = plus(n, m);
return Py_BuildValue("i", result);
}

所有的导出函数都返回一个 PyObject 指针,如果对应的C函数没有真正的返回值(即返回值类型为void),则应返回一个全局的 None 对象(Py_None),并将其引用计数增 1

1
2
3
4
5
PyObject* method(PyObject *self, PyObject *args)
{
Py_INCREF(Py_None);
return Py_None;
}
  • PyObject 是一个能表示任何Python对象的C数据类型
  • PyArg_ParseTuple() 函数被用来将Python中的值转换成C中对应表示
  • Py_BuildValue() 函数被用来根据C数据类型创建Python对象
  • 更多接口查看文档

PyArg_ParseTuple 更多类型请看文档, ii,表示args的长度必须为2,且必须为int类型

方法列表

1
2
3
4
static PyMethodDef sampleMethods[] = {
{"plus", wrap_plus, METH_VARARGS, "Return n plus m"},
{NULL, NULL}
}
  • 方法列表中的每项由四个部分组成:方法名、导出函数、参数传递方式和方法描述
  • 方法名是从Python解释器中调用该方法时所使用的名字
  • 参数传递方式则规定了Python向C函数传递参数的具体形式,可选的两种方式是METH_VARARGS和METH_KEYWORDS
  • {NULL, NULL} 标识结束

初始化函数

1
2
3
4
5
void initsample()
{
PyObject* m;
m = Py_InitModule("sample", sampleMethods);
}

构造 module 也可以使用 PyModuleDef_HEAD_INIT 和 PyModule_Create(官方这么写的)

编译链接

gcc -fpic -c -I/usr/include/python2.7 -I /usr/lib/python2.7/config-x86_64-linux-gnu sample.c gcc -shared -o sample.so sample.o cp sample.so /python/python/site-packages/

或者使用 distutils 安装

参考

rsync 使用

当我还在使用 pycharm 做开发的时候,经常会使用 rsync 来同步本地和服务器上的代码,因为比传统的 scp 更为节省流量,只上传有改动的部分。

Usage

只简单介绍,毕竟文档是最好的老师。rsync 包括服务器端和客户端,服务器可以指定相应配置文件。

rsync –daemon –config=/path/to/rsyncd.conf

可以配置权限以及应用的启动信息。使用默认配置即可。

rsync 支持 ssh、scp 等文件传输方式,也可以直接使用 socket 连接来传输。那么举个例子(Unix 环境下)

rsync -avz -e “ssh -p $portNumber” user@remoteip:/path/to/ /local/path/

我使用 ssh 协议,将本地的 /local/path/ 同步到 远端服务器 /patg/to/ 下。

  • a 相当于 rlptgoD,r 是递归、l 是链接文件、p 表示保持文件原有权限、t 保持文件原有时间、g 保持文件原有用户组、o 保持文件原有属主、D 相当于块设备文件
  • z 传输时压缩
  • v 传输时的进度信息
  • e 制定使用 rsh,ssh 方式进行数据传输

rsync 算法

rsync 核心算法是 rolling checksum,核心在 rolling 上,把文件按照相同大小分块,然后分块 checksum,来比较每一块的 checksum 有没有改变。

如果这样,改变文件中间的一个字节,后面的每块都会改变。所以关键在意 rolling 上。当找不到匹配时,算法就要向后移一个字节。知道找到匹配为止。

不盗图了,传送门 https://coolshell.cn/articles/7425.html

如果是这样的话,当文件越多时,所需要花费的时间越长。同步代码使用还是可以的。如果是需要发布的代码还是建议使用 git hook。

部署工具介绍

Python 是可以直接运行一个 Python Web Server 的,Python -m SimpleHTTPServer 8000就可以启动一个监听 8000 端口的 Web Server,不像是 php 需要一个 Web Server来配合开发。

Python 的 Web 框架有很多,最具名气的是 Django,flask,tornado,web.py 等,当写一个小的项目的时候我们会直接通过框架提供的启动方式。当要正式部署一个 Web Server时并不能使用如此粗暴的方式,Server 很容易出现异常就挂掉。那么解决方案有很多。

以下是软件介绍,都可使用 pip 直接安装。

Supervisor

Supervisor 是很强大的进程管理工具,也是守护进程,帮你管理服务器上所运行的程序,守护程序防止被杀掉。可以通过写配置文件来批量启动你的 Web Server。

Gunicorn

一款 Wsgi HTTP Server,据说是比 uwsgi 更加高效,但是实测并没有 uwsgi 强。但是部署应用简单。

example: test.py

1
2
3
4
5
6
7
8
9
10
def app(environ, start_response):
"""Simplest possible application object"""
data = 'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type','text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])

gunicorn –workers=2 test:app

启动方便,具体参数请看 gunicorn 文档 http://docs.gunicorn.org/en/latest/

uWsgi

这是我要说的重点,自测吞吐量是其他两种部署方式的两倍。

使用 Flask,uWsgi 和 Nginx 来部署 Server

flask run.py

1
2
3
4
5
6
7
import Flask

app = Flask(__name__)

@app.route('/')
def index():
return "Hello World!"

uwsgi 支持 xml,json,ini 等多种配置文件,我们来配置 testapp.ini

uwsgi testapp.ini

1
2
3
4
5
6
[uwsgi]
socket = /var/run/testapp.sock
venv = /path/to/python
wsgi-file = run.py
callable = app
chmod-socket = 666

/var/run 必须有可写权限,chmod-socket 是避免 nginx 无法读写导致502错误,接下来配置nginx

nginx server.conf

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name localhost;

location / {
include uwsgi_params;
uwsgi_pass unix:/var/run/testapp.sock;
}
}

这样可以成功部署了,访问 curl http://localhost 输出 Hello World! 部署成功。

更多可以看文档https://uwsgi-docs.readthedocs.io/en/latest/

与 Nginx 配合使用效果更好

早起最流行的是 LAMP,记得初学 Linux 让我们编译 LAMP,一干就是一天。慢慢的 Shell 用的都很熟练了。但是 Apache 用起来就很复杂,第一次使用 Apache 和 Django 部署搞 wsgi_mod 花了很长时间。之后使用了 Nginx 才算是彻底在部署 Web Server 上解放。配置简单,部署方便,轻量且强大。

Nginx 是不可少的,路由管理、静态文件管理,Gzip,HTTPS、HTTP2/SPDY、ETAG 都需要 Nginx 来 handle。

测试

使用 ab 测试工具 ab -c 10 -n 100 http://localhost/ 模拟10人请求 localhost 100次。

守护进程

Web Server 使用 uwsgi 或者 gunicorn ,都是需要守护进程来守护 Server 不被杀掉。这时再使用 supervisor 就可以了。

这篇文章不是讲教你怎么搭建无线热点的,毕竟不是很难的东西,网上都可以搜到相关的博客,毕竟搭建一次写个脚本就可以了。

从 Mac 讲起

公司刚刚搬家,周围 WiFi 信号颇多,Mac 并没有有线网卡,无线真的是卡的要死,ping网关有时都能达到两万毫秒时,这种延迟是要命的,一般都会连到内网服务器上写代码,这种延迟都是会被卡掉的,要是玩游戏的话都可以摔键盘了。

使用网卡转USB

leader 一直是这样上网的,毕竟会比无线稳定很多,但是买转换器也是一笔不必要的支出。网上搜搜一般在三十块钱左右,并不知道好不好用。引入一样新的东西就会增加事物的复杂度。

使用无线路由器

家中有个闲置的无线路由器,在家只是做WDS桥接网络,未免有些浪费。想拿过来连接有线再单独开出来个私有的 WiFi,这样会比之前的稳定多,但是发射出来的 WiFi 信号未免会干扰其他信号,使得别人网络更加差劲。

树莓派搭建无线热点

这不是教程,我找到一篇不错的教程,也不至于再写一遍,只做一些提示。

我的是 raspberry pi 2,安装的 debian 的系统,这样的搭建方法也适用于基于 debian的一些系统,比如 ubuntu。

还有在设置 WIFI 信道的时候是很有讲究的,尽量使用范围内 WIFI 信号岔开5个信道的值,比如1,6,11。

搭建热点使用的软件基本上都是 hostapd,搭建方法应该也适用大多的 linux 发行版,在搭建前要注意自己的无线网卡型号,可以使用 lsusb、lsmod 来查看无线网卡的具体型号,我的是 RTL8188C,是支持开启 WIFI 热点的,但是 hotspot 是不支持的,需要替换成兼容版本。

下面这个教程步骤非常详细,特别提示也很多。

有疑问的话,可以直接在评论中讨论。