期貨量化軟件:赫茲量化系統(tǒng)利用外部應(yīng)用程序進行加密
加密在 MQL 程序中很少使用。 在日常交易中,使用密碼術(shù)的機會并不多。 一個例外就是偏執(zhí)的信號跟單機希望保護發(fā)送的數(shù)據(jù)免于監(jiān)聽,僅此而已。 若數(shù)據(jù)不會離開終端,很難想象為什么需要加密/解密數(shù)據(jù)。 甚至,這可能代表開發(fā)人員能力低下,因其造成了終端的額外負載。
也許無需在交易中使用加密? 實際上,其實有。 例如,考慮許可。 可能會有一家小型公司,甚或一位廣受歡迎產(chǎn)品的獨立開發(fā)者。 這種情況與許可問題相關(guān),因此需要許可證加密/解密。
可在許可證中指定用戶數(shù)據(jù),和產(chǎn)品的可編輯列表。 指標或智能交易系統(tǒng)開始操作,檢查許可證的可用性,及給定產(chǎn)品的期限。 程序向服務(wù)器發(fā)送請求,更新許可證,如有必要,或可接收新的許可證。 這可能不是最有效和最安全的方式,但出于演示目的,我們將在本文中運用它。 顯然,在這種情況下,許可證將通過不同的軟件工具進行讀取/寫入 — 終端,遠程服務(wù)器,控制模塊和日志記錄模塊。 它們可以由不同的人,在不同的時間,以不同的語言編寫。
本文的目的是研究加密/解密模式,在這種模式下,MetaTrader 終端可以解密由 C# 或 C++ 程序加密的對象,反之亦然。
本文適用于中等技能的程序員和初學(xué)者。
設(shè)定任務(wù)
概述中已經(jīng)提到了這一點。 我們將嘗試模擬一個實際問題的解決方案,要求為若干種產(chǎn)品(指標和智能交易系統(tǒng))的許可證創(chuàng)建、加密和解密。 對于我們而言,用哪個程序來加密和解密許可證并不重要。 例如,可以先在開發(fā)者的計算機上創(chuàng)建許可證,然后在銷售部門對其進行糾正,然后在交易者的計算機上解密。 該過程必須針對性能低廉的算法有很強的容錯性。
除了解決主要任務(wù)外,我們還將研究許可的復(fù)雜問題。 這不是一切就緒立即可用的許可證,而只是可能的變體之一,應(yīng)對其進一步進行編輯和開發(fā)。
源數(shù)據(jù)
我們參考終端文檔來獲取操作的源數(shù)據(jù)。 有兩個標準函數(shù)負責(zé)加密/解密過程:
int ?CryptEncode( ? ENUM_CRYPT_METHOD ? method, ? ? ? ?// conversion method ? const uchar& ? ? ? ?data[], ? ? ? ?// source array ? const uchar& ? ? ? ?key[], ? ? ? ? // encryption key ? uchar& ? ? ? ? ? ? ?result[] ? ? ? // destination array ? ); int ?CryptDecode( ? ENUM_CRYPT_METHOD ? method, ? ? ? ?// conversion method ? const uchar& ? ? ? ?data[], ? ? ? ?// source array ? const uchar& ? ? ? ?key[], ? ? ? ? // encryption key ? uchar& ? ? ? ? ? ? ?result[] ? ? ? // destination array ? );
開發(fā)操作對象
鑒于我們研究如何將加密/解密應(yīng)用于許可,故我們的操作對象是許可。 這應(yīng)該是一些包含可適用在許可證的各種產(chǎn)品信息的結(jié)構(gòu)。 這里需要以下數(shù)據(jù):
該產(chǎn)品的許可期限。
產(chǎn)品名稱。
我們用最簡單的方法創(chuàng)建相應(yīng)的結(jié)構(gòu):
#define PRODMAXLENGTH 255 struct ea_user ?{ ? ea_user() {expired = -1;} ? datetime expired; ? ? ? ? ? ? ? ?//License expiration (-1 - unlimited) ? int ? ? ?namelength; ? ? ? ? ? ? //Product name length ? char ? ?uname[PRODMAXLENGTH]; ? ?//Product name ? void SetEAname(string name) ? ? { ? ? ?namelength = StringToCharArray(name, uname); ? ? } ? string GetEAname() ? ? { ? ? ?return CharArrayToString(uname, 0, namelength); ? ? } ? bool IsExpired() ? ? { ? ? ?if (expired == -1) ? ? ? ? return false; // NOT expired ? ? ?return expired <= TimeLocal(); ? ? } ?};//struct ea_user
包含在用戶描述結(jié)構(gòu)中的信息:
獨有的用戶 ID。 還可以保存名稱,但每次都要發(fā)送個人數(shù)據(jù)(即使是加密形式)似乎并不可取。
用戶帳戶上可用產(chǎn)品的有關(guān)信息。
用戶的許可證到期日期。 該字段可限定所有現(xiàn)有產(chǎn)品的用法,甚至是無限制產(chǎn)品,作為用戶服務(wù)時間。
用戶終端中許可產(chǎn)品的數(shù)量:
#define COUNTACC 5 struct user_lic { ? user_lic() { ? ? ?uid ? ? ? = -1; ? ? ?log_count = ?0; ? ? ?ea_count ?= ?0; ? ? ?expired ? = -1; ? ? ?ArrayFill(logins, 0, COUNTACC, 0); ? } ? long uid; ? ? ? ? ? ? ? ? ? ? ? //User ID ? datetime expired; ? ? ? ? ? ? ? //End of user service (-1 - unlimited) ? int ?log_count; ? ? ? ? ? ? ? ? //The number of the user's accounts ? long logins[COUNTACC]; ? ? ? ? ?//User's accounts ? int ?ea_count; ? ? ? ? ? ? ? ? ?//The number of licensed products ? bool AddLogin(long lg){ ? ? ?if (log_count >= COUNTACC) return false; ? ? ?logins[log_count++] = lg; ? ? ?return true; ? } ? long GetLogin(int num) { ? ? ?if (num >= log_count) return -1; ? ? ?return logins[num]; ? } ? bool IsExpired() { ? ? ?if (expired == -1) return false; // NOT expired ? ? ?return expired <= TimeLocal(); ? } ? };//struct user_lic