版本开发质量的一个容易被忽略的技术指标:混淆率
Android开发,都会关注包体、崩溃率、anr率,其实还有一个一直被忽略的维度,就是混淆率,混淆率越高,表示反编译成本越高,代码安全性越好,同时包体也会越小;为此,写了一个python软件包,专门用于计算代码混淆率
软件包已上传到了
PyPI
,可以直接通过terminal命令行使用,非常方便
注:PyPI是Python的正式第三方软件包的软件存储库;用户通过PyPI可以下载超过235,000个Python软件包。
使用步骤(下面的步骤是针对Mac系统,其他系统其实也差不多)
brew install python3
或者去官网下载安装:https://www.python.org/downloads/
pip install proguard-rate
proguard-rate
是这个脚本的名称,也可以去官网查看这个软件包:https://pypi.org/project/proguard-rate/,会默认安装最新版本
calRate
命令,enter键,根据提示传入mapping文件地址,就可以计算出混淆率了weigan@weigandeMacBook-Pro ~ % calRate
请输入mapping文件地址:/Users/weigan/Downloads/104-mapping.txt
总的有效行数: 186001 已混淆的行数 120641 混淆率 0.6486040397632271
上面通过传入的这个mappin可以知道,混淆率是64.8%
后续每次使用,直接在terminal输入
calRate
命令即可,非常方便
关于混淆率的计算规则,我们先看下mapping文件截图
一共有三种类型的混淆
上面三种混淆都会参与计算,最终得到一个总的混淆率,计算思路如下
->
左边跟右边的内容计算的规则还是很简单的,接下来看下具体的代码
为此,专门学了两周的python
# coding=utf-8
# 混淆的标识符
FILTER_SYMBOL = " -> "
SYMBOL_LENGTH = len(FILTER_SYMBOL)
def calculateProguardRate(filePath):
file = open(filePath)
lines = file.readlines()
length = len(lines)
# print("mapping.txt 总的行数是 :" + str(length))
# 方法跟变量的总的数量
methodTotal = 0
# 方法跟变量已混淆的数量
methodProguard = 0
for index in range(0, len(lines)):
lineString = lines[index]
symbolIndex = lineString.find(FILTER_SYMBOL)
if symbolIndex >= 0: # 代表有混淆标识
firstPart = lineString[0:symbolIndex]
firstPart = removeEndSymbol(firstPart)
secondPart = lineString[symbolIndex + SYMBOL_LENGTH:]
secondPart = removeLineBreak(secondPart)
sameEnd = firstPart.endswith(secondPart)
methodTotal = methodTotal + 1
# print "same end:" + str(sameEnd) + ",first:" + firstPart + ",second:" + secondPart + ",end"
# 代表有混淆
if not sameEnd:
methodProguard = methodProguard + 1
proguardRate = float(methodProguard) / methodTotal
print("总的有效行数: " + str(methodTotal) + " 已混淆的行数 " + str(methodProguard) + " 混淆率 " + str(proguardRate))
# 移除方法后面的符号
def removeEndSymbol(str):
newStr = str.strip()
index = newStr.find('(')
if index >= 0:
# 代表是方法,移除括号后面的内容
return newStr[0:index]
else:
return newStr
# 移除换行符
def removeLineBreak(str):
return str.strip()
def cal_rate():
mappingFile = input("请输入mapping文件地址:")
# 方法开始的地方
calculateProguardRate(mappingFile.strip())
def main():
cal_rate()
if __name__ == "__main__":
main()
代码也不复杂,看注释就明白了,整个工程的代码也传到github上,欢迎查阅 https://github.com/weidongjian/proguardRate