首發於個人gitpages博客 https://helenawang.github.io/2018/10/10/代碼類似度計算框架調研git
代碼類似度計算是一個已有40年研究歷史的問題了。它的應用範圍普遍,主要包括代碼抄襲檢測[3]、軟件維護中的類似代碼查找等。
Whale[1]於1988年首次提出一個代碼類似性檢測的通用框架和步驟,將檢測過程分爲如下兩個階段:github
代碼格式轉換 + 類似度肯定算法
後來不少檢測方法都參考這一框架,並將檢測過程細分爲四個部分:安全
預處理 -> 中間代碼轉換 -> 比較單元生成 -> 匹配算法markdown
參考以上算法,我把代碼類似度計算的技術按照以下三個指標分類數據結構
中間表示 + 比較單元 + 匹配算法框架
綜述中[2][3]對中間表示的總結經常把這個中間表示的內容(承載了代碼的什麼信息)和形式(用了什麼樣的數據結構)混在一塊兒。對此,我想作一個把內容與形式分離的總結。ci
先總結代碼中有哪些信息能夠被提取出來用於類似度計算,包括:get
這些信息在被具體定義並準確提取後,能夠構成中間表示的內容。其中有些信息是具備一些自然的數據結構的。以下表所示:同步
信息 | 數據結構 | 具體表示實例 |
---|---|---|
詞法信息 | 線性結構 | Token流 |
語法信息 | 樹形結構 | 抽象語法樹(AST) |
統計屬性信息 | 數值向量結構 | 保留字計數向量 |
控制流信息 | 有向圖結構 | 控制流圖(CFG) |
數據流信息 | 有向圖結構 | 數據流圖(DFG) |
學過數據結構的同窗應該記得,課本[4]將數據結構的邏輯結構分爲三類:線性結構(如向量、列表)、半線性結構(樹)與非線性結構(圖)。
以上三類結構並非相互獨立的關係,而是有層次的關係。我認爲,它們按照複雜程度和轉換層次,能夠表示爲以下的遞進關係:
線性結構 -> 樹結構 -> 圖結構
其中,高層次的結構能夠經過分解爲若干低層次的結構,而低層次的結構也能夠經過組合獲得高層次的結構。具體來講,樹結構能夠經過遍歷序列化爲線性結構,而線性結構也能夠經過合併節點轉化爲樹結構或圖結構。
基於這個不一樣結構之間可轉化的特性,不管咱們的中間表示多麼複雜,均可以轉化爲低層次的結構來作匹配。我認爲這也是論文[2]中提出的把「中間表示」與「比較單元」區分開來的緣由。而對於不一樣結構的匹配算法,這實際上是數據結構與算法領域研究的內容了。
除了計算複雜度上的差別,我認爲,不一樣的中間表示對源代碼結構的反映程度也是不一樣的。
更高層次的結構承載的代碼結構信息更多,也更接近源程序的結構,但這些結構比較複雜,不利於計算機處理;相反,較低層次的結構更便於計算機處理,但包含的信息過於抽象籠統,不能反映代碼結構的全貌。
針對個人特定業務場景找到最適配的中間表示與比較單位,是我近期的目標。
代碼類似度計算的一個主要應用是軟件抄襲檢測[3]。
綜述[3]給出了軟件抄襲檢測領域的幾個挑戰和將來研究方向,包括:
- 部分抄襲問題
- 抄襲定位及證據生成
對於這兩個方向,我認爲能夠嘗試引入其餘領域的方法論,好比信息檢索和知識工程。具體怎樣融合我會在後續的博客文章中介紹。
[1] Whale, Geoff and University of New South Wales. Department of Computer Science Plague : plagiarism detection using program structure. School of Electrical Engineering and Computer Science, University of New South Wales, [Sydney], 1988.
[2] 熊浩,晏海華,郭濤,等. 代碼類似性檢測技術:研究綜述[J]. 計算機科學, 2010, 37(8): 9-14, 76.
[3] 田振洲,劉烴,鄭慶華,等. 軟件抄襲檢測研究綜述[J]. 信息安全學報, 2016, 1(3): 52-76.
[4] 鄧俊輝. 數據結構(C++語言語言版 第3版). 2013
第一次在博客園發佈markdown格式的隨筆,效果還不錯。之後的博客會同步在gitpages和博客園上發佈,歡迎關注。