ASCII 和 Tryte 的转换

大家都知道在 iota 中是使用 Trinary (三进位)系统,因此在送资料的时候必须从电脑原本的二进位编码转换为三进位编码。这本身没有什麽问题,说不定反而要说是 IOTA 的特色之一。当初几个 IOTA 理想主义色彩浓厚的元素,三进位就是其中之一。但是呢本人最近在开发 IOTA 软体的时候发现被大大的 gank 了,所以特别写了这篇文章来解释一下。

其实可以快速的总结说我为什麽觉得我被 entangled 阴了一波。在 IOTA 的官方函式库「们」(对的不只有 entangled 这个 C 语言的函式库),可以找到像下面这边列出的 tryte 转 ascii、ascii 转 tryte 的函式。

iota.js 转换函式连结
entangled 转换函式连结
当初的我很天真地以为这只是做型态转换,所以我预计会有下面的转换结果

转换前的 ascii 字串 ABCDEFG
转换后的 tryte 编码 ABCDEFG
但实际上转换的结果会是

转换前的 ascii 字串 ABCDEFG
转换后的 tryte 编码 KBLBMBNBOBPBQB
好的我知道有些人会觉得我很蠢,转换当然会变成不一样的东西啊,还觉得转换后会是一模一样的我是不是智障。但是但是!! 我必须解释这是有原因的。因为我考虑到我的转换前的 ascii 就已经是以 IOTA 的 三进位方式进行编码,理应不需要再进行转换。但天知道 IOTA 官方函式库给的转换函式其实做的是把输入的字串不管怎样都把它当作一个 256 范围内的数字,转换成两个三进位的 tryte。换言之,我把编码转换函式 (ascii_to_trytes()和 trytes_to_ascii()) 当作是变数型态转换函式才会造成这个笨问题。

那麽究竟是如何转换的呢?其实公式十分的简单就只是把这个最大值为 256 的数字转成以两位数的 27 进位数表达。以字元 A 当作例子,A 根据 ascii table 若以数字表达是 65,首先 27 进位的个位数(最右边的数)是 65 / 27 的商 = 2,十位数(右边数来第2位数)是 65 / 27 的馀数 = 11。

所以到这边我们知道,65 可以表达成: [11, 2]

根据 tryte table 的顺序

TRYTE_ALPHABET = 9ABCDEFGHIJKLMNOPQRSTUVWXYZ
11 是 K,2 是 B。因此 A (ascii) = KB (trytes)

因为太快打完了,所以补一些前阵子处理这玩意而遇到的心得。

如果大家有注意到的话 ascii 的定义其实范围只有到 127,换句话说,char 的最高位 (sign bit) 完全不会用到,那这部份在 C 语言的函式 entangled 中其实会产生些问题 (对的我就是被这问题雷过不然怎麽知道有问题)。在 entangled 中若是 core API 收到 unicode 的输入,会造成整个软体 SEGV,争个爆炸,其根本原因就是因为 unicode 编码有时候会用到 sign bit,那这样我就不能把这个 char 变数所储存的数字当作 ascii 来解码,因为 ascii 根本没有定义到这个数字。

目前我自己想到的解决方法是把前 4 bit 转成一个 tryte,后 4 bit 转成一个 tryte,这样就可以轻鬆迴避掉 sign bit 的问题, core api 对于各种编码也会直接相容。但是有个缺点就是跟现在的编码转换方式不同轨。但就看之后要如何解决搂。

觉得不错的话打个赏: 0x4c0afDCcBD27cD65B2e77e4788A5DE8aa0fE03e5(乙太)
github: https://github.com/HowJMay

专栏作者:杨皓

个人简介:我共发表了 2 篇文章,总计被阅读了1,148 次,共获得了 17 个赞。

作者邮箱 作者主页 Ta的文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注