Category: 铁路

从“香港西九龙”到12306协议

从“香港西九龙”到12306协议

经过了乱七八糟的问题,质疑和风浪之后,香港西九龙终于开通在即了。 先来个小笑话: 这票二维码是和票面信息完全不符……槽点满满。 XJA-IZQ:香港西九龙——广州南 二维码上购票人姓名和票面购票人姓名不同,车次G9994是要干什么么……更别说时间日期以及票号等等等等了……车厢,座位号和证件倒是对的。 当然,也许二维码上这个日期和时间是原预定开通时间,然后原预定开通为香港西九龙——广州南,并且车次为G9994次……(完全瞎猜。如有雷同,实属巧合。不接受跨省追捕。) 回到正题: 现在这几天车迷圈儿除了香港西九龙就是香港西九龙,感觉什么都见不到。某微博(实在想不起来名字了)的香港西九龙至各地的时刻表传的圈子内(当然我也可以假设圈子外也是)基本无人不知无人不晓。 有意思的是,现在12306官网还没有把香港西九龙站上表——而APP已经这么做了。 作为kelibiao.com的站长,每次有新站上客里表的时候都必须得看一眼数据。明显,香港西九龙还没有上表,但是总是可以一探究竟的。毕竟数据需要及时更新,才能够吸引到更多用户么(说得跟用户有多少一样)。 正好有人跟我讲到香港西九龙上了APP的站名表,并且听说电报码是-XJA;同时有个叫做“边界”的“车站”,电报码为-XBA,希望我能求证。于是,我便开始了折腾一天的求证之旅。   首先,第一个想法就是进行http嗅探。作为昔日piao.today的站长,12306前端怎么工作我还是比较了解的。APP和网站很类似——APP其实就是个h5配上app的壳做成的WebAPP而已。但是我也早在那时候就知道APP的通讯也是https的。这就导致了嗅探起来比较麻烦。 当然,麻烦不代表做不了。大概有以下几种方法: 找个树莓派弄成路由器然后中间层攻击(真的懒得再碰树莓派了) 反编译app(这不是扯淡呢么,最麻烦的方法——写在这儿凑数的。两条还搞个list真的不好看) 手机层面上想办法。 嗅探么,一直在安卓上用一款叫做wicap的软件。Google Play也推送了剩下三个他家的软件——其中有一个叫做Proxymon。一看,正是我想要的:它会在手机上安装一个根证书,然后手机上的网络全走这上面一圈儿(中间层了么这不就是),然后解压。 于是,我便开始了我的折腾之旅。 第一件事儿,打开手机。发现手机0%电。小米手机这点好:插上电源0%也能开机——不像苹果必须达到一个安全值后才可以开机。 之前root过的手机不知道怎么回事儿root还给关了。幸亏早就刷了自定义的Discovery系统,很快重新root了。 打开Wicap和Proxymon,下载了12306,查询香港西九龙至随便点了一站。这样的话,APP会提交一个http请求,并且在里面显示出发到站和请求的出发日期。 很快,通过Proxymon我就读到了我需要的数据: OK,from_station=XJA,看来香港西九龙的电报码是XJA无误了。 那既然这样了,我为什么不直接顺便把整个请求链抓下来呢?Proxymon是我第一次使用,之前没有购买过,而免费版只会记录256kb的数据。准备购买完整版,却在支付的时候被Google Play拦截了,死活无法支付——从信用卡到PayPal到礼品卡都无法支付。给Google打电话用了45分钟才把问题解决好——因为我需要重新验证我的身份(安全是安全,但是真耽误事儿啊)。 很快,我得到了一堆(解密过的)数据包。dump到电脑后,发现里面所有Content-Encoding: gzip的response无法被解压——原因不得而知。试用了直接将response体存为文件用gzip解压,失败;用python找zlib库解压,失败;甚至直接用之前的代码套了个http server(dump下来的是http请求体和返回体如同上图,所以该有的header等都有)直接返回到浏览器或者给curl解压,也失败。得到的城市数据库等都无法被成功解压成response里所说的text/plain或者application/json(说白了还是text)格式,都是一大堆二进制数据。套了http server之后让浏览器自动解gzip失败后它自动把二进制数据下载了下来,大小和chunked里面描述的大小完全一样;同理,对于request请求体,很多写了Content-Type: application/json的也是一片乱码。用TridNet来分析response返回来的二进制文件也无法分析出是gzip格式。估计是12306学聪明了,把请求加密了一些。具体怎么解密,估计就不是今天能解决得了的事儿了。 此路不通,总有留爷处么(什么鬼混搭)。决定从APP入手。毕竟12306只需要从网上get一次基础数据,以后都可以用了就——这说明,他们肯定是有持久化存储的。果不其然,在文件系统的data目录里找到了12306的数据库——看到扩展名为db,第一个想法就是“这八成是SQLite吧”……把文件传到了电脑上,读取了一下——果然是SQLite! 好了,那就搜索一下就好了么…… 有意思的是,香港西九龙在12306 APP上的拼音的确为HKWestKowloon。这要是真的输拼音进去然后找不到香港西九龙该多尴尬啊…… 这是谁才能想得到这个站的拼音叫做HKWestKowloon,然后拼音缩写还是xg…… 证明一下: 同时,对id的搜索并未找到有电报码为-XBA的车站,也无法找到名为“边界”的车站。说明“边界”站未上表(比如不办理客运业务等)。根据这位提问者的说法,有TRS数据事实证明该站存在(注:TRS为中国铁路的售票系统,就是你去车站买票的时候车站售票人员用的那个软件)。他推测的本站定性为:“广深港高速线深港段的分界站,划定内地和香港铁路资产范围”。但是无论如何,我个人还是认为眼见为实的。目前来说我没有看到该站直接事实存在的证据,而该车站存在的方式也不好说(真的是个“站”是不可能了,没准就是个什么标记啥的呢。参考海岫铁路的那一堆车站,一个没见到影。跟着高德地图去了一趟所谓的析(shi2)木站,真的是什么标记都没有,周边都是玉米地)。 无论如何,任务完成了。上面提到的无法gzip解压(也许是解密)的问题以后可以再说。 今天一整天都耗在这上面了,连午饭都没吃就到了晚饭的点儿了。抛砖引玉,希望各位能够对12306的底层协议和数据结构等发展出更深刻的了解吧。

体验Amtrak Pacific Surfliner

体验Amtrak Pacific Surfliner

这次来美国,是从PEK乘坐的CA航到SFO之后转VX到了SAN. 这次回国,干脆选择从LAX走好了,方便快捷。 从SAN到LAX机票太贵(130$),而且我到市区也不方便,最方便的方法莫过于火车。 从学校到火车站用时大概是30分钟吧,相当方便(也算运气好,刚到公交站车就来了,下一班车应该是30分钟之后) 有学校学生卡 坐公交免费(当然我们每学期也是交了不到50$,但是这儿公交可是2.25$单程啊……月票也72$呢啊……) 从学校坐公交坐到了Solana Beach,一个风景很好的站。 不,应该说这条线路就是在太平洋沿岸,整条线路就是漂亮。   美铁内部内饰还是相当不错的。 二等座(Coach)的舒适程度不亚于国内动驴的一等座啊……甚至更甚啊…… 2+2的座位排列,大座椅间距的舒适程度简直没得说…… 仍然是美铁(或者说是西方)典型的乘车模式——上车查票。 我上车的Solana Beach(SOL)是一个Amtrak和本地NCTD运输公司共同运营的车站。 车站无需检票,是开放式的,从马路上了台阶就是。 NCTD刷卡机在站台上。若需要乘坐NCTD的火车,那么直接在站台上刷卡即可。 当时我已经把我的Amtrak票扔到手机Passbook里面了,上车直接让检票员扫passbook,极其方便。 只是,检票员对我吐槽手持检票机扫手机经常扫不上,得扫半天…… 比如我的就是扫了整整三十秒才扫上…… 总体来说,旅途很愉快,就是特别困…… 到了LAX我才醒…… 好了就这样,差不多了,有时间配图。   –配的都是从LAX回来的图……