Good good study, day day up

aleung的学习笔记, aleung的idea

跑步日記

| Running

今天難得的陰天,早上下過雨,溫度30℃出頭,沒有早幾天那麽酷熱,也有點風。 磨磨蹭蹭,早上10點半才出發。熱身段過後,按5’30”配速,從江灣橋過河南,沿江邊一直往東跑。

過了廣州塔,就到獵德大橋,大概10km位置。這時我面臨著一個艱難的選擇:上橋,就過到珠江新城然後沿江邊往回走,穿過二沙島回家,這是跑過好多次的路線,大概十七八公里左右。如果直走,就一直要到琶洲大橋才能過橋,到了北岸往回跑,要到家路程估計有近30公里,這時我從沒有跑過的距離。在我的大腦還在激烈思想鬥爭的時候,雙腿肌肉已經作出了決定——直走。

考慮到前路漫漫,將速度下降到5’50”。這時接近正午時分,雖然沒有太陽直射,人也比較熱,心率上升到接近160。找賣水的地方,但琶洲一帶很荒蕪,估算著也撐到過了琶洲橋後也沒問題。

13.5km處上橋,這橋真長,足足一公里。過了琶洲大橋下來,14.6km,去超市買運動飲料喝,停了幾分鐘。這麽一停下來,就沒法重新跑起來了,完全不想動。繼續跑後氣喘得很厲害,隔夜風爐都吹得著,腳擡不起,步頻下降了很多。將速度下降到6’30”了,希望能夠慢慢適應過來。堅持了一段,毫無起色,終於在過了華南大橋底,到了17km處放棄了。不清楚為什麼買水停了一下後狀態會突然變得那麽差,看回數據,過橋前的速度還是保持得比較平穩的5’50”左右。以前我也有經驗是不能停,一旦停下就很難重新回復狀態,但慢慢適應一段時間後還是可以的,這次完全不行。

找不到廁所,鑽進樹叢裏面尿尿。舒暢完後渾身酥軟,一轉身沒站穩跟身後樹幹長滿刺的木棉樹來了個親密接觸。

沿著江邊走,中午很寧靜,人不多,只有知了在不知疲倦的叫。突然覺得這個環境很舒服,享受一下時光吧,在榕樹陰下的石凳坐下,冰冷的石頭冷卻著大腿的肌肉,涼風吹拂身上的汗水。出來跑步什麼都沒有帶,不用再習慣性的拿手機來看,就讓時間的碎片留白,就是那樣靜坐著,看著開闊的江面,感覺那TMD不就是幸福麽。所以人都是自己感動自己的,要不哪來那麽多感人的事情。

歇了一會,將運動飲料全喝完了,感覺恢復了一些,起來繼續跑一下,邊跑盤算著後面還能再跑多遠。但是,跑累了的時候就是靠內心去堅持的,原來一直習慣了喘著氣的狀態,可以一直跑下去,一旦享受過停下休息的舒服後就承受不了之前那種苦了。最後跑到珠江新城地鐵站收官,累計20.5km。後面這段其實心率還在正常範圍,肌肉沒有不適,就是步頻慢了,按理說這個狀態還可以繼續跑上好一段距離的。

另一方面,今天跑的狀態看來確實不是那麽好,跑完幾個小時的感覺比以往跑這個距離要累。 回來看數據,感覺步頻似乎是反應體力狀態的一個直觀指標,從8.4km起步頻明顯下降了一個台階,而14.6km買水後步頻更是嚴重下降。另一方面,心率跟狀態有什麼關聯也還不是很清晰,每次跑步隨著疲勞累積,心率都是不斷升高的。但看以往的記錄,心率到160多速度依然保持的也有。

中國電子地圖偏移

| GPS_GIS

幾年前我寫過對Google中國地圖偏移規律的分析(1)(2),根據抓取到的偏移量數據,大概看出呈現了sin(a)+sin(3a)這樣的函數曲線規律,並且這個函數以不同頻率和幅度疊加了兩次。當時我推導出函數及其係數,利用它去校正偏移,在百公里範圍的區域內已經非常理想,但是在全國大範圍的不同區域,係數需要有點不同,也就是擬合函數還是差了一些低頻率的細節。不過當時的分析細節我也不敢在博客裏面寫,後來我也沒有再搞地圖方面的應用開發了,就把這個放下。

實際上這個地圖偏移並不是Google自己搞的算法,而是國家測繪局以立法的形式統一要求加的,稱為地形图非线性保密处理,所有從事國內電子地圖的廠商應該都得到了這個算法,實際上並起不到什麼所謂保護國家安全和國家利益的作用(保護行業壟斷者利益倒是真的),但是這個地圖偏移對地理信息處理和GPS技術的民用化起到了巨大的阻礙作用,近年各種與地理位置相關的應用如雨後春筍般湧現,但都為中國地圖的偏移而頭痛不已,後來由於下面提到的算法的流傳,問題得以解決,但增加很多不必要的複雜性和浪費開發、數據處理的人力。在我看來,這個地圖非線性加密處理在地理信息領域就像GFW在互聯網信息領域一樣,浪費了大量社會財富來對技術發展與應用進行封鎖。李成名,你真的成名了。

感謝Internet,感謝open source,現在這個偏移算法在網上已經可以輕松找到了。

網上流傳的原始算法是這個Java文件,然後有人整理過代碼,接力開發出多種語言版本。在『A Fork of Stuffs』博客裏,地球坐标系 (WGS-84) 到火星坐标系 (GCJ-02) 的转换算法給出了C#實現,這個博客另外一篇火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法也很有用。而使用比較方便應該是下面的github代碼庫:

另外,github裏還有一個項目 fourcels/lbs 是用查表法來糾偏的,裏面的偏移數據(共9M)說不定就是早期從Google地圖服務上抓下來的。但現在有了算法,查表法的價值就不大了。

Pebble

| Gadget

Pebble手錶戴了兩個星期,如果用一句話來總結感受,那就是:基本滿意,但還沒到愛不釋手的程度,沒有帶來驚喜。

首先,Pebble真的是一隻手錶,可以看時間。如果你有幸用過各種『智能手環』,就會明白為什麼這麽說了。我戴過Jawbone UP一段時間,試過好多次下意識的擡起手腕來看,然後才想起那貨是沒有任何顯示的。

佩戴舒適度上說,Pebble還過得去,塑料錶帶的柔軟度不錯,反正我已經習慣了24小時戴在手腕上的感覺。在這之前,我都有十幾年沒有戴過手錶了吧。

外形應該是我最不在意的一項了,但不得不說 Pebble 外形上太普通。我的黑色版本,正面看弧形表面,與黑白顯示屏融為一體,還算有點現代感,但側面看就很『薯鈍』的樣子 —— 厚,按鈕粗曠,左邊還有很突兀的幾個充電觸點。

手錶用的是 144x168 的低分辨率黑白e-paper屏幕,在現在手機電腦都視網膜屏的時代,這個分辨率真是超低了。E-paper的對比度很高,無論什麼光線條件下都非常清晰,雖然分辨率低,實際顯示文字的效果還是不差的。圖像?就算了吧,除了像素少,這個屏還連灰度都顯示不了。不知道這個e-paper跟Kindle之類閱讀器的屏是不是同樣的技術,但看起來還是有區別:Pebble屏的像素邊緣很銳利,顯示直接改變沒有殘影,不像Kindle要全屏反色刷一次。

Pebble 可以安裝 app,當然了,否則就對不起 smart watch 這個名字。App 分為 watchface 和 watchapp 兩大類,無論是那種也不管大小,總共最多安裝8個,不知道它內部怎麼管理空間的。Watchface 只有一屏顯示信息,不能接受按鍵控制,最常見用途是顯示時間,當然也可以顯示其他信息,例如天氣、日曆之類。Watchapp就是可以與用戶交互的應用,可以有多屏,用戶通過菜單、控制按鈕來操作。

Pebble 的方便之處是它作爲手機的一個延伸的信息終端,手機可以將實時的信息推送到手表上,或者是在手表上顯示濃縮的手機應用的某些信息。前者例如,我以前經常會漏接電話或者漏看短信,因爲手機放袋裏聽不到聲音,現在戴著 Pebble 就不會了,因爲手表會振動提醒。後者例如一些跑步應用,能在 Pebble 上顯示速度、距離等關鍵信息,就不用拿手機出來看。

Pebble 最大的問題是操控不方便。表上有四個按鈕:上/下/Enter/ESC,沒有觸摸屏,任何操作都只能靠按鍵選擇菜單項,因此經常要按好多次按鈕才能完全想要的操作。而 Pebble 的按鈕按起來又不算是特別方便,總之我是不會想在手表上做按超過一兩次按鈕的操作的。這種操控的不方便限制了app可以做的事情,感覺這個比起屏幕和表的硬件處理能力的限制還要大。Pebble 也不支持 app 後台運行,要求在手錶上跑多任務,電池撐不住吧,但沒有多任務也造成一些類型的 app 沒法做了。

至于耗電,目前還不至于很大問題。官方宣傳可以用5-7天,我實際用下來只有3天,也不知道是軟件問題還是硬件問題。但3天其實還是可以接受的。

最後介紹一下我現在常用的app:

Watchface

Agenda Watchface

在辦公室或者需要按日程做事的時候會用這個watchface,一眼就能看到當前時間和接下來的日程安排。

Postage

當我不需要看日程安排的時候,喜歡用這個face,夠簡潔,外圍的黑色與黑色表身融為一體。實際看起來比截圖好看很多。

Watchapp

PebbleAuth

二步認證的token生成器,相當於 Google Authenticator 運行在手錶上,這樣更加安全啦。現在除了 Google,LastPass 和 EverNote 都支持二步認證了。

Sleep as Android

我買 Pebble 就是因為看到 Sleep as Android 支持 Pebble 了,才動了心的。這個應用利用 Pebble 上的運動傳感器監控睡眠的深淺度,早上能夠在合適的淺睡眠週期通過振動叫醒。我以前就在用 Sleep as Android,但要用手機的運動傳感器,所以手機要放在床墊上,現在戴著手錶就行了,手機可以放遠一些。

Text to UML Diagram

| SoftwareDev, UML

Usually I used Astah to draw UML diagram to put into design document in MS Word or PowerPoint format. The separation of the source and generated file making management of the UML model file a problem. And also it’s annoying to adjust a large amount of elements by dragging with mouse whenever you add something in the diagram. For a coder, typing on keyboard is faster than drawing with mouse.

Now I switch to PlantUML. Just write UML in its DSL and PlantUML generates the diagram. It supports most of the frequent used UML diagrams, which I use most are sequence diagram, class diagram and state diagram. Then I paste the generated diagram into slides (design document) and keep the “source” in note. No need to wonder where to find original UML model file when I need to update the diagram.

The core of PlantUML is simply a jar file. It parses the text input and depends on dot tool from Graphviz for graph generation (except sequence diagram).

There are a bunch of ways to run PlantUML. I highlight some of them I prefer:

  • Online editor. Best choice if you’re too lazy to install anything on your computer.
  • Desktop (Windows): PlantUML File Watcher
  • Embedded into Octopress blog platform. The below examples are using it.
  • IDE plugin. Easy way to keep UML together with source code.

The syntax of PlantUML’s DSL is quite intuitional, you can start to use it by following example.

1
2
3
4
5
6
7
8
9
10
11
package ConsentObject <<Rect>> {
  Consent : id
  Scope : key
}
 
Client - User
(Client, User) . Consent
 
Consent - "*" Scope
 
Consent "1" -- "1..*" AccessToken

The generated diagram:

A sequence diagram example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
title OAuth 2.0 Authorization Code Grant

actor    UserAgent       as UA
participant Application     as APP
participant OAuthServer     as OAuth
participant ResourceServer  as RS

== Application requests authorization from user ==
UA->APP: 
APP-->UA:redirect to OAuth Server
UA->OAuth: GET /authorize?response_type=code
ref over UA, OAuth: user authentication\nuser confirms reqest
OAuth-->UA: redirect to App with authorization_code
UA->APP: authorization_code

== Application retrieve access token ==
APP->OAuth: POST /token with authorization_code
ref over APP, OAuth: client authentication
APP<--OAuth: access_token

== Application access protected resource ==
APP->RS: getResource with access_token
RS->OAuth: validateToken(access_token)
RS-->APP: result

拦截Android应用HTTPS通讯内容

| Android, SoftwareDev

昨天在捣弄 miCoachNike+ 的数据迁移,到了最后一步发现调用 Nike+ API 需要传送client_id和client_secret,这两个信息是用来认证客户端的,但Nike并没有公开开放API,因此无法申请到client_id。看 tcx2nikeplus 的作者说他是通过查看iPhone应用发送的请求来拿到这两个信息的。但是 Nike+ API 都是走HTTPS的,普通方式的截包看不到加密传输的数据。

要嗅探加密传输,必须通过中间人攻击的方式才行。上网搜索一下看看有没有现成工具,果然一搜就找到了:Burp Suite。它是一个安全测试工具,功能好像有不少,我这里用它做代理,从中监控应用到服务器的通讯内容。

下面记录大致操作过程。

在PC上安装运行Burp,设置 Proxy - Options - Proxy Listeners,让它监听合适的地址和端口,并且选择 “Generate CA-signed per-host certificates”。

将浏览器代理指向Burp proxy,访问任意一个https地址,Burp这时是中间人,它会用自己的根证书(PortSwiggerCA)签发一个目标服务器的证书,替换了真正服务器的证书。浏览器应该会有安全报警,因为系统并不信任签发这个证书的CA。查看证书详细信息,选择根证书并且信任这个根证书,就会把PortSwiggerCA的证书加入到系统的信任列表中。

要将这个根证书装进Android,需要先从系统 key chain 里将它导出到文件(.pem格式),然后执行下面的命令将它转换为DER格式后缀为.crt的文件。

openssl x509 -in PortSwiggerCA.pem -inform PEM –out PortSwiggerCA.crt -outform DER

接下来,将 PortSwiggerCA.crt 放入Android的sdcard,在系统安全菜单中安装证书。证书安装后,Android系统就会信任所有Burp签发的证书了。

在Android的WLAN设置代理指向Burp。但很多Android应用都不理会系统的代理设置,不使用系统指定代理,遇到这种情况就要用 ProxyDroid 来设置GlobalProxry(手机要root)。设置好了,在Burp里面就能够拦截到Android应用的HTTPS通信明文了。

注意:为确保安全,测试完之后要将 PortSwiggerCA 这个根证书从PC和Android系统信任列表中删除。如果不是临时使用,应该要用自己的证书代替Burp提供的证书。

这个故事告诉我们,中间人攻击并不是那么复杂的事情。特别是终端应用开发者,不可寄望于通过加密传输来隐藏应用到服务器的协议细节,要逆向工程是很容易的。