狂奔 lion

自强不息

关于文本协议中二进制到文本的转码

偶然间注意到一个困扰了我很久的问题,那就是如果我不通过Socket而通过应用层的某种基于文本的协议,比如SOAP进行通信的话,
如何传递二进制的数据呢?现在SOA,Web Service等很火,应该会遇到这种问题吧?

现在已知的方法可以通过Base64进行编码,其原理和方法见:
http://baike.baidu.com/view/469071.htm

这种方法采用了字节中的6位进行文本转换,并且在其他论坛上也看到了帖子说淘宝的搜索也采用了这种编码方式进行处理。
但是采用了5位进行转换。并且大胆地给出了5位转码的算法,见:
http://www.javaeye.com/topic/286240

不过这种5位的转换会产生更多多余的字节,6位的转码充分利用了现今的可读文本,可是5位却没有,因为5和8的最小公倍数是40,
所以当每转换40位即5个字节的二进制数据需要8个字节来表示,这样就多产生3个字节,浪费的效率是3/5, 而6位转码浪费的效率是
1/3。而且随着字节增多,转化效率也在下降。可见采用5位转码是一种既浪费空间,又浪费效率的解决方案。在不增加url长度的情况下充分提高效率,6位编码是最佳的。如果可以任意的饿牺牲url长度,
可以把0-9全部拿出来当做标记位,0-9不会单独出现,这样一共有10*26 + 26 = 286 种可能还不包括小写字母,
此外还有=,+,-什么的至少256可以编码8位的字节了,这样处理效率就提高了。

现在把问题优化一下,人类可读无歧义的文本码有0-9,A-Z,a-z共62个
设取出x个作为标志位则(62-x) * x + (62 - x) >= 256
解这个二元一次方程得到:
3.366<=X<=57.634
考虑到编码的文本长度,取x的最小值,即 4
最优解:
用0, 1, 2, 3做为标志位
4-9,A-Z, a-z参与编码并与标志位配合实现8位字节的文本化
可以看到这种方法的转码效率会比较高,但是空间冗余大。

此外其实可用的文本不知62个,包括感叹号等用上后补足64 = 2^6
它的高位是 00
那么只要再找到三个文本符保存其他三个高位01 10 11就可以了
这样的转码空间可以更小一些。


想法还很不成熟,欢迎大家批评

 @2008 杨一. 版权所有. 保留所有权利

posted on 2008-12-04 15:56 杨一 阅读(1592) 评论(2)  编辑  收藏 所属分类: Other Tech

评论

# re: 关于文本协议中二进制到文本的转码 2008-12-04 17:05 徐尧

我上午看那个帖子了,这么敲也看到您的  回复  更多评论   

# re: 关于文本协议中二进制到文本的转码 2008-12-04 19:11 magicgod

base64 + 压缩流 就行了,也不会浪费,就是多一点cpu就可以了。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

导航

公告

本人在blogjava上发表的文章及随笔除特别声明外均为原创或翻译,作品受知识产权法保护并被授权遵从 知识分享协议:署名-非商业性使用-相同方式共享 欢迎转载,请在转载时注明作者姓名(杨一)及出处(www.blogjava.net/yangyi)
/////////////////////////////////////////
我的访问者

常用链接

留言簿(5)

随笔分类(55)

随笔档案(55)

相册

Java

其他技术

生活

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

自强不息


用心 - 珍惜时间,勇于创造