“测试你的本命专业”选项与结果关系探究

 

1 代码获取

加载好页面后,断网,发现可以正常答题生成结果。推测通过JS即可直接生成结果,在Chrome浏览器中打开F12开发者工具->Network和Console窗口,根据下图红框选中部分推断相关代码应该在index.13918870.js中

构造网址(https://cdn-act.knowyourself.cc/life_profession/static/js/index.13918870.js),在代码末尾找到了//# sourceMappingURL=index.13918870.js.map,根据名称,可以推测与js文件有所联系,由于分析时并不了解.map格式的含义,因此要查询有关.map格式相关介绍的资料(资料来源:http://www.ruanyifeng.com/blog/2013/01/javascript_source_map.html),在资料中学习到,这种文件是JS进行源码转换后,对应的sourcemap文件。该文件储存着位置信息,即转换后的代码的位置对应的转换前的位置。

因此尝试构造网址(https://cdn-act.knowyourself.cc/life_profession/static/js/index.13918870.js.map),成功下载到index.13918870.js.map

接下来需要做的是将.map还原成代码转换前的格式,以便于我们分析。因此,接下来要查询有无可以在有map的情况下,帮助转换为JS的工具,查询得知GitHub上有一个开源工具shuji可以从sourcemap反向工程生成JavaScript/CSS源代码,工具地址为https://github.com/paazmaya/shuji

按照该项目的readme搭载好环境,使用shuji index.13918870.js.map -o c:\xlcs将生成的js源代码放入C盘xlcs目录下,

进入该文件夹,发现result.js,猜测该文件应为输出结果关键js文件。

打开文件验证猜测,

可以看到有对应的代码和注释,是所需的目标文件,接下来分析该文件的流程。

2 流程说明

浏览源代码,给出如下简要流程:

函数名:getResult

输入:select,含义:用户答题选项信息,代码编写者已给出注释

输出:max,含义:最大值

1、为Array数组添加一个打乱元素顺序的函数shuffle()作为备用。

2、定义config对象。该对象中包含0~9十个属性,代表十道题,每个属性里又包括选项属性,属性从0开始代表选项,比如0、1、2、3分别代表A、B、C、D,每个属性对应的是一个数组,数组内的数代表该选项对应的结果。通过原开发者的注释,可以清楚的知道28个数对应的学科,如下:

// 结果页id:

// 0:经济学

// 1:哲学

// 2:法学

// 3:社会学

// 4:教育学

// 5:汉语言文学

// 6:外国语言学

// 7:新闻学

// 8:历史学

// 9:数学

// 10:物理学

// 11:化学

// 12:生命科学

// 13:地理学

// 14:心理学

// 15:计算机科学与技术

// 16:土木工程学

// 17:建筑学

// 18:机电工程学

// 19:农林学

// 20:医学

// 21:管理学

// 22:艺术

// 23:戏剧影视导演

// 24:表演艺术

// 25:体育学

// 26:考古学

// 27:电子竞技

如,1: [3, 4, 24],代表选项B是符合3.社会学、4.教育学、24.表演艺术的。

3、从传入参数用户的选择中,使用双重循环遍历并获取对应的config对象。

外层循环:对10道题进行遍历。

内层循环:对每道题内用户选择的答案进行遍历(因为有多选题,需要遍历),并把用户选择的选项号作为数组下标,从config对象里找到该选择可以对应的学科号,把这些学科号拼接到result数组中。

4、创建一个result_map对象,该对象的属性是结果号,值为该结果号对应的数。如:16:2 代表用户作答的所有题中,有两个选项是符合“16.土木工程学”的。

遍历3中得到的result数组,每次遍历首先判断result_map中是否有该学科号?否:创建对应属性,属性值设为0,然后对应属性值+1。是:对应属性值+1。

遍历的同时获取最大值。默认最大值是-1,那么第一次遍历时将max设置为result数组第一个元素对应的学科号。此后,每次遍历对应属性值+1后与max进行比较,遍历结束后即可获得最大值。

3 验证

接下来用一个用例进行验证。

假定我们的预期输出是表演艺术。对应的结果号为24

从config里获知,第一题应选择C。第二题应选择B。第三题应选择A。第四题应选择A。第五题应选择A。第六题应选择B。第七题应选择B。第8题应选择B。第九题应选择第8个选项、第11个选项。第10题无所谓,不影响结果。

按照上面的选择进行测试,实际输出结果如下:

符合预期。

接下来改变专业、改变姓名、改变性别、改变第10题的选项,其他不变,因为认为这些均是无关选项,认为不会影响输出。实际结果如下:

符合预期。

上面选项是最理想最符合该结果的,实际上只要保证,符合上述输入的选择在本次答题中是最多的就可以。因此这里改变几道选项,在第1、2题中选择其他选项,第9题选8、9、11。其他不变。实际结果如下:

接下来多改几个:

1题选A。2题选C。第九题选1、2、3,其他不变

这时,表演艺术只有3-8题符合,而1、2、3、5、6、7、9题都有符合汉语言文学的,汉语言文学成为max,因此结果应该变成汉语言文学,实际输出如下:

 

4 致谢及补充

以上内容中暂未分析shuffle()的作用,测试部分没有考虑到可能有多个学科符合max的情况。博文https://www.cnblogs.com/ZigHello/p/14825696.html中的分析包含了这些部分,使得我能够意识到并弄清本文中遗漏及不完善之处,在此对博文作者表示感谢。

posted @ 2021-06-07 13:40  OurShiningDays  阅读(142)  评论(0编辑  收藏  举报