Encode your IP address as Haiku

2015-02-26

最近几天我写了一个好玩的库: pyhipku. 主要的用法就是俳句和 IP 地址之间的转换。 它其实是 hipku 的一个 Python 的实现吧,貌似最初是在 Hacker News 上看到的。

对于俳句,我能想起的是第一次见到的一首俳句:

不要打啊, 苍蝇搓他的手, 搓他的脚呢!

还能想起的有 《窗边的小豆豆》 中的一句:

白雪融化了, 村子里到处都是, 快乐的孩子。

下面我来说说这个库。

使用 pip (pip install pyhipku) 安装好了以后,使用起来很简单。我举个例子:

>>> from pyhipku import encode
>>> encode('127.0.0.1')
'The hungry white ape\naches in the ancient canyon.\nAutumn colors crunch.\n'

>>> from pyhipku import decode
>>> decode('The hungry white ape\naches in the ancient canyon.\nAutumn colors crunch.\n')
'127.0.0.1'

然后说说它的实现。原来的作者已经写了一篇博文来说明,我试着也再来解释一回。

我以上面的例子 IPv4 的地址 127.0.0.1 来解释一下这转换是怎么回事。

按照我的理解,这个过程用一句话来说就是词语填空。我们在 pyhipku/encode.py 中的 get_key 函数中能够找到这样的一个列表

key = [animal_adjectives, animal_colors, animal_nouns, animal_verbs,
       nature_adjectives, nature_nouns, plant_nouns, plant_verbs]

如果你还是没有感觉的话,那我换一个更加接近成品的再一次给你看看 (来自 pyhipku/encode.py 中的 get_schema 函数):

schema = ['The', octet, octet, octet, new_line, octet, 'in the',
          octet, octet, period, new_line, octet, octet, period,
          new_line]

这里的 octet 表示是一个 word slot,也就是待会要填空的地方,一共有 8 处,每处的词语的类型就是上面的 key 一一对应的,而词语的来源是自带的词典,也就是 pyhipku/dictionary.py

抛开词典的构建,此时我们的问题应该是清晰的:如果把一个 IP 地址转成一个长度为 8,元素是数字的列表 [Num, Num, Num, Num, Num, Num, Num, Num]。这样,每个数字对应词典中的一个词语, 填空一下,一首 haiku 就好了呀。

我就揭晓谜底吧: 这 8 个数实际上是两两一对的,生成的方式是 IP 地址中每个数字除以 16 得到的商和余数。以 127.0.0.1 为例,127 / 16 = 7 余 15,剩下的三个数字同理, 得到的列表为 [7, 15, 0, 0, 0, 0, 1]。按照上面的 schema 去 pyhipku/dictionary.py 中找到对应的单词一一填空,不出意外就是我们的结果了。

好奇的你可能要问了,为什么要除以 16 而不是别的数字呢。是这样的: IPv4 地址的数量为 2 的 32 次方, 我们既然留了 8 个空,计算一下就是 2 的 4 次方也就是 16。

让我们重新捋一下思路:

  1. 将 IPv4 地址分成 4 个数
  2. 分别计算每个数除以 16 后的商和余数,生成一个新的列表
  3. 根据列表中的数字,找到对应词典中的单词
  4. 单词填空

IPv6 以及 decode 的过程不再赘述,上面的原理搞清了应该不是问题。

Til next time,

lord63 at 21:02