import os
from Levenshtein import distance as levenshtein_distance
def read_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
def calculate_similarity(file1_content, file2_content):
distance = levenshtein_distance(file1_content, file2_content)
length = max(len(file1_content), len(file2_content))
similarity = (1 - distance / length) * 100
return similarity
def main(folder_path):
c_files = [f for f in os.listdir(folder_path) if f.endswith('.c')]
file_contents = {}
for c_file in c_files:
file_path = os.path.join(folder_path, c_file)
file_contents[c_file] = read_file(file_path)
for i in range(len(c_files)):
for j in range(i + 1, len(c_files)):
file1, file2 = c_files[i], c_files[j]
similarity = calculate_similarity(file_contents[file1], file_contents[file2])
print(f"相似度 {file1} 和 {file2}: {similarity:.2f}%")
if __name__ == "__main__":
folder_path = 'C:\\Users\\Anonymous\\Desktop\\up' # 你的文件夹路径
main(folder_path)
pip install python-Levenshtein
这个脚本首先读取指定文件夹下的所有.c文件,然后计算每对文件之间的相似度,并打印出来。相似度是基于编辑距离计算的,它表示为一个百分比,100% 表示文件完全相同,而0% 表示完全不同。
请注意,这个方法是基于文本比较的,它可能不会考虑到代码的逻辑结构。对于更高级的相似度检测,可能需要考虑使用专门的代码相似度检测工具,或者开发更复杂的算法来分析代码结构。
为了考虑代码的逻辑结构以及变量等因素,我们可以使用更高级的代码分析工具,例如Moss(Measure of Software Similarity),但是这是一个外部服务,需要网络连接,并且不是开源的。由于我们需要一个纯Python解决方案,我们可以考虑使用tokenize模块来将代码分解成基本的语法单元(tokens),然后比较这些tokens的序列。
import os
import tokenize
from io import BytesIO
def tokenize_code(code):
try:
tokens = tokenize.tokenize(BytesIO(code.encode('utf-8')).readline)
return [token.string for token in tokens if token.type == tokenize.NAME or token.type == tokenize.OP]
except tokenize.TokenError:
return []
def read_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
def calculate_similarity(tokens1, tokens2):
set1 = set(tokens1)
set2 = set(tokens2)
common_tokens = set1.intersection(set2)
total_tokens = set1.union(set2)
if not total_tokens:
return 100.0
similarity = len(common_tokens) / len(total_tokens) * 100
return similarity
def main(folder_path):
c_files = [f for f in os.listdir(folder_path) if f.endswith('.c')]
file_tokens = {}
similarity_results = []
for c_file in c_files:
file_path = os.path.join(folder_path, c_file)
file_content = read_file(file_path)
file_tokens[c_file] = tokenize_code(file_content)
for i in range(len(c_files)):
for j in range(i + 1, len(c_files)):
file1, file2 = c_files[i], c_files[j]
similarity = calculate_similarity(file_tokens[file1], file_tokens[file2])
similarity_results.append((file1, file2, similarity))
# Sort the results by similarity
similarity_results.sort(key=lambda x: x[2])
# Print the sorted results
for result in similarity_results:
print(f"相似度 {result[0]} 和 {result[1]}: {result[2]:.2f}%")
if __name__ == "__main__":
folder_path = 'C:\\Users\\Anonymous\\Desktop\\up' # 你的文件夹路径
main(folder_path)
本文介绍了一个Python脚本,使用Levenshtein距离计算.c文件内容的相似度,通过tokenize模块将代码分解为tokens进行比较。后续版本改进了方法,使用tokenizedtokens来衡量代码逻辑结构的相似性。

被折叠的 条评论
为什么被折叠?



