ETH ICAP 地址协议算法实现

以太坊钱包生成收款码时,有些是直接拿裸地址例如 "0x0728F0...75445F" 生成收款二维码,例如 TrustWallet;还有些是使用 "iban:" 开头的 ICAP 串来生成收款二维码,例如 imToken 1.0。

IBAN 本身是国际上一部分银行间转账使用的账号代码格式,以太坊社区在 IBAN 地址格式上做了一些扩展,用来编码以太坊地址和校验码,用作地址交换使用,叫做 ICAP (Inter exchange Client Address Protocol)。

IBAN 编码看起来很简单,但在实现上字母到数值的转换方法挺 trick 的,需要花一些时间进行理解。为简化理解,下面我拿一个例子来说明整个编码过程。

假设我们已经有了一个以太坊地址:0x730aEA2B39AA2Cf6B24829b3D39dC9a1F9297B88,下面是生成对应 ICAP 地址的过程:

第一步:将原始 16 进制以太坊地址转换成为 36 进制地址:

16 进制 ETH 地址:0x730aEA2B39AA2Cf6B24829b3D39dC9a1F9297B88
36 进制 ETH 地址:DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4

第二步:为 36 进制 ETH 地址拼接上国家码 "XE" 和空校验字符串 "00" 形成 36 进制待校验字串:

36 进制 ETH 地址: DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4
36 进制待校验字串: DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4XE00

第三步:将 36 进制待校验字串逐字符转成 10 进制数字字串:

36 进制待校验字串: DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4XE00
10 进制待校验字串: 1315273521273029152915344143118231017341572926622101234174331400

第四步:将 10 进制大整数对 97 取模,然后用 98 - 模数:

校验码:42 = 98 - 1315273521273029152915344143118231017341572926622101234174331400 % 97

第五步:将校验码替换空校验字符串,然后重新安排 XE** 到地址前,并加上前缀:

36 进制待校验字串: DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4XE00
36 进制已校验字串: DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4XE42
36 进制 IBAN 号: iban:XE42DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4

可以用这个 IBAN 号生成二维码,用支持 iban 地址的 app 扫描二维码验证下是否能解析到正确的 ETH 原始地址。

ICAP 地址生成和校验的实现,可以参考下面这段 Java 代码,可直接用于 Android 客户端:

package com.yangwenbo;

import java.math.BigInteger;

/**
 * Ethereum ICAP (Inter exchange Client Address Protocol) Address Converter
 * Convert Ethereum Address from/to ICAP iban address
 *
 * @ref https://github.com/ethereum/wiki/wiki/Inter-exchange-Client-Address
 * -Protocol-(ICAP)
 */
public class EthICAP {
  private static String ICAP_XE_PREFIX = "XE";
  private static String IBAN_SCHEME = "iban:";
  private static String IBAN_MOD = "97";

  /**
   * Build ICAP iban address from ethereum address.
   *
   * @param ethAddress ethereum address
   * @return ICAP iban address
   * @example input:  0x730aea2b39aa2cf6b24829b3d39dc9a1f9297b88
   * return: iban:XE42DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4
   */
  public static String buildICAP(String ethAddress) {
    if (!ethAddress.startsWith("0x") || ethAddress.length() != 42) {
      throw new IllegalArgumentException("Invalid ethereum address.");
    }
    BigInteger ethInt = new BigInteger(ethAddress.substring(2), 16);
    String base36Addr = ethInt.toString(36).toUpperCase();
    String checkAddr = base36Addr + ICAP_XE_PREFIX + "00";
    String base10Str = "";
    for (Character c : checkAddr.toCharArray()) {
      base10Str += new BigInteger(c.toString(), 36);
    }
    Integer checkSum = 98
        - (new BigInteger(base10Str)).mod(new BigInteger(IBAN_MOD)).intValue();
    String icapAddress = IBAN_SCHEME + ICAP_XE_PREFIX 
        + checkSum.toString() + base36Addr;
    return icapAddress;
  }

  /**
   * Decode ethereum address from ICAP iban address
   *
   * @param icapAddress ICAP iban address
   * @return ethereum address
   * @example input:  iban:XE42DFRZLRUTFTFY4EVINAHYF7TQ6MACYH4
   * return: 0x730aea2b39aa2cf6b24829b3d39dc9a1f9297b88
   */
  public static String decodeICAP(String icapAddress) {
    if (!isValid(icapAddress)) {
      throw new IllegalArgumentException("Invalid icap address.");
    }
    BigInteger ethInt = new BigInteger(icapAddress.substring(9), 36);
    String base16Addr = ethInt.toString(16).toLowerCase();
    return "0x" + base16Addr;
  }

  /**
   * Check ICAP iban address validation
   *
   * @param icapAddress ICAP iban address
   * @return true if valid; false if invalid
   */
  public static boolean isValid(String icapAddress) {
    if (!icapAddress.startsWith("iban:XE") || icapAddress.length() != 40) {
      return false;
    }
    String base10Str = "";
    for (Character c : icapAddress.substring(9).toCharArray()) {
      base10Str += new BigInteger(c.toString(), 36);
    }
    for (Character c : icapAddress.substring(5, 9).toCharArray()) {
      base10Str += new BigInteger(c.toString(), 36);
    }
    Integer checkSum
        = (new BigInteger(base10Str)).mod(new BigInteger(IBAN_MOD)).intValue();
    return checkSum == 1;
  }
}

更新 JabRef 2.7 中文版

JabRef 的中文版是我翻译的。但是好久没有关注邮件列表,偶然瞄到才发现又有新增的部分需要翻译。于是今天就花了些时间更新了一下中文翻译,将会集成到 JabRef 的 2.7 版本中。“抢先版”请看这里 ^_^

另外,在我 Windows 平台下的 JabRef 2.6 以后版本中,列表页中文文献名都显示为方框,由于下方细节中有正确显示,我也就没管它。但是 Linux 下却显示正常,这点让我比较好奇。今天才发现 Windows 平台下需要设置列表页字体为中文字体才能正确显示。这样看原来的显示正常到方框,大概与 Java 不同版本的默认字体设置有关系。

再另外,sourceforge 的 svn checkout 速度可是真慢啊!不知道是不是帝国的网络条件导致的。

JPerf Single Jar with UDP BW Unit Fixed

JPerf is the GUI frond-end of IPerf, a TCP and UDP bandwidth performance measurement tool which allows the tuning of various parameters and UDP characteristics.

The official JPerf release (2.0.2 version) has some flaws. First, it mistakenly uses bytes/sec as the unit of UDP bandwidth, which should be bits/sec according to IPerf man-page:

-b, --bandwidth #[KM]
       for  UDP,  bandwidth  to  send  at  in  bits/sec (default 1 Mbit/sec,
       implies -u)

Second, starting it from command line is error prone. The command to start it (jperf.sh) is:

java -classpath jperf.jar:lib/forms-1.1.0.jar:lib/jcommon-1.0.10.jar:lib/jfreechart-1.0.6.jar:lib/swingx-0.9.6.jar net.nlanr.jperf.JPerf

We can see that all jar paths in classpath are relative paths. So if we create a symbol link to the jperf.sh script, e.g. /usr/bin/jperf -> /opt/jperf-2.0.2/jperf.sh. Then calling /usr/bin/jperf will result in some errors like:

Exception in thread "main" java.lang.NoClassDefFoundError: net/nlanr/jperf/JPerf
Caused by: java.lang.ClassNotFoundException: net.nlanr.jperf.JPerf
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: net.nlanr.jperf.JPerf. Program will exit.

This error can be fixed by resolving the real path of the symbol link, as I reported.

However, a better way to solve this problem is to pack all libs JPerf needed(i.e. forms*.jar, jcommon*.jar, jfreechart*.jar, swingx*.jar) to a single jar, and add a proper "Manifest". Then we will be able to start JPerf with a much simpler command:

java -jar jperf.jar

And finally, I gave a try to solve the above 2 flaws and put my work (deb/jar/src packets) on my site. You can find them here .

ACM 图灵奖演讲论文集

今天尝试了一下 JabRef 论文数据库的 HTML 导出,将我搜集的 ACM Turing Award Lectures 的 BibTeX 信息输出到了这个页面

由于版权问题,无法给出 PDF 文件下载,但是每篇论文后面都给出了 DOI 链接,有 ACM 数据库访问权限的用户可以自己去下载。如果您是我的朋友且对此感兴趣且无法访问 ACM Portal,可以在 IM 上联系我索取 PDF 包(为个人学习、研究或者欣赏使用),Email 是不行的,因为太大了。

事实上,这个页面的大部分文章是收入《ACM Turing Award Lectures -- The First Twenty Years : 1966 to 1985》中的,中国的苏运霖教授翻译后出版了《ACM图灵奖演讲集:前20年》。

再为 JabRef 做个广告。我不知道其它的论文管理工具能否做这样的事情,不过 JabRef 输出的 HTML 页面真的很不错。我以后要是成为学术男,就用它来发布我发表的论文列表 :)

Ubuntu 9.04 安装手记

此次安装是在一台 Dell OptiPlex 740 台式机上进行,处理器 AMD Athlon 64 X2 4400+,显卡 nVIDIA GeForce 6150,声卡 SigmaTel STAC9200。Ubuntu 版本为 9.04 Jaunty Jackalope Alpha 5 amd64 位版,硬盘安装。

1. 硬盘安装时在分区那步仍无法列出分区表,需要 Ctrl-Alt-F2 进入控制台 2 手动 umount -l /hd-media 后重试。

2. 开箱显示正常,但 Compiz 3D 特效无法开启,可能因为没有可用的受限驱动。

3. 默认 ALSA 驱动不支持该声卡,但选择 OSS 驱动可以支持(很奇怪)。必须在音量设备那开启对 capture 设备,才能录入声音,此时可以使用 ALSA 驱动。在使用 Mplayer、SMplayer 之类播放器播放视频时,需要手动在选项中选择声音输出的驱动为 OSS。

4. 安装 smplayer 之后即支持 avi 格式解码,不用手动下载 codecs。在播放 720p 以上高清视频时,最好将 smplayer 的本地缓存调整为 10M 以上(默认为2M),否则容易引起底层 mplayer 内存问题,会无法播放、内存占用过大死机或崩溃。

5. Socks 代理软件 Dante 源代码在该 x86_64 平台上编译后运行会出现段错误;更换为 antinat,经源码编译后运行正常。

6. Libfetion for 64 位 deb 包不可用,异常退出;经源码编译后运行正常。

7. sendsms 编译为 64 位版本会出现段错误,但短信仍能发送成功。

9. 网易的 Ubuntu 软件仓库镜像不包含 Jaunty,cn 的镜像没有总镜像快,security 的连接速度太慢。正式发布后,网易已经有了 Jaunty 源。

10. 使用 Firefox 时可直接安装 Adobe Flash Player 10 64 位版本。

11. 新的状态通知很漂亮,可以显示 Pidgin 上好友的登录和短讯。

12. 根分区使用 ext4 文件系统,数据分区为了与其它系统保持共享仍采用 ext3 文件系统。

13. 安装中文支持时可以选择是否安装该语言用户常用软件,选择是则会增加 PCManX、StarDict 等软件。PCManX 中包含非常全的港台和大陆 BBS 地址簿,但是字体有问题,未解决;QTerm 5.3 会崩溃。

14. 传说中的启动加速没有明显感觉,也许是因为启动的服务太多。

15. Ubuntu 9.04 Jave 程序中文显示不正常,部分文字变成方格。文泉驿字体从 wqy-zenhei.ttf 改为 wqy-zenhei.ttc,导致 java 程序中文字体显示不正常。在 /etc/java-6-sun/fontconfig.properties 中添加 wqy 相关内容,diff 文件可以从这里下载。Java 貌似不可用 ttc 字体,从 8.04 拷来 wqy-zenhei.ttf 到 /usr/share/fonts/truetype/wqy 目录下可解决,wqy-zenhei.ttf 也可以从这里下载。

16. 在另一台笔记本 Dell D630 上安装 9.04 正式版时,发现居然默认不支持 NVS135M 视频驱动,需要配置好网络后,使用命令 sudo apt-get install nvidia-glx-180 安装 Nvidia 180 版本的驱动,或者自己到 NV 网站上下载最新驱动。

在 Ubuntu Linux 8.04 上安装永中 Office 2007

这篇文章介绍了在 Ubuntu Linux 8.04上安装永中 Office 2007 遇到的问题以及解决的办法。由于其主要问题在于 Java 虚拟机,其它 Linux 平台如果遇到同样情况也可以借鉴这里的方法。

永中 Office 2007 Linux

目录

1. 介绍
2. 下载
3. 安装问题
4. 运行问题

1. 介绍

用 OpenOffice 总会遇到这样那样的中文问题,有时候怎么也搞不定,很令人沮丧。听说永中 Office 虽然只放出试用版,但在 Linux 下超过试用期后只会提示超期而不会禁止使用,就尝试着装了一下永中 Office。

2. 下载

从官方下载地址:http://www.evermoresw.com.cn/webch/download/downEIOffice.jsp 下载永中 Office 2007 Linux 安装包。

安装之后才知道 Ubuntu 中文源中有打包好的 deb 文件,要从源中直接安装就方便许多了。比如用 CN99 源的话,将:

deb http://ubuntu.cn99.com/ubuntu-cn hardy main restricted universe multiverse

加入 /etc/apt/sources.list 中,然后:

$ sudo apt-get install eio

即可。我没有尝试这一方法,从源直接安装显然不会出现下面的"3. 安装问题",但不知道会不会出现下面讨论的"4. 运行问题"。

3. 安装问题

下载好官方的 Office 2007 Linux 安装包之后,先解压:

$ tar -xzvf EIO2007BetaZH_Lin.tar.gz

然后,进入安装目录,执行安装脚本:

$ cd 4.3.1210.101ZH.L1/
$ sudo sh setup.sh

将会出现下面错误,而且安装窗口显示为空白(窗口空白可能是由于 Beryl 引起的 Java Swing 界面问题):

Decompression in Progress,Please Wait.
Locking assertion failure. Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0xb2a66767]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0xb2a668b1]
...

这个问题可能因为永中 Office 使用自带的 JRE 和系统的某些库不匹配导致的,所以我们只需更改安装脚本,让它使用系统的 JRE。用编辑器(如 vim)打开 setup.sh,按照下面的方法注释掉解压和使用自带 JRE 的两行,添加一行使用系统 JRE 的命令。(注意:使用 gcj 的 jre 也会出现错误,最好使用 Sun 官方的 jre,Ubuntu 下使用 sudo apt-get install sun-java6-jre 安装。)

$ vim setup.sh
#unzip $progdir/Jre.zip -d /tmp/EIOffice/ &> /dev/null
#/tmp/EIOffice/Jre/bin/java -jar $progdir/dispose.jar $1
/usr/lib/jvm/java-6-sun/jre/bin/java -jar $progdir/dispose.jar $1

然后再执行 sudo sh setup.sh 命令,就能出现正常的安装窗口了。下面的安装步骤和 Windows 下软件的安装步骤颇为相似,只是选择安装路径那一项最好将 /usr/local 改成 /opt,因为永中 Office 不是开源软件。

4. 运行问题

安装完成后,运行永中 Office:
$ eio
Locking assertion failure. Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0xb7d37767]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0xb7d378b1]
...

和刚开始安装时一样,出现下面错误,主窗口中也是空白。如前面所说,窗口空白可能是由于使用了 Beryl 窗口管理器引起的 Java Swing 界面问题,可以通过修改永中 Office 的启动文件解决,在 /usr/bin/eio 中正式代码前添加 export AWT_TOOLKIT=MToolkit 一行:

$ sudo vim /usr/bin/eio
#!/bin/bash
export AWT_TOOLKIT=MToolkit
exec 4<&0 0

GF in Beijing Now

好久没更新了,当然了,原因是很多的,标题是最重要的一个。

我们家 xixi 24号考完放假就来北京啦,在学校周围给她租了个床位(没办法,北京租房太贵了),正好在这陪我上小学期。

暑期实习的事情算是没戏了,不是别人看不上咱,就是咱时间不够。也好,准备放假就回家,带着女友 ^_^

北京这几天太讨厌,天天傍晚对流雨,还没见过那么潮的天气呢?出去玩已经被淋了三次了~~~快点儿放晴吧,不然都不敢走远了。

昨天参加了一个 Java 移动开发者大会,Sun 挺大方的,每个报名的人送了几张光盘和一本《NetBeans权威指南》,定价75块呢。可惜等不及下午一点的免费午餐,早早就撤了。下午怕下雨,也没去观摩一下抽奖活动,索爱手机啊~~~

三星手机 Java 开发-Hello World 篇

摘要:

这篇文章主要介绍了在 Windows 平台上使用 NetBeans 和 Samsung SDK 构建三星手机 Java 开发环境,建立和调试简单 Java 程序的过程。

目录:

1. 工具
2. 安装和配置开发环境
3. Hello World 程序
4. 在三星模拟器(Samsung Emulator)上调试
5. 结论
6. 参考文献

1. 工具

Windows XP: SamsungSDK 不支持 Windows Vista.

JDK version: 1.6.0_03: 这个版本不重要,自己去下载好了。

NetBeans IDE 6.01(Mobility) Chinese Edition:
http://zh-cn.netbeans.org/download/6.0/ml/netbeans-6.0.1-ml-mobility-windows.exe

Samsung Java SDK 1.0.2
http://developer.samsungmobile.com/Developer/resources/SamsungSDK/SamsungSDK_1.0.2.zip
这个版本的 SamsungSDK 支持的三星手机型号为:
D900 (D600, D820, T809)
E200 (E380, E390, E500, E780, E830, P200, T509)
E250
E590
E740
E790 (E490, E530, E570, E620, E720, E880)
E900 (D800, D830, D840, P900)
F500 (F500, P300, X820, Z370)
J600
L760 (Z140, Z150, Z170, Z230, Z240, Z240E, Z300, Z310, Z360, Z500, ZM60, ZX10, ZX20, ZV40, ZV60)
P310
U100
U600 (U300)
U700 (P910, P920, P940, Z400, Z540, Z560, Z720, ZV50)

2. 安装和配置开发环境

我不知道 JDK 是否必须安装的,因为我电脑里老早就安装上了,但是做 JAVA 开发嘛,JDK 总是需要的,所以建议首先安装 JDK。

安装完 JDK 之后,安装 SUN 公司的 JAVA 集成开发环境 NetBeans。为什么是 NetBeans 而不是 Eclipse?因为 SamsungSDK 官方支持 NetBeans。

当 NetBeans 安装完成后,接着安装 SamsungSDK。需要注意的一点是,由于 SamsungSDK 1.0.2 支持的 NetBeans 版本是 5.5,所以在安装过程中要选择是否安装 NetBeans 插件时,请选择否,因为我们使用的 NetBeans 版本是 6.01。

既然无法自动安装 NetBeans 插件,就需要我们在 NetBeans 中手动添加插件了。具体步骤如下:

一,从 NetBeans 菜单中选择“工具->Java平台”,进入 Java 平台管理器;(我们的 NetBeans 是中文版 *_*,请英文版用户自行理解。)
二,点击“添加平台”按钮,进入“选择平台类型”步骤,选择“Java ME MIDP 平台仿真器”,进入下一步;
三,在“选择要在其中搜索平台的目录”对话框中,选择 SamsungSDK 的安装目录,比如我的是 D:\Program\SamsungSDK,点击确定;
四,这时在“平台文件夹”对话框中会出现三个要检测的平台,将三个平台都勾选上,进入下一步;
五,在“已检测到的平台”对话框中,将三个平台都勾选上,选择“完成”,这样我们的开发环境就配置完成了。

3. Hello World 程序

下面介绍在 Samsung Java 开发环境下如何建立并在模拟器上运行一个 Hello World 项目:

一,“文件->新建项目”,在对话框中项目“类别”选择“Mobility”,然后在右侧“项目”中选择“MIDP 应用程序”,点击下一步;
二,将项目名字更改为“HelloWorld”,项目位置可以自行修改,比如我的就是 D:\J2ME,下面两个“设置为主项目”和“创建 Hello MIDlet”保留为默认值,进入下一步;
三,在“选择缺省平台”对话框中,“仿真器平台”选项选择为“SamsungSDK 1.0”,在设备下拉条中,选择目标平台,比如我的手机是 E908,和 E900 是一类,我就选择“SGH-E900”,其它选项保持不变,进入下一步;
四,在更多配置中用户可以自定义更多配置,刚开始使用可以保持不变,点击完成。

这样我们就建立了一个 Samsung Java 的 Hello World 项目,可以查看它的源代码。由于我们在配置时选择了“创建 Hello MIDlet”选项,此时的源程序已经包含了打印一个“Hello World”的功能,我们只需要在菜单中选择“生成->生成主项目”,即可生成 Hello World 项目。

生成项目后,在项目文件夹里可以找到 dist 目录,比如我的就是 D:\J2ME\HelloWorld\dist,这个目录里面包含了可以在 SGH-E908 上安装并运行的 JAVA 程序:HelloWorld.jar 和 HelloWorld.jad。看着很眼熟吧,对,这和普通的 JAVA 游戏形式是一样的,我们可以把这两个文件下载到手机里并安装它。(不同版本安装方法不一样)

SGH-E908 的安装方法是:先将 jar 和 jad 文件下载到手机的 other files 文件夹中,在待机状态下输入 *#9998*5282#,然后选 3,输入密码 235282,选择 jad 文件安装即可。

安装完程序后,我们可以在自己的 Java world 中找到它,运行后,屏幕上会打印出来一行字符:HelloHello, World! 这样,我们的第一个 Samsung Java 程序就成功了。

4. 在三星模拟器(Samsung Emulator)上调试

当然,我们写嵌入式程序不可能一次成功,总会有需要找 BUG 的时候,那么如何进行调试呢?仍然以我们 Hello World 程序为例:

一,先在程序中设置断点,在要设置断点的行前点击边框即可,比如我在 startApp() 函数中的 initialize (); 一行前设置了一个断点;
二,选择“运行->调试主项目”,就可以开始我们的调试了,耐心等待一会儿,会发现弹出了一个 E908 模拟器的窗口,窗口中写着:Select on to launch,因为只有唯一的一个 HelloMIDlet,所以我们直接选择右下角的 Launch,直接点 Launch 是没用的哦,你要点模拟器的手机键盘,作用和按下手机上某个键是一样的。
三,点下 Launch 之后,激活窗口会重新返回到 NetBeans 中, initialize (); 行前有一个右箭头,指代程序已经运行到断点,我们点“运行->继续”,程序就会继续运行,在模拟器中打印出:HelloHello, World!,并在左下显示 Exit 标志,表示程序运行结束。

如果在第三步产生问题,可能是由于在前面介绍中,我们先“生成主项目”造成的调试信息缺失导致的,可修改设置,更直观的方法是重新建立新项目并跳过生成主项目那一步,使用“运行->运行主项目”或者“运行->调试主项目”来生成主项目文件。

5. 结论

三星手机提供的开发环境在一定程度上还是比较易于使用的,这篇文件对三星手机开发环境的建立做了一个简要的介绍,提供了中文入门导引,降低了中文世界初学者学习的难度。

6. 参考文献

[1] Samsung SDK 1.0.0 Documentation

飞信充分表明了中国移动是一个闷骚的弱智

因为平时短信通信量很大,所以最近在尝试中国移动的飞信业务,然后发现了一些很有趣的事情。

1. 不允许下载飞信手机客户端到电脑。

在飞信的官方网站上,手机客户端只能用手机上网下载。(飞信给你发条包含 URL 的消息,你点击下载)

为什么用户不能在电脑上下载了然后自己安装到手机上呢?嘿嘿,就算只有几十K,GPRS 下载也是有钱赚的(0.01元/KB那也是将近一块钱那)!要是大家都在电脑上下了,中国移动不少赚了很多吗?

其实这是典型的中国移动拿用户当弱智耍的例子(当然,这也不是第一次了)。不过大家要明白一个道理,几乎所有 WAP 网站都是可以通过 WEB 访问的,那么移动给的链接自然可以用电脑下载的。拿我的 Samsung E908 来说,移动给的链接是:
http://nav.m161.com.cn/drops/clientdownload.aspx?category=j2me&vendor=sam&model=e908
在这里链接下载下来的是一个 Amigo_sam_e908.jad,和下载 JAVA 游戏时一样,.jad 文件其实只是一个文本文件,用文本编辑器打开后就能发现真正的 JAVA 程序 .jar 文件的下载地址是:
http://nav.m161.com.cn/drops/clientdownload.aspx?category=j2me&vendor=sam&model=e908_jar
在这个链接下载下来的是一个 Amigo_sam_e908.jar 文件,然后只需要把那个 .jad 文件中的 MIDlet-Jar-URL: 后面换成 .jar 文件的文件名 Amigo_sam_e908.jar,然后将两个文件传输到手机里,按照一般安装手机 JAVA 游戏的步骤安装即可。

2. 手机客户端的常用短语。

在用手机客户端发消息时,飞信内置了一些常用短语,下面大家来看看这些“常用”短语是什么:

1> 你好。
2> 有时间么?可以和你聊聊吗?
3> 你好,很高兴可以和你成为朋友。
4> 你多大了?是男生还是女生?
5> 你是用手机聊吗?
6> 为什么不说话?
7> 你的名字好特别,是什么意思呢?
8> 可以给我你的电话号码吗?
9> 回头再聊,我正开车呢?
10> 这么晚了,还不睡?

看完了这几条,我实在不明白它们有哪条能勉强算上“常用”!特别是第 5 条和第 8 条,用飞信自然能看到对方在线状态和对方手机号码,傻啊,还问?

嘿嘿,如果真的有某个人“常用”这几句话,我只能说你很“中国移动”了!