用pyinstaller打包你的Python程式並繫結CPU

王平發表於2019-01-14

你的Python程式寫好了,該如何釋出呢?最簡單的當然是釋出原始碼,這也是開源世界推崇的方式。可是,有時候,給終端使用者程式碼是不切實際的,讓人撓頭的。

cpu

比如,

你用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獲得資訊都是什麼意思,詳情見這裡

通過研究上面這篇CPUID的詞條,獲取了不同的CPU資訊組成一個序列號來唯一確定CPU,具體程式碼如下:

c語言獲取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序列號。這是一個簡單但可以充分發揮你想象力的演算法,比如,資料庫儲存密碼時的原則是“加鹽做雜湊”,這個方法就可以用在這裡。

授權,除了繫結機器,可能還要繫結時間(比如,到年底過期)。那麼,如果把時間繫結也加入到授權碼演算法中呢?你可以再發揮自己的想象力。

以上繫結的方法,主要是考慮客戶那邊不能訪問網際網路的情況。如果客戶那邊可以訪問網際網路,你的授權又該怎麼做呢?環境不同,解決問題的方法就不同,無聊什麼樣的問題,都難不倒一個身為愛思考、善動手的程式設計師的你。

獲取繫結CPU原始碼,關注猿人學Python公眾號回覆“cpu”即可。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章