美文网首页
生成 objc 垃圾代码

生成 objc 垃圾代码

作者: nzkaw | 来源:发表于2024-10-08 23:03 被阅读0次

非完整版,本来是打算用来应对苹果审核 4.3 被拒的,后面莫名其妙的过审了 (随便改了改 UI),暂且搁置了

目前版本只是简单的搭了一下基本的生成规则,当做 Python 练习了

  • 随机生成类文件(.h/m)
  • 随机生成属性并初始化
  • 随机生成方法/方法体并实现调用
  • 生成垃圾文件包对应的 Headers 文件

Gitee 源码地址


Python

调试环境: Python 3.9.6

import random
import string
import os

# 当前文件目录
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))

# 关键字配置文件
KEYWORDS_FILE = CURRENT_DIR + "/keywords.txt"

# 类前缀
CLASS_PRE = "Test"

# 随机生成多少个类文件
FILE_NUM = 100

# 文件导出目录
OUTPUT = CURRENT_DIR + "/output/" + CLASS_PRE


void = 0
NSString = 1
NSInteger = 3
NSNumber = 4
BOOL = 5
double = 6
NSArray = 2
NSDictionary = 7
UIView = 8
UIFont = 9

def objc_type_name(type):
    if type == void:
        return "void"
    if type == NSString:
        return "NSString *"
    if type == NSInteger:
        return "NSInteger "
    if type == NSNumber:
        return "NSNumber *"
    if type == BOOL:
        return "BOOL "
    if type == double:
        return "double "
    if type == NSArray:
        return "NSArray *"
    if type == NSDictionary:
        return "NSDictionary *"
    if type == UIView:
        return "UIView *"
    if type == UIFont:
        return "UIFont *"
        
        
def random_objc_property_value(type):
    if type == void:
        return ""
    if type == NSString:
        v = f"{random_keywords()}{str(random.randint(0, 10000))}{random_keywords()}"
        return f"@\"{v}\""
    if type == NSArray:
        return "@[]"
    if type == NSInteger:
        return str(random.randint(0, 10000))
    if type == NSNumber:
        return f"@{random.randint(0, 10000)}"
    if type == BOOL:
        return "YES" if random.randint(0, 1) == 1 else "NO"
    if type == double:
        return str(random.randint(0, 10000))
    if type == NSDictionary:
        return "@{}"
    if type == UIView:
        return "[UIView new]"
    if type == UIFont:
        return f"[UIFont systemFontOfSize:{random.randint(9, 30)}]"
    return "nil"


class ObjcProperty:
    def __init__(self):
        self.name = ""
        self.type = 0
        self.ref = ""
        self.typename = "NSString *"
        
    def Random():
        result = ObjcProperty()
        
        name = random_keywords()
        if random.random() < 0.1:
            name = f"{name}_{random_keywords()}"
        if random.random() < 0.1:
            name = f"{name}_{random_keywords()}"
        if random.random() < 0.1:
            name = f"{name}_{random_keywords()}"
        name = underscore_to_camelcase(name,True)
        
        result.name = name
        result.type = random.randint(1, 9)
        result.typename = objc_type_name(result.type)
        if result.type == NSString:
            result.ref = "strong"
        if result.type == NSInteger:
            result.ref = "assign"
        if result.type == NSArray:
            result.ref = "strong"
        if result.type == NSNumber:
            result.ref = "strong"
        if result.type == BOOL:
            result.ref = "assign"
        if result.type == double:
            result.ref = "assign"
        if result.type == NSDictionary:
            result.ref = "strong"
        if result.type == UIView:
            result.ref = "strong"
        if result.type == UIFont:
            result.ref = "strong"
        return result


class ObjcFunc:
    def __init__(self):
        self.name = ""
        self.type = 0
        self.returntype = 0
        self.params = [] # ObjcProperty
        self.fullname = ""
        self.run = ""
        
    def Random():
        result = ObjcFunc()
        name = random_keywords()
        name = f"{name}_{random_keywords()}"
        name = f"{name}_{random_keywords()}"
        if random.random() < 0.3:
            name = f"{name}_{random_keywords()}"
        if random.random() < 0.6:
            name = f"{name}_{random_keywords()}"
        if random.random() < 0.9:
            name = f"{name}_{random_keywords()}"
        name = underscore_to_camelcase(name,True)
        result.name = name
        for i in range(0, random.randint(0, 5)):
            result.params.append(ObjcProperty.Random())
        result.type = random.randint(0, 1)
        result.returntype = random.randint(0, 8)
        fullname = ""
        if result.type == 0:
            fullname = f"{fullname}- "
        if result.type == 1:
            fullname = f"{fullname}+ "
        fullname = f"{fullname}({objc_type_name(result.returntype).rstrip()})"
        fullname = f"{fullname}{result.name}"
        for i in range(0 ,len(result.params)):
            p = result.params[i]
            typename = p.typename.rstrip()
            if i == 0:
                fullname = f"{fullname}:({typename}){p.name} "
            else:
                fullname = f"{fullname}{p.name}:({typename}){p.name} "
        fullname = fullname.rstrip()
        result.fullname = fullname
        return result


class ObjcClass:
    def __init__(self):
        self.name = ""
        self.supertype = 0
        self.supername = "NSObject"
        self.importH = "#import <UIKit/UIKit.h>"
        self.func = []
        self.property = []
        self.output = ""
        self.link = [] # ObjcClass
        
    def contains_property(self,property):
        for obj in self.property:
            if obj.name == property.name:
                return True
        return False
    
    def Random():
        result = ObjcClass()
        result.name = random_class_name()
        for i in range(0, random.randint(0, 30)):
            p = ObjcProperty.Random()
            if result.contains_property(p) == False:
                result.property.append(p)
        for i in range(0, random.randint(0, 30)):
            result.func.append(ObjcFunc.Random())
        result.supertype = random.randint(0, 2)
        if result.supertype == 0:
            result.supername = "NSObject"
            result.importH = "#import <UIKit/UIKit.h>"
        if result.supertype == 1:
            result.supername = "UIViewController"
            result.importH = "#import <UIKit/UIKit.h>"
        if result.supertype == 2:
            result.supername = "UIView"
            result.importH = "#import <UIKit/UIKit.h>"
        result.output = OUTPUT
        return result
        
    def export(self):
        # 生成 .h 文件
        self.exportH()
        # 生成 .m 文件
        self.exportM()
        
    def exportH(self):
        code = ""
        code = random_enter_for(code)
        code = f"{code}{self.importH}\n"
        code = f"{code}\n"
        code = f"{code}NS_ASSUME_NONNULL_BEGIN\n\n"
        code = random_enter_for(code)
        code = f"{code}@interface {self.name} : {self.supername}\n"
        code = random_enter_for(code)
        for p in self.property:
            code = f"{code}@property ({p.ref} ,nonatomic) {p.typename}{p.name};\n"
            code = random_enter_for(code)
        code = f"{code}\n"
        code = random_enter_for(code)
        code = random_enter_for(code)
        for f in self.func:
            code = f"{code}{f.fullname};\n"
            code = random_enter_for(code)
        code = f"{code}@end\n\n"
        code = f"{code}NS_ASSUME_NONNULL_END"
        code = random_enter_for(code)
        file = open(f"{self.output}/{self.name}.h", "w")
        file.write(code)
        file.close()
        
    def exportM(self):
        code = ""
        code = random_enter_for(code)
        code = f"{code}#import \"{self.name}.h\"\n"
        for obj in self.link:
            if obj.name != self.name:
                code = f"{code}#import \"{obj.name}.h\"\n"
        
        code = f"{code}\n"
        code = random_enter_for(code)
        code = f"{code}@implementation {self.name}\n"
        code = random_enter_for(code)
        
        code = f"{code}- (instancetype)init {{\n"
        code = f"{code}    self = [super init];\n"
        code = f"{code}    if (self) {{\n"
        
        for p in self.property:
            code = f"{code}        _{p.name} = {random_objc_property_value(p.type)};\n"
            code = random_enter_for(code)
            
        for obj in self.func:
            sender = "self" if obj.type == 0 else self.name
            full_run_func = f"{sender} {obj.name}"
            for i in range(0 ,len(obj.params)):
                p = obj.params[i]
                if i == 0:
                    full_run_func = f"{full_run_func}:{random_objc_property_value(p.type)} "
                else:
                    full_run_func = f"{full_run_func}{p.name}:{random_objc_property_value(p.type)} "
            full_run_func = full_run_func.rstrip()
            code = f"{code}        [{full_run_func}];\n"
            code = random_enter_for(code)
        
        code = f"{code}    }} return self;\n"
        code = f"{code}}}\n\n"
        code = random_enter_for(code)
        
        for obj in self.func:
            if obj.returntype == void:
                code = f"{code}{obj.fullname} {{\n\n}}\n"
            else:
                code = f"{code}{obj.fullname} {{\n    return {random_objc_property_value(obj.returntype)};\n}}\n"
        
        code = f"{code}@end\n"
        file = open(f"{self.output}/{self.name}.m", "w")
        file.write(code)
        file.close()
        
    def random_func_from_link(self):
        obj = random.choice(self.link)
        return random.choice(obj.func)
        
        
# 生成随机类名
def random_class_name():
    result = ""
    result = f"{result}_{random_keywords()}"
    if random.random() < 0.8:
        result = f"{result}_{random_keywords()}"
    if random.random() < 0.4:
        result = f"{result}_{random_keywords()}"
    if random.random() < 0.2:
        result = f"{result}_{random_keywords()}"
    if random.random() < 0.3:
        result = f"{result}_controller"
    result = underscore_to_camelcase(result)
    result = f"{random_pre()}{result}"
    return result
    
# 类前缀
def random_pre():
    return CLASS_PRE

# 随机在尾部插入换行符
def random_enter_for(code):
    if random.random() < 0.2:
        code = f"{code}\n"
    return code
    
# 从 file 文件里随机读取一行文本
def random_keywords(file = KEYWORDS_FILE):
    result = ""
    with open(file, 'r', encoding='utf-8') as file:
        # 读取所有行
        lines = file.readlines()
        random_line = random.choice(lines)
        result = random_line.strip()
    if result == "":
        result = "".join(random.choices(string.ascii_uppercase, k=5))
    return result
    
# 下划线转驼峰
def underscore_to_camelcase(underscore_string,lowerFirst = False):
    words = underscore_string.split('_')
    camelcase_string = ''.join(word.capitalize() for word in words)
    if lowerFirst == True:
        camelcase_string = camelcase_string[0].lower() + camelcase_string[1:]
    return camelcase_string
    
    
# 清空目录下的所有文件
def clear(directory):
    # 获取目录中的所有文件
    files = os.listdir(directory)
    # 遍历并删除每个文件
    for file in files:
        file_path = os.path.join(directory, file)
        if os.path.isfile(file_path):
            os.remove(file_path)


def main():
    
    if not os.path.exists(OUTPUT):
        os.makedirs(OUTPUT)
    clear(OUTPUT)
    
    # 一共生成多少个类
    total = FILE_NUM
    
    # 每个文件最多关联多少个类
    link = total if total < 20 else 20
    
    allObjcClass = []
    for i in range(0, total):
        obj = ObjcClass.Random()
        allObjcClass.append(obj)
        
    for obj in allObjcClass:
        obj.link = random.sample(allObjcClass, random.randint(0, link))
        
    for obj in allObjcClass:
        obj.export()
        
    code = ""
    for obj in allObjcClass:
        code = f"{code}#import \"{obj.name}.h\"\n"
    file = open(f"{OUTPUT}/{CLASS_PRE}Headers.h", "w")
    file.write(code)
    file.close()

if __name__ == "__main__":
    main()

相关文章

网友评论

      本文标题:生成 objc 垃圾代码

      本文链接:https://www.haomeiwen.com/subject/cebrpltx.html