偷梁换柱终级版:用最少的步骤在Bambook上阅读原生EPUB文件

本文内容已过时,云梯0.98b版本开始,直接支持向Bambook中传送原生EPUB格式文件,不再需要用本文的方法去折腾了。

我不得不说,伸手党是促进社会劳动生产率不断进步的源泉。

前一篇“偷梁换柱”写完以后放到某论坛上,很快就有伸手党跳出来说,还是太复杂了,能不能把所有的东西写成一个软件一运行就好了。我有点生气的回复他,可以,不过我没有兴趣和精力做这个。不过过了一会儿转念想想,其实这事儿吧,也真没有那么难。花了几十分钟,搞定了这个“终级版”的“偷梁换柱”,希望后面我不要再想出什么更好的办法来,不然我真不知道该用什么词来做文章的标题了。

目标:把calibre中管理的自有EPUB格式的电子书传到Bambook中原生阅读,不做格式转换。

适用人群:Bambook用户,有用Bambook阅读原生EPUB格式电子书的需求,基本会用calibre管理电子书,会用记事本修改文本文件,能知道自己所用电脑的IP地址。

系统与环境要求:安装过云梯和calibre的Windows操作系统,Bambook通过USB连接,可以通过该Windows系统代理上网。或者安装过calibre的Windows操作系统,Bambook通过Wi-Fi上网。(其它操作系统的用户,也可以参照执行,完全是可行的,只是本文中不做针对性说明,如果有问题,可以留言询问)

1. 从本站下载工具包:

本地下载:工具包

把下载的文件解压缩到硬盘上,比如C:\,得到fakedns.py和fakehttp.py。还有两个批处理1.bat和2.bat。

2. 运行脚本文件

如果calibre是安装在默认的C:\Program Files\Calibre2中,直接双击运行1.bat和2.bat即可。运行成功的话,会在屏幕上保留两个命令提示符的窗口,里面会显示本机IP,后面还会不断显示一些调试信息。

如果calibre不是装在默认路径下:用记事本打开1.bat和2.bat,修改里面的calibre安装路径后再运行。

两个脚本运行后,都会在屏幕上打出本机的IP地址。如果与实际情况不符,请把命令提示符窗口关掉,用记事本修改脚本文件中的IP = “”行,写成IP = “192.168.0.1”这样的形式,强行指定本机IP,保存后重新运行这两个脚本。

3. 修改电脑或Bambook的DNS设置,指向我们的假DNS服务器

为了确保成功,在这里先把Bambook断开USB或无线连接,并重启一次。

如果用电脑USB共享给Bambook上网,就修改电脑上网网卡上的DNS设置,改成本机的IP地址(在第2步的脚本运行过程中会打印在屏幕上,照抄就行了)。改完后,把Bambook用USB连接到电脑上。

如果Bambook自己Wi-Fi无线上网,就修改Bambook上网络配置中的DNS设置,设成电脑的IP地址。改完后,关闭并重新开启Bambook的无线连接。

在修改前,请记下原来的值(也有可能原来选的是“自动获取”),以便在用完后把它恢复原样。

4. 启动calibre服务器

运行calibre,主界面下“连接/共享”->“启动连接服务”,这时calibre应该会在8080端口上启动http服务器,提供 OPDS服务,可以通过访问http://127.0.0.1:8080/opds来验证。(这是在默认配置的情况下,如果有改变过配置,需修改fakehttp.py中的URL)

搞定了!

在Bambook上按“找书”->1.访问云中书城->*.切换到第三方书库,或者最新固件上书架主菜单中选3.更多书城,就可以看到被我们 “篡改”过的第三方书城列表,选择其中的5. calibre,就可以尽情的享用你本地calibre书库中的EPUB图书了。

从calibre中获取到心仪的EPUB图书后,记得把第3步中改过的DNS值恢复原样,免得影响正常上网。

偷梁换柱升级版:用calibre为Bambook提供EPUB书库

本文内容已过时,云梯0.98b版本开始,直接支持向Bambook中传送原生EPUB格式文件,不再需要用本文的方法去折腾了。

上一篇Blog中提供了在Bambook上阅读EPUB书籍一个折腾方法,但那个方法显然很tricky,依赖环境多,成功率低,要传多本图书更复杂。这次又折腾出个改进版的方法,虽然也比较复杂,但成功率比以前高多了,而且也更直观好用,分享给大家。原理:用calibre提供的OPDS服务,把这个服务器添加到Bambook的第三方书城列表中。用到的软件和技术跟以前差不多:calibre,DNS劫持,nginx反向代理与rewrite。

前提条件:有一台正常上网的电脑A,Bambook用无线上网并在上网过程中可以访问到电脑A。或者,有两台电脑(可以是虚拟机)A和B,A用来做服务器,B上安装云梯给Bambook共享网络,AB之间也可以相互访问。

1. 在电脑A上下载安装nginx for Windows

http://nginx.org/download/nginx-1.1.15.zip

下载后,解压缩到C:\,得到C:\nginx-1.1.15

2. 配置nginx,实现Web服务和反向代理

用记事本打开C:\nginx-1.1.15\conf\nginx.conf,把它修改成以下内容,其中的192.168.8.102为A电脑的IP地址,请自行替换(下同)

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server {
        listen          80;
        server_name     opds.gk.sdo.com;
        location / {
            proxy_pass              http://$http_host$request_uri;
            proxy_redirect          off;
            proxy_set_header Host   $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            rewrite ^.*Default.aspx.*$ http://192.168.8.102:81/1.xml redirect;    
        }
    }
    server {
        listen       81;
        location / {
            root   html;
            index  index.html index.htm;
        }
    }           
    sendfile        on;
    keepalive_timeout  65;
}

3. 在C:\nginx-1.1.15\html中创建1.xml文件,内容如下,使用UTF-8编码(如果用记事本,那就需要用“另存为”对话框,把下面的“编码”由ANSI改为UTF-8)。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:opds="http://opds-spec.org/2010/catalog" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">锦书OPDS源列表</title>
  <id>uuid:ea8a979d-7e28-4bf7-8d11-31aafb2ac66a;id=60</id>
  <updated>2012-03-11T15:49:25Z</updated>
  <link rel="search" type="application/atom+xml" href="http://opds.gk.sdo.com/Search.aspx?ST=ALL&amp;PageIndex=1&amp;k={searchTerms}&amp;{bbtk}" />
  <entry>
    <id>JiuYue</id>
    <title type="text">新华书店九月网</title>
    <updated>2012-03-11T15:49:25Z</updated>
    <link rel="alternate" type="application/atom+xml" href="http://opds.9yue.com/category.atom?site=BamBook" />
    <content type="text">新华书店九月网</content>
  </entry>
  <entry>
    <id>http://m.gutenberg.org/ebooks/?format=opds</id>
    <title type="text">古腾堡计划</title>
    <updated>2012-03-11T15:49:25Z</updated>
    <link rel="alternate" type="application/atom+xml" href="http://m.gutenberg.org/ebooks/?format=opds" />
    <content type="text">英文电子书</content>
  </entry>
  <entry>
    <id>http://www.feedbooks.com/site/free_books.atom</id>
    <title type="text">feedbooks</title>
    <updated>2012-03-11T15:49:25Z</updated>
    <link rel="alternate" type="application/atom+xml" href="http://www.feedbooks.com/site/free_books.atom" />
    <content type="text">在线阅读网线图书</content>
  </entry>
  <entry>
    <id>http://www.feedbooks.com/site/free_books.atom</id>
    <title type="text">calibre</title>
    <updated>2012-03-11T15:49:25Z</updated>
    <link rel="alternate" type="application/atom+xml" href="http://192.168.8.102:8080/opds" />
    <content type="text">calibre</content>
  </entry>
</feed>

4. 启动nginx

双击运行C:\nginx-1.1.15\nginx.exe,用任务管理查看nginx进程,确认启动成功。如果用netstat -na检查,应该在80和81端口上有LISTENING。如果访问http://192.168.8.102:81/1.xml,可以看到上面我们建立的1.xml文件。

5. 安装Python 2.7

http://www.python.org/getit下载Python Windows Installer并安装到C:\Python27目录。

6. 写Python脚本,建假DNS。把下面的内容存为C:\FakeDNS.py。同样,其中的192.168.8.102为A电脑的IP地址,请自行替换

#! /usr/bin/env python
# This code comes from
# http://code.activestate.com/recipes/491264-mini-fake-dns-server/
# with some modifications
import socket

class DNSQuery:
  def __init__(self, data):
    self.data=data
    self.domain=''
    tipo = (ord(data[2]) >> 3) & 15
    if tipo == 0:
      ini=12
      lon=ord(data[ini])
      while lon != 0:
        self.domain+=data[ini+1:ini+lon+1]+'.'
        ini+=lon+1
        lon=ord(data[ini])

  def respuesta(self, ip):
    packet=''
    if self.domain:
      packet+=self.data[:2] + "\x81\x80"
      packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00'
      packet+=self.data[12:]
      packet+='\xc0\x0c'
      packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04'
      packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.')))
    return packet

if __name__ == '__main__':
  udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  udps.bind(('',53))
  try:
    while 1:
      data, addr = udps.recvfrom(1024)
      p = DNSQuery(data)
      if p.domain == 'opds.gk.sdo.com.':
        ip = '192.168.8.102'
      else:
        ip = socket.gethostbyname(p.domain)
      udps.sendto(p.respuesta(ip), addr)
      print p.domain + "=>" + ip
  except KeyboardInterrupt:
    udps.close()

7. 启动假DNS

在命行提示符中运行:

C:\Python27\python.exe C:\FakeDNS.py

启动后应该会停在那里,有请求时会打印出解析结果。可以再开一个窗口用nslookup确认它的工作状态:对于除了opds.gk.sdo.com以外的域名,都解析为正常IP地址;对于opds.gk.sdo.com.,解析为电脑A的IP地址。

8. Bambook设置

设置Bambook的无线连接,其中DNS服务器地址设为假DNS所在电脑A的IP地址。

如果采用两台电脑的方案,就把电脑B的网卡配置中的DNS指向电脑A的IP地址。然后连接Bambook与电脑B,让Bambook通过电脑B上网。

9. 启动calibre服务器

运行calibre,主界面下“连接/共享”->“启动连接服务”,这时calibre应该会在8080端口上启动http服务器,提供OPDS服务,可以通过访问http://127.0.0.1:8080/opds来验证。(这是在默认配置的情况下,如果有改变过配置,上面的1.xml做相应改动即可)

一切就绪,在Bambook上按“找书”->1.访问云中书城->*.切换到第三方书库,或者最新固件上书架主菜单中选3.更多书城,就可以看到被我们“篡改”过的第三方书城列表,选择其中的5. calibre,就可以尽情的享用你本地calibre书库中的EPUB图书了。

注意:这个方法只支持Bambook从calibre书库中下载EPUB格式的图书。如果书城列表获取不正常,可能是DNS缓存的问题,重启Bambook后再试一次。

calibre除了自带的OPDS连接服务,也可以用calibre2opds这个软件来提供更美好的OPDS服务器,以后另文介绍calibre2opds。

偷梁换柱:在Bambook中阅读自有epub电子书

本文内容已过时,云梯0.98b版本开始,直接支持向Bambook中传送原生EPUB格式文件,不再需要用本文的方法去折腾了。

先写一句话指南,免得浪费有很强动手能力的技术青年们的时间:通过假DNS把res.gk.sdo.com劫持到本地,对于非.epub文件下载请求,反向代理到真正的res.gk.sdo.com上;对于.epub文件请求,你想把什么书传到Bambook上,就在本地把这个.epub通过HTTP返回出去吧。在Linux上,可以用nginx做Web服务器、反向代理和Rewrite,用dnsmasq或我下面提供的Python脚本做假DNS。

我也算是Bambook的老用户了,从它上市第一天起就开始使用,当年写的体验心得算是很给面子、非常委婉指出了它的一些致命缺点(对于我自己而言的),其中最重要的两条是:只有Windows-Only的客户端程序和不支持除了它自有的SNB以外的任何电子书格式。第一个问题,我通过盛大后来开放的SDK给calibre写了一些插件基本解决了(支持Windows/Linux/Mac OS X,使用方法在这里),第二个问题盛大后来自己开始支持PDF格式了,算是解决了一半,但如果再能支持一下epub格式就美好了。

在盛大去年发布的最后一版支持第三方书库(Feedbooks和古登堡计划)的固件中,某些人敏锐的注意到,从第三方书库下载的电子书明显有比SNB格式更丰富的排版,而且下载页面上也以很小的字体提示了说,这是epub格式的。由此可知,Bambook的固件已经可以支持epub的直读,剩下的问题就是怎么把epub书放进去了。

尝试过一些方法,比如把epub文件跟pdf文件一样,用SNB格式包裹起来再通过SDK传到Bambook上,总之都是失败。最后实在没有办法,决定用Wireshark抓包分析Bambook从Feedbooks下载图书的交互过程,从中做点坏事。

分析过程其实一点也不复杂,会用Wireshark的人应该都能搞定。我选了对Feedbooks的交互过程进行分析,分析的结果是,Bambook从第三方书库下载图书时,仍然会与盛大的服务器交互,并且最终是从盛大的服务器的URL上下载实际的文件(最新的分析结果是:可能从盛大的服务器,也可能从原始feedbooks的服务器,取决于盛大的服务器有没有缓存过这个文件。该分析未完全确定),所以简单的劫持对Feedbooks.com的访问是没用的。反复尝试,下面描述的方法是可行的(但很可能不是最简单的,懒得再深入研究了)。为照顾大部分Windows用户,下面以Windows环境来介绍。Linux用户请参考本文第一段自己折腾,应该更简单一些。

前提条件:有一台正常上网的电脑A,Bambook用无线上网并在上网过程中可以访问到电脑A。或者,有两台电脑(可以是虚拟机)A和B,A用来做服务器,B上安装云梯给Bambook共享网络,AB之间也可以相互访问。

1. 在电脑A上下载安装nginx for Windows

http://nginx.org/download/nginx-1.1.15.zip

下载后,解压缩到C:\,得到C:\nginx-1.1.15

2. 配置nginx,实现Web服务和反向代理

用记事本打开C:\nginx-1.1.15\conf\nginx.conf,把它修改成以下内容,其中的192.168.8.102为A电脑的IP地址,请自行替换

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server {
        listen          80;
        server_name     res.gk.sdo.com;
        location / {
            proxy_pass        http://res.gk.cdn.sdo.com/;
            proxy_redirect    off;
            proxy_set_header  Host            $host;
            proxy_set_header  X-Real-IP       $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            rewrite ^.*/.*\.epub$ http://192.168.8.102:81/1.epub redirect;
        }
    }
    server {
        listen       81;
        location / {
            root   html;
            index  index.html index.htm;
        }
    }           
    sendfile        on;
    keepalive_timeout  65;
}

3. 启动nginx

双击运行C:\nginx-1.1.15\nginx.exe,用任务管理查看nginx进程,确认启动成功。如果用netstat -na检查,应该在80和81端口上有LISTENING。

4. 安装Python 2.7

http://www.python.org/getit下载Python Windows Installer并安装到C:\Python27目录。

5. 写Python脚本,建假DNS。把下面的内容存为C:\FakeDNS.py。同样,其中的192.168.8.102为A电脑的IP地址,请自行替换

#! /usr/bin/env python
# This code comes from
# http://code.activestate.com/recipes/491264-mini-fake-dns-server/
# with some modifications
import socket

class DNSQuery:
  def __init__(self, data):
    self.data=data
    self.domain=''
    tipo = (ord(data[2]) >> 3) & 15
    if tipo == 0:
      ini=12
      lon=ord(data[ini])
      while lon != 0:
        self.domain+=data[ini+1:ini+lon+1]+'.'
        ini+=lon+1
        lon=ord(data[ini])

  def respuesta(self, ip):
    packet=''
    if self.domain:
      packet+=self.data[:2] + "\x81\x80"
      packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00'
      packet+=self.data[12:]
      packet+='\xc0\x0c'
      packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04'
      packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.')))
    return packet

if __name__ == '__main__':
  udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  udps.bind(('',53))
  try:
    while 1:
      data, addr = udps.recvfrom(1024)
      p = DNSQuery(data)
      if p.domain == 'res.gk.sdo.com.':
        ip = '192.168.8.102'
      else:
        ip = socket.gethostbyname(p.domain)
      udps.sendto(p.respuesta(ip), addr)
      print p.domain + "=>" + ip
  except KeyboardInterrupt:
    udps.close()

6. 启动假DNS

在命行提示符中运行:

C:\Python27\python.exe C:\FakeDNS.py

启动后应该会停在那里,有请求时会打印出解析结果。可以再开一个窗口用nslookup确认它的工作状态:对于除了res.gk.sdo.com以外的域名,都解析为正常IP地址;对于res.gk.sdo.com,解析为电脑A的IP地址。

7. Bambook设置

设置Bambook的无线连接,其中DNS服务器地址设为假DNS所在电脑A的IP地址。

如果采用两台电脑的方案,就把电脑B的网卡配置中的DNS指向电脑A的IP地址。然后连接Bambook与电脑B,让Bambook通过电脑B上网。

8. 把打算要传到Bambook上的EPUB电子书放到C:\nginx-1.1.15\html中,命名为1.epub。

9. Bambook上选择Feedbooks.com上任意一本Public Domain的图书,下载阅读。

找书->1.访问云中书城->*.切换到第三方书库->3.feedbooks->3.Public Domain Books->2.Recently Added->任选一本以前没有下载过的书->1. 免费试读本书。

搞定!返回书架后就可以看到你自己的epub电子书已经放进了Bambook,可以尽情的阅读了。

重要更新:如果有时候发现下载下来的还是第三方书库的书,不是被自己替换过的。也许是因为盛大服务器上还没缓存过这本书,所以我们劫持盛大服务器就没用了。暂时的解决方案是换一本排在比较前面的书(这些书有缓存的可能性比较大),或者到书架上把刚刚下载的书删掉,重新再去下同一本,那时这书可能已经被缓存在盛大的服务器上了,这样我们的劫持就有效了。

其它说明:

1. 不能只用一台电脑或不用Bambook无线上网搞定的原因是:Bambook USB共享上网中的NAT服务中带了DNS服务,会与我们的假DNS抢53端口。

2. 制作在Bambook上阅读的EPUB电子书时,内部单个文件不要太大,不然翻页速度会让你抓狂。如果用calibre转换格式,可以在EPUB格式输出插件的设置中设定页面文件分割大小。

3. 虽然我们偷换掉了EPUB文件,但似乎Bambook还是认为我们是下载了我们所选的书籍并会记住这个状态,再次选择同一本书时,就不会再下载了。所以每次传书都得从Feedbooks中找一本以前没有用过书才行。

4. 这个方法只在Bambook SD928经典白色版上验证有效,未在全键盘版上验证过。且盛大只要服务器那里稍微动动手脚就可以让它失效,所以不保证有效期。并欢迎大家寻求更简单完美的解决方案。

5. 我曾经有过另一个在Bambook上阅读富格式书籍的想法,就是把HTML(或EPUB、MOBI等,反正本质都是HTML)页面封装成Bambook的Widget,用JavaScript在HTML中实现阅读器应该有的功能。现在是有SDK可以把Widget传入Bambook的,所以用这个方法完全可以写软件(或者给calibre写个插件,非常简单)自动完成常见的电子书格式转成Widget和传入Bambook的全过程。这个方法我已经做过POC,是完全可行的。但我没有能力用Java Script写出一个让我自己满意的阅读程序,所以最终放弃了。

6. 本文描述的所有内容仅供技术宅折腾和探讨,不愿折腾的人、Kindle或其它功能强大的阅读器拥护者请勿喷。谢谢。

五周年-我的独立博客

五年前的今天,因为“自由软件综合症”发作,在朋友给的fx.jiuzhe.com域名上用Emacs+Muse创建了我的独立博客,通过几次改进,最后就形成了今天大家所看到的FreeMindWorld.com。

为了折腾,我一直在享受和忍受着Emacs+Muse所建的Blog的各种方便和不方便之处。这次,终于是痛定思痛,放弃了个性,把整个Blog系统切换到了WordPress上面,不过还是花了不少的时间去定制WordPress,让整个网站的风格与原来大体上保持一致,所有页面的链接也尽量保持跟原来的一样,免得造成太多的死链。

这次迁移半自动半手动的迁移了原来FreeMindWorld.com上和我以前CSDN博客和Live Space上的文章169篇和465条评论,非常艰辛。现在我这个博客上包含了以下的文章:

  • 2002年2月至2003年7月在CSDN文档中心发表的文章。
  • 2004年6月至2007年2月在CSDN博客和Live Space上写的文章。
  • 2007年2月以后FreeMindWorld.com上的文章。

所以,如果把当年给CSDN文档中心写文章也算上的话,这次也可以算是个10周年纪念。在转移这些文章时,不可避免的把它们都回顾了一遍,很有感触,人生的十年、互联网的十年,变化都很大。

五年,见证了微博从兴起到到兴旺。十年,见证了博客从兴起到衰落。谁会知道下一个五年又会发生什么。

上个月关停了我的另一台运行了5年的ASP虚拟主机,上面原本运行着一些从1999年就开始做的网站,但是这些网站早就没有了任何的访问量,只有发Spam的机器人坚持不懈的在留言板上活跃着。那台主机上还存放着的我早年做的一些静态个人主页,这次也一并迁移了过来,放在这里怀个旧吧。点击图片就可以访问相关的网页。三个版本的个人主页除了长的不一样,内容几乎是一样的。那年头,做个人主页就是做页面设计,内容有什么并不重要,现在可大不一样了。

个人主页第一版

个人主页第一版 1999年2月19日-1999年5月

个人主页第二版

个人主页第二版 1999年5月-2000年5月

个人主页第三版

个人主页第三版 2000年5月-?(不记得什么时候它就不存在了)

Rubik’s 360解法

去年去美国的时候给自己买了个玩具,LEGO的Mindstorm NXT 2.0机器人,可惜一年半时间下来发现自己的设计能力有点玩不转这种高科技的玩具。今年去美国时无意间在超市看到有正版的Rubik’s魔方卖,比国内便宜,没有买魔方,但它倒让我想起了另一个玩具--Rubik’s 360,最终在Amazon上找到了它,买了下来。Rubik’s 360在国内也有山寨版的卖,价格不到正版的1/10,品质如何不知道,不过正版的做工倒是确实很让我失望……

Rubik’s 360是魔方之父Ernő Rubik在发明魔方25年后发布的一个新玩具,它由三个透明的同心圆球组成,球与球之间以两根45度角相交的轴连接,最里面的球上有一个圆孔,中间的球上有两个圆孔,并且两个球上都各安装有一个重锤,在正常情况下保持圆孔朝上。玩具的目标就是把最里面的球中的六颗彩色珠子,通过两层球上的圆孔,移动到外层球表面上对应颜色的凸起中。在球体上还安装有两个控制钮,可以用来打开或关闭外层球上凸起的大门,这样就可以在把一个珠子移动到凸起中后,把门关上,防止珠子从里面再掉出来。

玩具的关键点在于:由于重锤的存在,圆孔总是朝上,所以就很难让珠子从圆孔中”掉出来“,到达外层球体。反倒是好不容易把珠子移到外层后,只要一不小心,就会重新从小孔中掉回内层球体中。

这个玩具有个很简单的解法,Shake-Shake,也就是把整个球乱摇,总有一定的可能性可以把珠子从内层球体摇到外面来。只不过这个解法就是完全靠运气了,就算你摇上20分钟,也没人能保证能不能成功摇出一个来。

其实Rubik’s 360跟Rubik’s Magic(魔板)很相似,只有一个步骤很关键,一旦学会了这个步骤,这个玩具就被破解了,也就不好玩了。这跟魔方很不一样,魔方的变化情况要多得多,对于每一个状态,都可以有很多不同解法。

所以,如果你对Rubik’s 360有兴趣,在往下看本文前,最好先自己玩一玩。下面的内容会把玩具的魅力破坏一大半,本文是为想立即知道这个玩具解法的人准备的。好,现在你已经被警告过了。

Rubik's Magic和Rubik's 360

Rubik's Magic和Rubik's 360

首先定义一些名词。从内到外三个球体分别叫作内球、中球和外球。外球上的拼接缝把外球分为两个半球,一个半球上是蓝白绿三色凸起,叫BUUG,另一个半球上是红橙黄三色凸起,叫ROY。我把两个控制旋钮处在一上一下的位置、它们连成的直线垂直于地面时的状态称为是竖着的,当这条直接平行于地面时,称为是横着的。

不难发现,当玩具是横着的时候,内球和中球的重锤会同时指向地心方向。当玩具是竖着的时候,内球的重锤通常会指向侧下方而中球的重锤会指向水平方向。

第一步:如果把球横过来,并让其中一个旋钮正朝向自己,慢慢把球朝外转动90度,就可以把球竖起来(朝向自己的旋钮朝上了)。请注意观察这个过程:内球和中球的重锤会分别朝两个方向离开地心方向的位置。

看清楚这一点后,重新再操作一次:先把球横过来,然后慢慢把它竖起来,到快接近竖直的时候(朝向自己的旋钮接近朝上,微微偏向自己一点,不完全朝上的原因是那时中球可能会带着内球开始乱转了),先静止一下,然后继续沿相同的方向流畅、稳定并迅速的转动180度。在这个过程中,需要确保两个重锤各自沿之前的运动方向继续向两边分离。当完成这次转动后,你就可以看到,内球的孔已经不再是朝上了,而是朝向了水平方向,与中球的重锤到达一样的位置。至此,最关键的一步就完成了。

第二步:适当转动Rubik’s 360,就可以让内球的孔基本朝下,这时就可以轻松的把内球中的某个珠子赶到内球与中球的夹层中了。到了这里,你需要牢记的一点是不可以再把Rubik’s 360完全横过来了,除非你希望珠子重新掉回内球去。

第三步:保持一个适当的倾斜角度,轻轻晃动Rubik’s 360,就可以让内球和中球夹层中珠子在夹层里运动起来,并最终卡到中球与外球相连的孔中。这个过程中,如果你的角度选择不合适,或者珠子在夹层中运动速度过快,或者你不小心把整个玩具完全横过来了,都会导致珠子掉回内球,前功尽弃。

第四步:当珠子卡到外球与中球之间后,剩下的工作就比较简单了,让你希望珠子进入的凸起朝向斜上方(具体角度请自行摸索,不难,但讲不清),然后用旋钮开门,把珠子晃进凸起,关门。

还遗留最后一个问题,就是有关颜色的。蓝白绿三色的珠子只应该进入BUUG半球,红橙黄三色珠子则只应该进入ROY半球,不然最后它们就不能回到颜色与它们相符的凸起中。做完第二步后,基本上就决定了你正在操作的珠子会进入BUUG半球还是ROY半球,如果进错了半球,基本上就没有搞头了,只好它让掉回内球,重新操作。在我的Rubik’s 360上,做第三步时,珠子总是会倾向于往某一个方向运动(虽然我总觉得应该两个方向的概率是一样的),在这种情况下就很容易预测从内球中掉出来的珠子会进入到哪一个半球中,所以在把珠子从内球赶到中球夹层时,可以有意识的选择合适的颜色的珠子。或者当剩下的珠子只有某个半球的颜色时,就应该在第一步时就选择正确的半球朝向自己,才能保证后面珠子可以进入正确半球。这个也请大家自己摸索一下吧,反正只有两种可能性,规律很好找。

好吧,我想我已经尽力用文字去解说整个过程了,不知道能不能对不会玩的朋友有所帮助。大家也可以参考以下资料(包括一些视频)来研究这个玩具。中国大陆用户访问会有些困难,但我也没有办法……

Rubik’s官方指南,有视频解说和原理动画,个人认为完全看不懂:http://www.rubiks.com/solving-center/solve_rubiks_puzzles.php

一个第三方的博客介绍技巧的,有说明和视频,跟我的方法比较接近,可以参考一下:http://rubix360.blogspot.com