当前位置:C++技术网 > 精选软件 > 高手眼中并没有代码,选对了方向方法会事半功倍

高手眼中并没有代码,选对了方向方法会事半功倍

更新时间:2016-06-29 10:22:58浏览次数:1+次

    最近工作中,涉及到了三种语言,包括Java、C#、Python。然而,我最熟悉的是C++。任务来了,不能说我只会C++而拒绝,不能因为自己不会一些东西而放弃。因为主要做的是C#端的微信公众号开发,借鉴已经开发的Java版的APP,与后台Python对接。
    拿到了Java开发的APP的源码、拿到了Python的源码,自己写着C#代码,要让三者的信息互通。第一个挑战就是注册用户。注册用户使用了Sha256、RSA加密、Base64编码,了解了基本流程,迅速用C#写好了注册的流程,结果总是提示错误。经过几天的排查,最后通过比对正确的数据,发现了问题。
    问题不在看似麻烦的加密身上,而是在+号的处理上。因为网页提交请求到后台,通过http方式,加密后得到的参数含有+号,而加号在后台接受的时候,已经被处理成空格了,结果导致密文长度不正确或者填充错误。因为后台处理以空格作为一个字符串的终止,才造成这样的问题。
    一开始总是掉进了加密的陷阱中,以为问题出在加密中。所以找了大量的资料,仍然无济于事。现在知道,选错了方向才导致大量的徒劳无功,身心疲惫。
    因为APP是已经完成的,所以功能都是正确的。后台也是可以控制的,所以可以把握整个过程,虽然文档不多,但是有源码,有后台,其实也是相对比较容易的了。这是一个方向,通过正确的数据来做参考,来比较结果,来分析原因。这个方向这个方法也就是解决注册问题的最有效的方式。否则,就没有正确的数据参考,没有正确的参考系,将后台当做黑盒子,不断的测试,实际上很难找到问题,更何况后台错误提示并不详细确切。
    我一开始用黑盒子去测试,最终还是放弃了,请了两个同事去注册,得到了正确的数据样本之后,和我在网页提交的注册数据一比较,就发现我提交的数据总是有那么一两个空格,然而正确的数据样本中是没有的。然后,我大量的提交,会发现N次之后,会成功。我又比较了成功的数据和正确的数据样本,发现都是没有空格的,反观出错的数据,都带有空格。我想空格就是问题所在了。我去查看加密后字符串,看看有没有空格,结果并没有。
    加密的密文没有空格,后台得到的却有空格,根据web开发经验,我隐约感觉到参数在传递的时候出了问题。然后我将加密后的密文参数和后台接受到有空格的密文参数比较,得到了空格对应的字符,那就是+号。我才发现加号的问题,也就迅速知道+确实会被处理掉。这是我在开发C++技术网时也遇到的问题。实际上你在用百度搜索时,在搜索后的地址的URL中在关键词中输入+号,回车后,在百度搜索框中会出现一个空格。有兴趣自己可以去试试。
    找到了问题,解决问题那就太容易了。对+号编码,最好是对URL编码,这样才可以避免所有可能的字符被过滤了。这样处理之后,然后注册功能就完美通过了。
    不过,这是找到了注册的一个最隐蔽的Bug。一开始C#代码写的RSA加密等,也并不是全部都OK的,经过大量的阅读APP和后台Python代码,才逐步确定每一个细节的处理。在最后实在没有什么加密上的Bug了,问题总是重复出现。世界上最远的距离莫过如此,明知道你就在身边,却就是找不到你。
    解决了注册之后,就是登陆了。登录采用的和注册的不一样的加密解密,而用的是AES对称加解密算法。之前因为没有用对方法,被虐的很惨。看似方法错了做了很多无用功,但是还是有一定的作用的,这促进了我把加密部分的代码的Bug参照已有的APP和后台代码都搞定了。只是还是多浪费了一些时间罢了。被虐的很惨之后,我也隐约感觉到,AES加密也是一个坑。事实证明,真是坑。关键是,此时的Java代码和Python又很陌生,C#这边的代码也很陌生。所以,看不懂已有代码,很多信息无法提取出来,没有详细的文档,对接就成了问题。对于发过来的密文,在我写的C#代码中解密,方法不对,总是解密不到正确的结果。此时我没有盲目的用黑盒子大量测试,而是开始分析特点,提取特征。因为对C#也不熟,对于AES加密本身也是第一次使用,所以也是陌生的。
    所以问题在哪里,依然不得而知。所以现在上班面对的问题就是这样的一个麻烦事。昨天下班的时候,我问了一个C#同事,他说他也没有做过AES加密,看不懂。不过,他接下来的话,却让我得到了很多启发,给了我正确的指引。他说,要么拿到后台原始的数据,然后在C#这边自己加密,自己解密,这样来排除C#自己加密解密的Bug。如果这个排除了,那就是对接的问题。如果对于同样的数据,加密后能够得到同样的密文,那么再自己解密,自然也能够得到正确的结果。而且,有输入有输出,在C#一端做测试,比起对接起来,是容易很多的。毕竟同一个语言的加解密不存在兼容问题,而且你可以对每一个参数设置都可以做到保持一致。在加解密参数一致的情况下,只要能够解密得到正确的密文,也就可以了。这样的话,瞬间将问题局部化,而且简单得多了。
    我这个同事大我大概八岁的样子,是一个资深的程序员。不管什么时候问他,他总能站的很高,在方法方面提供有效的建议,而不是掉入代码层面。可能旁观者清,但是他给的思路却非常清晰,很有逻辑。所以让我很是佩服。这才是高手。真正的高手,并不需要通晓各种语言,而是掌握解决问题的套路。套路越多,越通用,解决问题能力就越强。对于语言,可以根据需要,来熟悉,而这个套路则需要通过大量的实践和思考来积累。这才是界定高手和菜鸟的根本。
    高手眼中并没有代码,而是一个模型。高手在解决问题的时候,不断地去分析问题的特点,从而建立对应的模型,再来解决,而不是一开始就栽倒在代码里出不来。有了正确的解决问题的模型,然后一步步攻克问题,那只是时间的问题,技术上不会有太大的问题。当然,这里说的技术是一般能够实现的技术,既然人家能够做出来,我们也能做出来,只是需要正确的研究方法和解决问题的方法。
    编程,并不限定于语言,所有的编程,都是一致的,解决问题为根本。而方法是通用的,在解决问题之后,及时的总结,将会大大提到自己的解决问题的能力。因为总结可以让问题解决方法更加通用,可以帮助自己提高解决问题的水准。
    理清了思路,现在继续去解决AES加密解密的问题,相信在正确的思路的指导下,能够更快的解决问题的。加油。