Nghiên cứu phương pháp xác định mức độ tương tự giữa các mã nguồn dựa vào cây cú pháp

Luận văn thạc sĩ nghiên cứu phương pháp xác định mức độ tương tự giữa các mã nguồn dựa vào cây cú pháp, cung cấp kiến thức chuyên sâu và ứng dụng thực tiễn.

Chuyên ngành

Hệ thống thông tin

Người đăng

Ẩn danh

Thể loại

luận văn thạc sĩ kỹ thuật

2022

85
2
0

Phí lưu trữ

30 Point

Mục lục chi tiết

LỜI CAM ĐOAN

1. CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN

1.1. Tổng quan về sao chép và sử dụng lại mã nguồn

1.1.1. Vấn đề sao chép và sử dụng lại mã nguồn

1.1.2. Những tác động của sao chép và sử dụng lại mã nguồn

1.1.3. Ý nghĩa của việc đánh giá mức độ tương tự giữa các mã nguồn

1.1.4. Giới thiệu các kiểu sao chép mã nguồn phổ biến

1.2. Đánh giá chương trình xác định mức độ tương đồng giữa các mã nguồn

1.2.1. Khái niệm ma trận nhầm lẫn (Confusion Matrix)

1.2.2. Biểu diễn đường cong ROC

1.3. Cây cú pháp trừu tượng (AST, abstract syntax tree)

1.3.1. Tổng quan về các công nghệ so sánh mã nguồn phổ biến

1.3.2. Khái niệm về cây cú pháp trừu tượng (AST, abstract syntax tree)

1.3.3. Các phần mềm sinh ra cây cú pháp AST

1.3.4. Tổng quan về LLVM (Low-Level Virtual Machine)

1.3.5. Tổng quan về Clang

1.3.6. Sử dụng Clang với Python

1.4. So sánh cây AST khi áp dụng các thủ thuật sao chép khác nhau

1.4.1. Thay đổi định dạng hoặc thêm/sửa các “comment code”

1.4.2. Đổi tên các định danh (hàm, tham số và biến)

1.4.3. Thay đổi thứ tự các toán hạng trong biểu thức

1.4.4. Thay đổi kiểu dữ liệu (data types)

1.4.5. Thay thế giữa các biểu thức tương đương

1.4.6. Bổ sung các đoạn mã nguồn không có giá trị (dead-code)

1.4.7. Thay đổi thứ tự của những đoạn mã nguồn độc lập

1.4.8. Thay thế một câu lệnh lặp bằng một câu lệnh tương đương

1.4.9. Thay đổi các câu lệnh rẽ nhánh tương đương

1.4.10. Thay thế các lệnh gọi hàm bằng chính nội dung của hàm

1.4.11. Kết hợp đoạn mã nguồn sao chép với mã nguồn tự viết

1.5. Kết luận chương 1

2. CHƯƠNG 2: PHƯƠNG PHÁP ĐÁNH GIÁ ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN

2.1. Tiền xử lý cây AST trước khi thực hiện đánh giá

2.1.1. Gộp thông tin tại các nút

2.1.2. Chuyển AST sang dạng chuỗi (xâu)

2.2. Các phương pháp đánh giá mức độ tương tự giữa các mã nguồn

2.2.1. Tìm xâu con chung dài nhất (LCS - Longest common subsequence)

2.2.1.1. Lý thuyết về LCS
2.2.1.2. Phương pháp LCS
2.2.1.3. Ứng dụng LCS để so sánh 2 cây AST
2.2.1.4. Đánh giá hiệu quả sử dụng LCS

2.2.2. TF-IDF và Độ tương tự Cosin

2.2.2.1. Lý thuyết về TF-IDF
2.2.2.2. Phương pháp TF-IDF
2.2.2.3. Lý thuyết về Mô hình không gian vector (Vector space model)
2.2.2.4. Lý thuyết về Độ tương tự Cosin (Cosine similarity)
2.2.2.5. Ứng dụng TF-IDF và Độ tương tự Cosin để so sánh 2 cây AST
2.2.2.6. Đánh giá hiệu quả sử dụng TF-IDF và Độ tương tự Cosin

2.2.3. Tổng quan về AST-CC

2.2.4. Các bước thực hiện AST-CC

2.3. Kết luận chương 2

3. CHƯƠNG 3: THỰC NGHIỆM VÀ ĐÁNH GIÁ

3.1. Cài đặt hệ thống để so sánh độ tương tự giữa các mã nguồn

3.1.1. Cài đặt Python

3.1.2. Cài đặt thư viện Clang

3.2. Xây dựng công cụ so sánh mã nguồn với 3 thuật toán LCS, TF-IDF, AST-CC

3.2.1. Mã nguồn hiển thị cây AST

3.2.2. Mã nguồn so sánh 2 cây AST theo phương pháp LCS

3.2.3. Mã nguồn so sánh 2 cây AST theo phương pháp TF-IDF

3.2.4. Mã nguồn so sánh 2 cây AST theo phương pháp AST-CC

3.3. Thực nghiệm hệ thống với dữ liệu đầu vào đã gán nhãn (phân loại)

3.3.1. Sử dụng phương pháp LCS

3.3.2. Sử dụng phương pháp TF-IDF

3.3.3. Sử dụng phương pháp AST-CC

3.3.4. Nhận xét, đánh giá

3.4. Thực nghiệm hệ thống với dữ liệu đầu vào chưa phân loại

3.4.1. Sử dụng phương pháp LCS

3.4.2. Sử dụng phương pháp TF-IDF

3.4.3. Sử dụng phương pháp AST-CC

3.4.4. Nhận xét, đánh giá

3.5. Kết luận chương 3

DANH MỤC CÁC TÀI LIỆU THAM KHẢO

Tóm tắt

I. Tổng quan về nghiên cứu mức độ tương tự giữa các mã nguồn

Nghiên cứu mức độ tương tự giữa các mã nguồn là một lĩnh vực quan trọng trong công nghệ thông tin. Việc xác định mức độ tương tự giúp phát hiện sao chép mã nguồn, từ đó nâng cao chất lượng đào tạo và phát triển phần mềm. Cây cú pháp trừu tượng (AST) là một công cụ hữu ích trong việc phân tích mã nguồn, cho phép so sánh cấu trúc và nội dung của các đoạn mã.

1.1. Ý nghĩa của việc xác định mức độ tương tự giữa các mã nguồn

Việc đánh giá mức độ tương tự giữa các mã nguồn giúp phát hiện sao chép, hỗ trợ giảng viên trong việc đánh giá chất lượng học tập của sinh viên. Điều này cũng giúp lập trình viên cải tiến mã nguồn, tối ưu hóa hiệu suất và phát hiện các đoạn mã không tốt.

1.2. Các kiểu sao chép mã nguồn phổ biến

Có nhiều kiểu sao chép mã nguồn, từ việc thay đổi định dạng, thêm ghi chú, đến việc thay đổi tên biến và cấu trúc mã. Những kiểu sao chép này có thể làm giảm khả năng sáng tạo của sinh viên và ảnh hưởng đến chất lượng đào tạo.

II. Vấn đề và thách thức trong việc xác định mức độ tương tự

Mặc dù việc xác định mức độ tương tự giữa các mã nguồn mang lại nhiều lợi ích, nhưng cũng tồn tại nhiều thách thức. Việc phát hiện sao chép chính xác là một nhiệm vụ khó khăn, đặc biệt khi các đoạn mã đã được chỉnh sửa. Điều này đòi hỏi các phương pháp phân tích mạnh mẽ và chính xác.

2.1. Thách thức trong việc phát hiện sao chép mã nguồn

Việc phát hiện sao chép mã nguồn gặp khó khăn do các lập trình viên thường thay đổi một số chi tiết nhỏ để tránh bị phát hiện. Điều này làm cho việc so sánh trở nên phức tạp hơn.

2.2. Tác động của sao chép mã nguồn đến chất lượng phần mềm

Sao chép mã nguồn có thể dẫn đến việc gia tăng lỗi trong phần mềm, gây khó khăn cho quá trình bảo trì và phát triển. Điều này ảnh hưởng đến chất lượng sản phẩm cuối cùng và sự hài lòng của người dùng.

III. Phương pháp xác định mức độ tương tự giữa các mã nguồn

Có nhiều phương pháp để xác định mức độ tương tự giữa các mã nguồn, trong đó cây cú pháp trừu tượng (AST) là một trong những công cụ hiệu quả nhất. Các phương pháp như LCS, TF-IDF và AST-CC đã được áp dụng để so sánh mã nguồn.

3.1. Phương pháp LCS trong so sánh mã nguồn

Phương pháp tìm độ dài dãy con chung dài nhất (LCS) giúp xác định các đoạn mã tương tự bằng cách so sánh cấu trúc và nội dung của mã nguồn. Đây là một trong những phương pháp phổ biến nhất trong phân tích mã nguồn.

3.2. Ứng dụng TF IDF trong đánh giá mã nguồn

Phương pháp TF-IDF giúp đánh giá mức độ tương tự giữa các mã nguồn dựa trên tần suất xuất hiện của các từ khóa trong mã. Điều này giúp phát hiện các đoạn mã tương tự một cách hiệu quả.

3.3. Phương pháp AST CC và ưu điểm của nó

AST-CC là một phương pháp mới giúp so sánh mã nguồn dựa trên cây cú pháp trừu tượng. Phương pháp này cho phép phát hiện các đoạn mã tương tự một cách chính xác và nhanh chóng.

IV. Ứng dụng thực tiễn của nghiên cứu mức độ tương tự

Nghiên cứu mức độ tương tự giữa các mã nguồn không chỉ có ý nghĩa lý thuyết mà còn có nhiều ứng dụng thực tiễn. Các phần mềm phát hiện sao chép mã nguồn đã được phát triển và áp dụng rộng rãi trong giáo dục và công nghiệp.

4.1. Ứng dụng trong giáo dục

Trong môi trường giáo dục, việc phát hiện sao chép mã nguồn giúp giảng viên đánh giá chất lượng học tập của sinh viên. Điều này cũng khuyến khích sinh viên tự học và phát triển kỹ năng lập trình.

4.2. Ứng dụng trong phát triển phần mềm

Trong ngành công nghiệp phần mềm, việc xác định mức độ tương tự giữa các mã nguồn giúp lập trình viên cải tiến mã nguồn, tối ưu hóa hiệu suất và phát hiện các đoạn mã không tốt.

V. Kết luận và tương lai của nghiên cứu

Nghiên cứu phương pháp xác định mức độ tương tự giữa các mã nguồn dựa vào cây cú pháp là một lĩnh vực đang phát triển mạnh mẽ. Tương lai của nghiên cứu này hứa hẹn sẽ mang lại nhiều giải pháp mới và hiệu quả hơn trong việc phát hiện sao chép mã nguồn.

5.1. Xu hướng phát triển trong nghiên cứu

Các nghiên cứu trong tương lai có thể tập trung vào việc phát triển các thuật toán mới, cải thiện độ chính xác và hiệu suất của các phương pháp hiện tại.

5.2. Tầm quan trọng của việc bảo vệ bản quyền mã nguồn

Việc xác định mức độ tương tự giữa các mã nguồn không chỉ giúp phát hiện sao chép mà còn bảo vệ quyền sở hữu trí tuệ của các lập trình viên. Điều này ngày càng trở nên quan trọng trong bối cảnh công nghệ thông tin phát triển nhanh chóng.

17/07/2025

Trích đoạn nội dung tài liệu

CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN.1: Không gian ROC Đường chéo nét đứt từ tọa độ (0,0) tới (1,1) đại diện cho phép dự đoán ngẫu nhiên, chia không gian ROC thành 2 phần theo 2 chiều hướng tốt hơn và xấu hơn. Tức là những phép dự đoán cho kết quả nằm phía trên đường chéo được đánh giá là có kết quả tốt hơn so với các phép dự đoán cho kết quả nằm dưới đường chéo, phép đo có kết quả càng gần với đỉnh trên bên trái (0,1) thì càng tiệm cận tới phép đo “hoàn hảo”. Tập hợp kết quả các lần dự đoán của một hệ thống dự đoán sẽ tạo thành một đường cong trong không gian ROC, thường được gọi là “đường cong ROC”. 10 Hình CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN.2: Đường cong ROC Một số tính chất của đường cong ROC:  Đường cong càng đi dọc theo biên trái và rồi đi dọc theo biên phía trên của không gian ROC, thì chứng tỏ kết quả kiểm tra càng chính xác.

 Đường cong càng tiến tới thành đường chéo 45 độ trong không gian ROC, thì độ chính xác của kiểm tra càng kém.  Hệ số góc của đường thẳng tiếp tuyến tại một điểm cutpoint cho ta tỉ lệ likelihood ratio (LR) của giá trị cutpoint đó của bài kiểm tra.  Diện tích phía dưới đường cong, giới hạn trong không gian ROC, là thước đo cho độ chính xác của bài kiểm tra, chẳng hạn: 1 là tối ưu, 0. Phần diện tích này có ý nghĩa là thước đo cho khả năng phân biệt (discrimination) tốt hay không.

Dựa vào tính chất trên, chúng ta có thể so sánh kết quả của những chương trình đánh giá mức độ tương tự bằng cách vẽ đường cong ROC tương ứng với mỗi chương trình, chương trình nào cho đường cong ROC nằm trên thì được đánh giá có khả năng dự đoán chính xác hơn. Cây cú pháp trừu tượng (AST, abstract syntax tree) 1.1 Tổng quan về các công nghệ so sánh mã nguồn phổ biến Trong giai đoạn đầu nghiên cứu về vấn đề sao chép, công nghệ chủ yếu để phát hiện ra một bản sao là dựa trên nội dung của văn bản. Phương pháp này rất đơn giản là xác định xem hai tệp tương tự bằng cách so sánh các giá trị được tính toán của các tệp. Nhưng giải pháp này chỉ có thể phát hiện khi sao chép mà không có sửa đổi.

Với sự phát triển của công nghệ, nhiều nghiên cứu trong lĩnh vực này đã đề xuất rất nhiều thuật toán và phương án khác nhau. Đến nay có nhiều phần mềm, công cụ giúp phân tích và phát hiện trùng lặp trong mã nguồn, tuy nhiên về cơ bản đều thuộc một trong 4 trường phái sau: Dựa trên phân tích văn bản thuần túy (string-based): Mã nguồn được chuyển thành các chuỗi liên tiếp ký tự. Hai mã nguồn được coi là tương tự nhau nếu chúng bao gồm các chuỗi ký tự giống nhau. Thuật toán chính được sử dụng trong công nghệ này là thuật toán tìm chuỗi con dài nhất (LCS).

Nhưng rõ ràng thuật toán có những hạn chế, chỉ khi tất cả các chuỗi giống nhau, hai mã nguồn mới có thể được coi là tương tự. Dựa trên phân tích chuỗi ký tự đại diện (token-based): Công nghệ này được cải tiến từ việc phân tích mã nguồn dựa trên văn bản thuần túy trình bày phía trên. Mã nguồn chương trình lúc này được tách từ thành chuỗi các token, sau đó thực hiện quét và kiểm tra các chuỗi token trùng nhau để xác định khả năng xảy ra lặp, sao chép mã nguồn. So với hướng tiếp cận trên, hướng tiếp cận này mạnh hơn trong việc phát hiện các đoạn mã nguồn lặp cho dù mã nguồn đã được sửa chữa đôi chút.

Các công cụ phát hiện sao chép mã nguồn tiêu biểu theo trường phái này gồm: CP-Mine, CCFinder, Jplag. Tuy nhiên các công cụ này đều có nhược điểm không thể phát hiện khi mã nguồn có sự thay đổi như thay đổi tên hàm, biến, thứ tự các đoạn code độc lập, hay chèn thêm các đoạn code vô nghĩa. Dựa trên cấu trúc cây (tree-based): Đây là công nghệ mới được đề cập và phát triển nhanh trong những năm gần đây. Việc so sánh các mã nguồn dựa trên cấu trúc của nó là hướng đi rất hợp lý, khi mà nó có thể bằng cách này hay cách khác để loại bỏ sự ảnh hưởng bởi những thao tác như: đổi tên hàm, tên biến, thứ tự code… Do ưu điểm của phương pháp tiếp cận này, nên các thuật toán trong luận văn này tập trung vào việc phân tích mã nguồn dựa trên cấu trúc cây.

12 Dựa trên biểu đồ phụ thuộc (Program Dependence Graph - PDG): Một số nghiên cứu chỉ ra rằng các thủ thuật sao chép mã nguồn không làm thay đổi nhiều đối với biểu đồ phụ thuộc của mã nguồn gốc. Do đó việc tiếp cận PDG trong phân tích đánh giá mức độ tương tự giữa các mã nguồn là một ý tưởng rất thú vị. Trong khuôn khổ của luận văn này, tác giả không trình bày về các giải thuật liên quan đến phương pháp tiếp cận này.2 Khái niệm về cây cú pháp trừu tượng (AST, abstract syntax tree) Trong ngành khoa học máy tính, cây cú pháp trừu tượng (AST, abstract syntax tree), là cấu trúc dữ liệu được sử dụng rộng rãi trong trình biên dịch, do thuộc tính đại diện cho cấu trúc của mã chương trình. AST thường là kết quả của giai đoạn phân tích cú pháp của trình biên dịch [11].

AST là cấu trúc cây mà các nút gốc của cây được gán nhãn bằng các toán tử và các nút là của cây là các toán hạng. Trong các công đoạn của chương trình dịch, cây AST này được dùng trong bộ phân tích cú pháp như là một trung gian giữa cây phân tích cú pháp (concrete syntax tree) và cấu trúc dữ liệu. Cây cú pháp trừu tượng khác với cây phân tích cú pháp là ở chỗ nó không chỉ quan tâm đến cú pháp mà còn quan tâm đến ngữ nghĩa của chương trình. Hãy cùng xem xét ví dụ đoạn mã nguồn sau (ngôn ngữ C++): void fun1(){ int a = 2; int b = 5; fun2(a, b); } Về cơ bản đoạn mã nguồn này có cây AST như sau: 13 Hình CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN.3: Cây cú pháp trừu tượng của mã nguồn hàm func 1.3 Các phần mềm sinh ra cây cú pháp AST Mỗi ngôn ngữ lập trình có những công cụ complier khác nhau (ví dụ Java có Java Complier Complier – JavaCC hoặc JJTree, Javascript có JIT, C++ có GCC hoặc Clang).

Tương ứng với mỗi công cụ này, sẽ có các công cụ xây dựng cây cú pháp AST khác nhau. Ngoài ra hiện nay trên internet đã có những công cụ trực tuyến cho phép xem trực tiếp cây cú pháp của một đoạn mã nguồn ngay trên trình duyệt web tại địa chỉ sau: https://astexplorer. Công cụ này hỗ trợ nhiều ngôn ngữ lập trình như PHP, Python, Lua, Javascript. Trong phạm vi luận văn này, do chỉ tập trung vào ngôn ngữ C++ nên chọn lựa trình biên dịch Clang trong bộ khung biên dịch LLVM để phục vụ cho việc xây dựng cây AST từ các mã nguồn viết bằng ngôn ngữ C++.

Dưới đây là một số thông tin tổng quan về LLVM và Clang.4 Tổng quan về LLVM (Low-Level Virtual Machine) LLVM là một bộ khung biên dịch (compiler framework) được sử dụng để tối ưu hóa mã cho nhiều ngôn ngữ lập trình khác nhau. Nó cung cấp những công cụ mạnh mẽ để xây 14 dựng phần front-end (parser, lexer) cũng như phần backend (phần chuyển phần code trung gian LLVM sang mã máy), cho các ngôn ngữ lập trình mới [12]. Xuất phát từ khái niệm Low-Level Virtual Machine - Máy ảo cấp thấp, LLVM thường được xem là một khung để tạo nên các trình biên dịch được thiết kế để hỗ trợ phân tích và chuyển đổi chương trình suốt đời, suốt đời cho các chương trình tùy ý, bằng cách cung cấp thông tin cấp cao để chuyển đổi trình biên dịch tại thời điểm compile-time, link-time, run- time và idle time giữa các lần chạy. LLVM cung cấp những công cụ mạnh mẽ để xây dựng phần front-end (parser, lexer) cũng như phần backend (phần chuyển phần code trung gian LLVM sang mã máy), cho các ngôn ngữ lập trình mới.

LLVM đã được sử dụng để xây dựng nên nhiều trình biên dịch (compiler) của nhiều ngôn ngữ lập trình cấp cao phổ biến hiện nay, ví dụ như C, C++, Python, Java, Ruby, cũng như Objective-C và Swift. Hình CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN.4: Kiến trúc nền tảng biên dịch LLVM Như được thể hiện trong hình trên, một hệ sinh thái chương trình dịch LLVM gồm 3 phần:  Front-end: nhận mã nguồn viết trên các ngôn ngữ lập trình và chịu trách nhiệm thực hiện 3 bước gồm Lexical analysis (phân tích từ tố) - đọc từng ký tự thành các token, syntax analysis (phân tích cú pháp) - Parser chuyển các token ở bước 15 trước thành AST và semantic analysis (phân tích ngữ nghĩa) - kiểm tra các thông tin khác. Đầu ra của Front-end là mã trung gian.  Middle-end: được biết đến với cái tên "LLVM Optimizer", sử dụng một ngôn ngữ lập trình cấp thấp gọi là intermediate representation (IR) làm mã trung gian.

IR được sử dụng nhằm mục đích chuyển đổi giữa kết quả của phần Front- end sang Back-end để có thể tạo mã máy.  Back-end: chịu trách nhiệm tạo ra mã máy từ mã trung gian cho từng kiến trúc CPU cụ thể. Hình CHƯƠNG 1: TỔNG QUAN VỀ BÀI TOÁN ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TỰ GIỮA CÁC MÃ NGUỒN.5: Luồng xử lý từ frontend  middle-end  back-end Nhờ thiết kế độc lập của 3 thành phần dạng module, LLVM giúp các nhà phát triển rất dễ hỗ trợ thêm ngôn ngữ front-end mới, cũng như hỗ trợ cho các kiến trúc CPU mới ở phía back-end, ngay cả những kiến trúc không tồn tại ở thời điểm ứng dụng ra đời. Cùng với nhiều công cụ mạnh mẽ khác, dự án LLVM mang đến sức mạnh, tốc độ, an toàn cùng với tiện lợi cho hầu hết các ngôn ngữ hiện đại ngày nay.5 Tổng quan về Clang Clang là một trình biên dịch (compiler front-end) sử dụng cơ sở hạ tầng trình biên dịch LLVM cho các ngôn ngữ lập trình C, C ++, Objective-C và Objective-C ++ [13].

Clang được thiết kế để hoạt động như một sự thay thế cho Bộ trình dịch GNU (GNU Compiler Collection - GCC). Clang được đóng góp và hỗ trợ bởi các tổ chức uy tín như Apple, Microsoft, Google, ARM, Sony, Intel và Advanced Micro Devices (AMD). Đây là 16 phần mềm nguồn mở, với mã nguồn được phát hành theo Giấy phép của Đại học Illinois / NCSA.

Nội dung được bảo vệ bản quyền — Tải xuống đầy đủ