偶然間注意到一個(gè)困擾了我很久的問(wèn)題,那就是如果我不通過(guò)Socket而通過(guò)應(yīng)用層的某種基于文本的協(xié)議,比如SOAP進(jìn)行通信的話(huà),
如何傳遞二進(jìn)制的數(shù)據(jù)呢?現(xiàn)在SOA,Web Service等很火,應(yīng)該會(huì)遇到這種問(wèn)題吧?
現(xiàn)在已知的方法可以通過(guò)Base64進(jìn)行編碼,其原理和方法見(jiàn):
http://baike.baidu.com/view/469071.htm
這種方法采用了字節(jié)中的6位進(jìn)行文本轉(zhuǎn)換,并且在其他論壇上也看到了帖子說(shuō)淘寶的搜索也采用了這種編碼方式進(jìn)行處理。
但是采用了5位進(jìn)行轉(zhuǎn)換。并且大膽地給出了5位轉(zhuǎn)碼的算法,見(jiàn):
http://www.javaeye.com/topic/286240
不過(guò)這種5位的轉(zhuǎn)換會(huì)產(chǎn)生更多多余的字節(jié),6位的轉(zhuǎn)碼充分利用了現(xiàn)今的可讀文本,可是5位卻沒(méi)有,因?yàn)?和8的最小公倍數(shù)是40,
所以當(dāng)每轉(zhuǎn)換40位即5個(gè)字節(jié)的二進(jìn)制數(shù)據(jù)需要8個(gè)字節(jié)來(lái)表示,這樣就多產(chǎn)生3個(gè)字節(jié),浪費(fèi)的效率是3/5, 而6位轉(zhuǎn)碼浪費(fèi)的效率是
1/3。而且隨著字節(jié)增多,轉(zhuǎn)化效率也在下降。可見(jiàn)采用5位轉(zhuǎn)碼是一種既浪費(fèi)空間,又浪費(fèi)效率的解決方案。在不增加url長(zhǎng)度的情況下充分提高效率,6位編碼是最佳的。如果可以任意的餓犧牲url長(zhǎng)度,
可以把0-9全部拿出來(lái)當(dāng)做標(biāo)記位,0-9不會(huì)單獨(dú)出現(xiàn),這樣一共有10*26 + 26 = 286 種可能還不包括小寫(xiě)字母,
此外還有=,+,-什么的至少256可以編碼8位的字節(jié)了,這樣處理效率就提高了。
現(xiàn)在把問(wèn)題優(yōu)化一下,人類(lèi)可讀無(wú)歧義的文本碼有0-9,A-Z,a-z共62個(gè)
設(shè)取出x個(gè)作為標(biāo)志位則(62-x) * x + (62 - x) >= 256
解這個(gè)二元一次方程得到:
3.366<=X<=57.634
考慮到編碼的文本長(zhǎng)度,取x的最小值,即 4
最優(yōu)解:
用0, 1, 2, 3做為標(biāo)志位
4-9,A-Z, a-z參與編碼并與標(biāo)志位配合實(shí)現(xiàn)8位字節(jié)的文本化
可以看到這種方法的轉(zhuǎn)碼效率會(huì)比較高,但是空間冗余大。
此外其實(shí)可用的文本不知62個(gè),包括感嘆號(hào)等用上后補(bǔ)足64 = 2^6
它的高位是 00
那么只要再找到三個(gè)文本符保存其他三個(gè)高位01 10 11就可以了
這樣的轉(zhuǎn)碼空間可以更小一些。
想法還很不成熟,歡迎大家批評(píng)
@2008 楊一. 版權(quán)所有. 保留所有權(quán)利