【Python】检查.c文件相似度

本文介绍了一个Python脚本,使用Levenshtein距离计算.c文件内容的相似度,通过tokenize模块将代码分解为tokens进行比较。后续版本改进了方法,使用tokenizedtokens来衡量代码逻辑结构的相似性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值