学生生涯结束,踏入社会,没有成绩、学分约束,没有老师、学校监督,完全凭个人兴趣、意志自学的技能,挑出三个你最有成就感的。

你会选哪三个?

另外两个暂且不提,对于我来说,肯定会有小鹤双拼

小鹤双拼

其实说「小鹤双拼」还不太准确,应该说「小鹤音形」。因为它不仅仅是一个双拼方案,还有双形方案。

双形即从每个字中提取首末两部分形态各异的组字单元,以区分同音字,组字单元即字根

小鹤字根

比如「」字,拆分是:一戈止,首字根是(形码是 a,笔画中「横」对应 a),末字根是(形码是 v,zh 对应 v),完整的小鹤音形码是: 「双拼+双形」,即wuav。小鹤的字根基本都取声母,不需要特别记忆。所以,学起来也不难,主要是要多练习,形成肌肉记忆。
基本坚持学习一个月就能掌握「小鹤音形」,此后四码上屏,打字如飞。我的意外收获是:借机学会了盲打,如虎添翼。

尽管我已熟练掌握小鹤音形,但是偶尔部分字还是会忘记编码。这时,我希望手边有一个工具能够辅助我快速查询编码。有爱好者制作了一款微信小程序,不过因为某些原因,该小程序需要看广告换积分来查询。pass

另外还有一个网站可以查询编码。

如果不想折腾,这里已经可以打住了,iOS 端只需要将该网页「添加到主屏幕」即可,参见上篇文章

但我喜欢折腾,下面,我将说说我是如何利用该网站的接口自己开发了一款小鹤编码查询工具。

先说说如何找接口。使用谷歌浏览器访问该网站,然后按 F12 进入开发者模式,执行查询时会发现多了一个叫 searchCode 的请求。

这是一个 POST 请求,请求 URL 是 http://www.xhup.club/Xhup/Search/searchCode。

请求头如下

其中,Host 告诉后台,浏览器想访问的 web 服务器的域名/IP 地址和端口号,这里是 www.xhup.club。Origin 告诉后台请求发起方是 http://react.xhup.club,所以后面假如我们想用 Python 模拟该请求必须带上该头部,否则后台判定该请求不合法,后面响应头部中有个: Access-Control-Allow-Origin: http://react.xhup.club,意思是只接受 http://react.xhup.club 发起的请求。

再来看看这个 Referer,跟 Origin 类似,我们是访问 http://react.xhup.club/search 后再发起的查询请求,所以这里记录的是上一个页面的 URL(协议+域名+查询参数) 即是 http://react.xhup.club/search。另外,还需要注意这个 User-Agent,当我们用 Python 调该接口时需要带上该头部以欺骗后台服务: 请求是浏览器发起的

代码中请求头如下:

headers = {
  'Origin': 'http://react.xhup.club',
  'Referer': 'http://react.xhup.club/search',
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
  'Host': 'www.xhup.club',
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
  'Accept': 'application/json, text/plain, */*',
}

接下来是最关键的一步了。

我们执行查询时实际上是提交了一个表单,该表单包括所要查询的汉字与一个 sign。当表单上传编码格式为application/x-www-form-urlencoded,参数的格式(点击view source)如下

search_word=%E4%B8%AD&sign=fa8d52dc60388d70b092c7f34db8f0c2

其中,汉字需要进行百分号转义。那么这里的 sign 是从哪来的呢? 通常是一个 md5 值。我们来看下相关 js 代码,打一些断点调试。

图中变量 ekey_xhup 的值,即 fjc_xhup,变量 rsearch_word 的值,即所要查询的汉字,W() 不用管,姑且猜测为 md5 加密函数,这里对 fjc_xhupsearch_word 合并后的字符串进行了加密作为 sign 的值。

在浏览器查询「」的编码时,sign 值为: fa8d52dc60388d70b092c7f34db8f0c2。下面我们用 Python 的 md5 测试下。

In [1]: import hashlib

In [2]: key_xhup = 'fjc_xhup'

In [3]: search_word = '中'

In [4]: sign = hashlib.md5((key_xhup + search_word).encode('utf-8')).hexdigest()
   ...:

In [5]: print(sign)
fa8d52dc60388d70b092c7f34db8f0c2

猜测正确。好了,剩下的事情就非常简单了。

我分别用 Pythonista 与苹果自带的快捷指令实现了该功能。其中,由于捷径的局限性,我设计为一次只能查询一个字的编码。