Python程序打包并绑定CPU

你的Python程序写好了,该如何发布呢?最简单的当然是发布源代码,这也是开源世界推崇的方式。可是,有时候,给最终用户代码是不切实际的,让人挠头的。比如,

 

你用python给你的女朋友写了个小软件,还带GUI界面,女朋友很喜欢它,也更喜欢了你。然后,你把源代码给她,给她安装好Python,然后教她如何进到源代码的目录,如何运行这个Python代码。。。如果是这样,女朋友会疯的,对你的好感度也会直线下降。你需要做的是,给她一个可执行文件,双击即可使用。

 

再比如,

 

你用Python实现了客户的需求,要把程序部署到客户那里。但是,你想保护你这部分代码里面的算法。或者不想客户把代码改来改去增加你的客服量。

 

这些时候,你需要打包你的Python程序。Python打包程序有很多,比如Windows上的py2exe,跨平台的pyinstaller等等。在这里,强烈推荐一下pyinstaller打包。非常简洁也非常强大,Windows、Linux、Mac通吃。

 

$ pyinstallter -F –key password main.py

 

一行命令就把main.py 打包成一个独立(-F 选项)的可执行文件,顺便还加了个密(–key 选项)。

 

如果你只是想打包Python程序,看到这里就可以了,赶紧去学习Pyinstaller打包技能吧。

 

但是,你给客户的程序合同上写的是单台机器授权,多台机器再加钱。有人的地方就有利益,有利益的地方就要考验人性,自己要做到守信但也要防一下客户。程序给了客户,你完全不能控制他不在别的机器上跑你的程序。这时候,你就想要把程序跟硬件绑定。

 

可以绑定的硬件信息有很多,比如mac地址、硬盘、主板等等。mac地址容易修改,硬盘和主板信息似乎不太好获取。那我们就来绑定CPU吧。

 

x86架构的CPU可以通过CPUID操作码来获取处理器的类型和特性支持(例如MMX/SSE),通过这些信息,我们就可以唯一确定CPU。这里我们不研究具体的如何通过EAX获得信息都是什么意思,详情见这里:

https://en.wikipedia.org/wiki/CPUID

 

通过研究上面这篇CPUID的词条,获取了不同的CPU信息组成一个序列号来唯一确定CPU,具体代码如下:

 

打包你的Python程序并绑定CPU

 

可以看到,这个函数对不同级别的EAX寄存器的值做了取舍(a,b,c,d四个值的一部分),这是因为,对于同一个有些值会变(比如,level == 1 时的b)。有兴趣的同学可以把注释去掉,隔几秒运行一下,看看寄存器值的变化情况。最终选取7个值的十六进制生成一个字符串作为CPU的序列号。这个序列号,即使对同一个CPU下的Virtualbox虚拟机的CPU序列号和其宿主的CPU序列号也是不同的。

 

到了这里,还不算完。咱们说的是Python,可上面是C啊。别急,先编译一下这个C代码生成一个库文件:

 

gcc -fPIC -shared cpusn.c -o cpusn.so

 

通过Python的ctypes就可以使用这个cpusn.so库来获取CPU序列号了:

 

打包你的Python程序并绑定CPU

 

运行这段python代码,就可以获得类型下面的字符串:

 

0000000D_000306A9-7FBAE3FF-BFEBFBFF_76035A01-00F0B2FF-00CA0000

 

有了这个CPU序列号,我们就可以把Python程序和CPU绑定了。在你需要绑定的程序的入口处加入你的验证流程:

 

(1)获取用户配置的授权码(比如,读取某个文件);

(2)通过cpusn.so获取当前机器的CPU序列号

(3)通过你的授权码生成算法计算当前CPU序列号对应的授权码;

(4)对比用户配置的授权码(你发给他的)和第三步计算得到的授权码,二者不一样就说明当前机器没有获得授权,随便打印些警示信息,然后就可以退出程序了。

 

加入以上验证流程后,你就可以用Pyinstaller打包你的程序,和获取CPU序列号的程序一起发给客户了。

 

客户想要运行你的程序,还有以下步骤:

 

第一步,让你客户在他的机器上运行程序获得CPU序列号并发给你,你用你的授权码生成算法生成一个授权码发个客户;

 

第二步,客户把授权码配置到程序中(比如,写入一个指定文件)就可以成功运行了。

 

最后,说说授权码生成的算法,就是把一个字符串(CPU序列号)转换成另外一个字符串(授权码):

 

授权码 = 算法(CPU序列号)

 

这个算法必须不可逆,也就是,无法通过授权码反向计算出CPU序列号。这是一个简单但可以充分发挥你想象力的算法,比如,数据库保存密码时的原则是“加盐做哈希”,这个方法就可以用在这里。

 

授权,除了绑定机器,可能还要绑定时间(比如,到年底过期)。那么,如果把时间绑定也加入到授权码算法中呢?你可以再发挥自己的想象力。

 

以上绑定的方法,主要是考虑客户那边不能访问互联网的情况。如果客户那边可以访问互联网,你的授权又该怎么做呢?环境不同,解决问题的方法就不同,无聊什么样的问题,都难不倒一个身为爱思考、善动手的程序员的你。

未经允许不得转载:996ICU » Python程序打包并绑定CPU

赞 (0) 打赏