大家都知道,ASCII(不包括扩展ASCII)的最高位是0,所以,我们可以利用这一空位来存储数据,“7BIT压缩编码”就是这么做的。关于7BIT压缩编码的详细算法,可以在网上找到(Simple)。这里,我说一下自己的一种关于计算7BIT编码长度的C语言实现方法。(应该有更好的方法啦~)
1。如果给出已经7BIT编码的字符串,在不解码的情况下,计算出解码后的长度,也就是源码(ASCII)的长度。
pSrc -- 已经编码的字符串地址
nSrc -- 通过函数strlen(pSrc)计算出来的长度
nLength -- 原编码的长度(就是我们想知道的结果)
if (nSrc%7 == 0)
{
if (*(pSrc+nSrc-1) >> 1)
nLength = (nSrc/7)*8;
else
nLength = (nSrc/7)*8 - 1;
}
else
{
if (*(pSrc+nSrc-1) >> (8-nSrc%7))
nLength = (nSrc/7)*8 + nSrc%7 + 1;
else
nLength = (nSrc/7)*8 + nSrc%7;
}
解释:
第一个判断编码后的长度是不是7的倍数,我们都知道,7BIT压缩编码可以将8字节ASCII压缩成7字节。如果编码后的长度恰好是7的倍数,那么就“很可能"源码是8的倍数长度。这里只能说是“很可能”,因为 8*n-1 个ASCII编码后也会占用 7*n 个字节(也有可能是 7*n-1 字节)。也就是说,160个ASCII编码后为140字节,159个ASCII编码后也为140字节(或者139字节),那么现在我们知道编码后是140字节,原编码ASCII到底是160个,还是159个呢?
if (*(pSrc+nSrc-1) >> 1) 做出了判断,如果结果为真,那么就是 8*n 个原编码,如果为假,那么就是 8*n-1 个原编码。这里,相信大家稍微思考一下就明白了;)嘻嘻,有不明白的,email问我啦~
如果编码后的长度,不是7的倍数,那么对最后一位的移位判断稍微复杂一些,道理是和上面一样的,只是移位的位数不一样而已。计算长度的时候,先取出8位ASCII的整数倍(nSrc/7)*8,然后再取余数nSrc%7,然后根据对最后一位的移位判断结果,判断到底是否还得加一位。(这是为什么呢?为什么不是和上面7的整数被时的减一位呢?哈哈~思考一下就知道了)
2。如果给出原ASCII字符串,在不编码的情况下,计算出7BIT编码后的长度。
pSrc -- 源ASCII字符串地址
nSrc -- 通过函数strlen(pSrc)计算出来的长度
nLength -- 7BIT编码后的长度(就是我们想知道的结果)
if (nSrc%8 == 0)
{
nLength = (nSrc/8)*7;
}
else
{
if (*(pSrc+nSrc-1) >> nSrc%8-1)
nLength = (nSrc/8)*7 + ((nSrc%8)*7)/8 + 1;
else
nLength = (nSrc/8)*7 + ((nSrc%8)*7)/8;
}
解释:
如果长度是8的整数倍,那非常简单,如果不是呢,那么又得对最后一位进行移位判断了,所移位的位数为 nSrc%8-1 位,如果移位后,还“剩”数据,那么就得多加一位了:)
好了,就说到这里,如果有什么不明白,或者发现我有不对的地方,或者有更好的计算方法,可以一起讨论哦!
顺便提一下,7BIT编码在发送短信时,如果短信内容都是ASCII,那么将会采用7BIT压缩编码,将160个ASCII压缩为140字节进行传输。:)