方法数量随机
属性数量随机
方法参数随机
效果:代码控制生成代码文件数量
使用方法:python 代码名.py --oc_folder 制定你的工程目录
代码:
import os,sys
import random
import string
import re
import md5
import time
import json
import shutil
import hashlib
import time
import argparse
#from Enum import enum
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
#垃圾代码临时存放目录
target_ios_folder = os.path.join(script_path, "./target_ios")
#备份目录
backup_ios_folder = os.path.join(script_path, "./backup_ios")
#忽略文件列表,不给这些文件添加垃圾函数
ignore_file_list = ["main.m", "GNative.mm", "MobClickCpp.mm"]
#忽略文件夹列表,不处理这些文件夹下的文件
ignore_folder_list = ["thirdparty","Support",".svn","paycenter","UMMobClick.framework","UMessage_Sdk_1.5.0a","TencentOpenApi_IOS_Bundle.bundle",
"TencentOpenAPI.framework","Bugly.framework","AlipaySDK.framework","AlipaySDK.bundle"]
ocModelClasses = ["UIImage","NSObject","NSString","NSMutableArray","NSMutableDictionary"]
ocControllerClasses = ["UIViewController","UINavigationController"]
ocViewClasses = ["UIImageView","UIView","UIButton","UILabel","UITableView", "UICollectionView", "UITextField"]
basidDataType = ["int","double", "float", "BOOL", "bool"]
exportFloder = "/Users/guoanguan/Desktop/laJiCode"
#class OCClassType(Enum):
# oc_Model
# oc_View
# oc_Controller
# oc_Other
#创建函数数量范围
create_func_min = 2
create_func_max = 10
#创建垃圾文件数量范围
create_file_min = 50
create_file_max = 100
#oc代码目录
ios_src_path = ""
#确保添加的函数不重名
funcname_set = set()
#单词列表,用以随机名称
with open(os.path.join(script_path, "./word_list.json"), "r") as fileObj:
word_name_list = json.load(fileObj)
#获取一个随机名称
def getOneName():
global word_name_list
return random.choice(word_name_list)
#oc代码头文件函数声明
def getOCHeaderFuncText():
funcName = getOneName()
text = "\n- (void)%s" %(funcName)
return text
def getMethodName():
methodCanShuCount = random.randint(1,10)
text = "\n- (void)"
totleCount = methodCanShuCount
while methodCanShuCount > 0:
funcName = getOneName()
argName = getOneName()#方法参数名
classType = getOCClasses(random.randint(0, 20))#获取oc类类名
if methodCanShuCount != totleCount:
text = text + " "
text = text + funcName + ":(" + classType + " *)" + argName
methodCanShuCount = methodCanShuCount - 1
text = text
return text
def isObject(targetString):
allClass = ocModelClasses + ocViewClasses + ocControllerClasses
for ocC in allClass:
if(targetString == ocC):
return True
for baseDataTypeStr in basidDataType:
if(targetString == baseDataTypeStr):
return False
return False;
#oc代码函数实现模板
def getOCFuncText(header_text):
arg1 = getOneName()
text = [
header_text + "\n",
"{\n",
"\tNSLog(@\"%s\");\n" %(arg1),
"}\n"
]
return "".join(text)
def getLJFOCFuncText(header_text):
arg1 = getOneName()
text = [
header_text + "\n",
"{\n"
]
count = random.randint(0, 30)
while count > -1:
type = random.randint(0,5)
allocText = getAlloc(type)
text.append(allocText)
count = count - 1;
text.append("}\n");
return "".join(text)
def getAlloc(type):
arg1 = getOneName()
if(type == 1):
return "\tUIImage *%s = [UIImage imageNamed:@\"%s\"];\n" %(arg1,arg1)
if(type == 2):
return "\tNSString *%s = [[NSString alloc ] initWithString:@\"%s\"];\n" %(arg1,arg1)
if(type == 3):
return "\tNSLog(@\"%s\");\n" %(arg1)
if(type == 0):
return "\tNSObject *%s = [[NSObject alloc] init];\n" %(arg1)
if(type > 3):
return "\tNSObject *%s = [[NSObject alloc] init];\n" %(arg1)
def getOCClasses(type):
if type == 0:
return "UIImage"
if type == 1:
return "NSObject"
if type == 2:
return "NSString"
if type == 3:
return "UIViewController"
if type == 4:
return "UIView"
if type == 5:
return "UIButton"
if type == 6:
return "UILabel"
return "NSString"
#oc代码以@end结尾,在其前面添加text
def appendTextToOCFile(file_path, text):
with open(file_path, "r") as fileObj:
old_text = fileObj.read()
fileObj.close()
end_mark_index = old_text.rfind("@end")
if end_mark_index == -1:
print "\t非法的结尾格式: " + file_path
return
new_text = old_text[:end_mark_index]
new_text = new_text + text + "\n"
new_text = new_text + old_text[end_mark_index:]
with open(file_path, "w") as fileObj:
fileObj.write(new_text)
def addProperty(file_path):
#添加@property
addProperty = random.randint(0,1)
if addProperty == 1:
addPropertyCount = random.randint(0,20)
for i in range(0, addPropertyCount):
propertyType = random.randint(0,1)
strongOrWeak = "strong"
xingHao = "*"
className = "UIViewController"
if propertyType == 1:#引用类型
classType = random.randint(0,1)
if classType == 1:#强引用
strongOrWeak = "strong"
className = getOneClassName()
elif classType == 0:#弱引用
strongOrWeak = "weak"
className = getOneViewClassName()
elif propertyType == 0:#值类型
strongOrWeak = "readwrite"
className = getBasicDataTypeName()
xingHao = ""
propertyName = getOneName()
propertyText = "@property(nonatomic, %s)%s %s%s;\n" %(strongOrWeak, className, xingHao, propertyName)
text.append(propertyText)
#处理单个OC文件,添加垃圾函数。确保其对应头文件存在于相同目录
def dealWithOCFile(filename, file_path):
global target_ios_folder,create_func_min,create_func_max,funcname_set
funcname_set.clear()
end_index = file_path.rfind(".")
pre_name = file_path[:end_index]
header_path = pre_name + ".h"
if not os.path.exists(header_path):
print "\t相应头文件不存在:" + file_path
return
#添加@property
addProperty = random.randint(0,1)
if addProperty == 1:
addPropertyCount = random.randint(0,20)
for i in range(0, addPropertyCount):
propertyType = random.randint(0,1)
strongOrWeak = "strong"
xingHao = "*"
className = "UIViewController"
if propertyType == 1:#引用类型
classType = random.randint(0,1)
if classType == 1:#强引用
strongOrWeak = "strong"
className = getOneClassName()
elif classType == 0:#弱引用
strongOrWeak = "weak"
className = getOneViewClassName()
elif propertyType == 0:#值类型
strongOrWeak = "readwrite"
className = getBasicDataTypeName()
xingHao = ""
propertyName = getOneName()
propertyText = "@property(nonatomic, %s)%s %s%s;" %(strongOrWeak, className, xingHao, propertyName)
propertyText = appendText_n(propertyText)
#text.append(propertyText)
appendTextToOCFile(header_path, propertyText)
new_func_num = random.randint(create_func_min, create_func_max)
print "\t给%s添加%d个方法" %(filename, new_func_num)
for i in range(new_func_num):
#header_text = getOCHeaderFuncText()
header_text = getMethodName()
# print "add %s to %s" %(header_text, header_path.replace(target_ios_folder, ""))
appendTextToOCFile(header_path, header_text + ";\n")
#funcText = getOCFuncText(header_text)
funcText = getLJFOCFuncText(header_text)#给方法添加细节
appendTextToOCFile(file_path, funcText)
def appendText_n(text):
k = random.randint(0,2)
for i in range(0, k):
text = text +"\n"
return text
#扫描parent_folder,添加垃圾函数,处理了忽略列表,添加方法
def addOCFunctions(parent_folder):
global ignore_file_list
for parent, folders, files in os.walk(parent_folder):#遍历所有生成的.h .m 文件,为其生成方法内容
need_ignore = None
for ignore_folder in ignore_folder_list:
if parent.find("/" + ignore_folder) != -1:#是x需要被忽略的文件夹
need_ignore = ignore_folder
break
if need_ignore:
print "\t忽略文件夹" + ignore_folder
continue
for file in files:
if file.endswith(".m") or file.endswith(".mm"):
if file in ignore_file_list:
continue
dealWithOCFile(file, os.path.join(parent, file))
#新创建的垃圾文件header模板 添加头文件
def getOCHeaderFileText(class_name):
global funcname_set
new_func_name = getOneName()
while new_func_name in funcname_set:
new_func_name = getOneName()
funcname_set.add(new_func_name)
text = [
"#import <Foundation/Foundation.h>\n\n",
"@interface %s : NSObject {\n" %(class_name),
"\tint %s;\n" %(new_func_name),
"\tfloat %s;\n" %(getOneName()),
"}\n\[email protected]"
]
return string.join(text)
#新创建的垃圾文件mm模板
def getOCMMFileText(class_name):
text = [
'#import "%s.h"\n\n' %(class_name),
"@implementation %s\n" %(class_name),
"\n\[email protected]"
]
return string.join(text)
#添加垃圾文件到parent_folder/trash/ 只有.h或者.m,无方法实现
def addOCFile(parent_folder):
global create_file_min, create_file_max
file_list = []
target_folder = os.path.join(parent_folder, "trash")
if os.path.exists(target_folder):
shutil.rmtree(target_folder)
os.mkdir(target_folder)
file_num = random.randint(create_file_min, create_file_max)
for i in range(file_num):
file_name = getOneName()
file_list.append("#import \"" + file_name + ".h\"")
print "\t创建OC文件 trash/" + file_name
#header_text = getOCHeaderFileText(file_name)
header_text = create_ocHeader_h_Text(file_name);
full_path = os.path.join(target_folder, file_name + ".h")
with open(full_path, "w") as fileObj:
fileObj.write(header_text)
fileObj.close()
mm_text = getOCMMFileText(file_name)
full_path = os.path.join(target_folder, file_name + ".mm")
with open(full_path, "w") as fileObj:
fileObj.write(mm_text)
all_header_text = "\n".join(file_list)
with open(os.path.join(parent_folder, "Trash.h"), "w") as fileObj:
fileObj.write(all_header_text)
fileObj.close()
#解析参数
def parse_args():#读取程序入口输入的参数
parser = argparse.ArgumentParser(description='oc垃圾代码生成工具.')
parser.add_argument('--oc_folder', dest='oc_folder', type=str, required=True, help='OC代码所在目录')
parser.add_argument('--replace', dest='replace_ios', required=False, help='直接替换oc源代码', action="store_true")
args = parser.parse_args()
print "main"
return args
def create_ocHeader_h_Text(class_name):
global funcname_set
new_func_name = getOneName()
while new_func_name in funcname_set:
new_func_name = getOneName()
funcname_set.add(new_func_name)
ocCTypeEnumCount = 4#OCClassType.oc_Other - OCClassType.oc_Model + 1#emum个数
ocCTypeEnumIndex = random.randint(0, ocCTypeEnumCount-1)#要添加的脚本的类型
targetInheritClassesList =[]#可能会继承的类list
if ocCTypeEnumIndex == 0:#ocCType.oc_Controller):
targetInheritClassesList.append("UIViewController")
if ocCTypeEnumIndex == 1:# ocCType.oc_View):
targetInheritClassesList = ocViewClasses
if ocCTypeEnumIndex == 2:# ocCType.oc_Model):
targetInheritClassesList.append("NSObject")
if ocCTypeEnumIndex == 3:# ocCType.oc_Other):
targetInheritClassesList = ocViewClasses + ocModelClasses + ocControllerClasses
inheritClassCount = len(targetInheritClassesList)#可能继承的类的数量
targetInheritClassIndex = random.randint(0,inheritClassCount-1)
text = [
"#import <Foundation/Foundation.h>\n\n",
"@interface %s : %s {\n" %(class_name, targetInheritClassesList[targetInheritClassIndex])
]
addShuXing = random.randint(0,1)
if addShuXing == 1:#头文件添加属性
shuxingCount = random.randint(1,10)#要添加的属性数量
for i in range(0,shuxingCount):
#类名 变量名
shuXingText = "\t%s %s;\n" %(basidDataType[random.randint(0,len(basidDataType) - 1)], getOneName())
shuXingText = appendText_n(shuXingText)
text.append(shuXingText)
text.append("}\n\[email protected]")
#print text
return string.join(text)
def getOneViewClassName():
k = random.randint(0, len(ocViewClasses) - 1)
return ocViewClasses[k]
def getOneModelClassName():
k = random.randint(0, len(ocModelClasses) - 1)
return ocModelClasses[k]
def getOneClassName():
k = random.randint(0,2)
if k == 0:
return getOneViewClassName()
if k == 1:
return getOneModelClassName()
return "UIViewController"
def getBasicDataTypeName():
k = random.randint(0, len(basidDataType) - 1)
return basidDataType[k]
def main():
app_args = parse_args()#读取程序入口输入的参数
global ios_src_path, backup_ios_folder, target_ios_folder
ios_src_path = app_args.oc_folder
if not os.path.exists(ios_src_path):#如果不存在这个文件夹 终止程序
print "oc_folder path not exist."
exit(0)
print "拷贝OC代码到target_ios"
if os.path.exists(target_ios_folder):
shutil.rmtree(target_ios_folder)
shutil.copytree(ios_src_path, target_ios_folder)
print "开始创建oc文件到trash目录"
addOCFile(target_ios_folder)
print "\n开始添加oc方法"
addOCFunctions(target_ios_folder)
if app_args.replace_ios:
print "\n用target_ios替换原目录"
print "\t备份OC代码到" + os.path.abspath(backup_ios_folder)
if os.path.exists(backup_ios_folder):
shutil.rmtree(backup_ios_folder)
shutil.copytree(ios_src_path, backup_ios_folder)
print "\t开始替换"
trash_folder = os.path.join(ios_src_path, "trash")
if os.path.exists(trash_folder):
shutil.rmtree(trash_folder)
os.mkdir(trash_folder)
for parent, folders, files in os.walk(target_ios_folder):
for file in files:
if file.endswith(".h") or file.endswith(".m") or file.endswith(".mm"):
full_path = os.path.join(parent, file)
target_path = full_path.replace(target_ios_folder, ios_src_path)
shutil.copy(full_path, target_path)
print "替换成功\n需要在Xcode上重新添加trash文件下的oc文件"
else:
print "垃圾代码生成完毕,垃圾代码目录:" + os.path.abspath(target_ios_folder)
print "\nfinished"
if __name__ == "__main__":
main()