在pdu模式中,如果短信内容为英文,通常采用7bit 编码 ,网上有许多7bit编码转为字符的源码,字符转为7bit编码的源码也有不少,但我却没有找到什么可用的php源码。于是我自己刚写的一段代码,现在拿上来供大家参考,希望能起到抛砖引玉的作用。
我们先简单聊一下7bit的来源及原理。
下面这段话我也是网上看到的,说得很好,为了更贴近pdu实例,我稍微做了些修改:
7bit编码实际上是一种压缩编码,因为ASCII码(不包括扩展的ASCII) 其值都是小于0x80的,也就是说其最高位为0,那么最高位信息也就是说没有意义的,可以被忽略。而7-bit编码也正是关注到了这一点,利用最高位也来存储数据,其编码时一次将下一7位编码的后几位逐次移到前面,形成了新的8位编码。
那么这样的话,回到我们的例子,也就是说ASCII字符可以使用7位编码
首先将所有字符转换成7位编码,即只要去除最高位就行:
1 2 3 4
0110001 0110010 0110011 0110100
现在需要将没个字节补齐,也就是补到8位,
首先将1补齐,将2的最后一位补到1前面:00110001 011001 0110011 0110100
将2补齐,将3的最后两位不到2前面: 00110001 11011001 01100 0110100
将3补齐,将4的最后补到3前面: 00110001 11011001 10001100 0110
最后将4补齐,在最前面不上四个0: 00110001 11011001 10001100 00000110
这个时候1234字符串的编码就变为了: 31 d9 8c 06 该值正好就是我们的短信内容!
下面开始上源码:
class CharsetConv{ /** * pdu编码 * @param $codetype 编码方式 08:ucs-2,00:7bit * @param $str 待 转码 的字符 * @return 转码后的字符 */ public function decode_pdu($codetype,$str){ switch($codetype){ case "08"://ucs-2 $smsok = $this->decode_ucs2($str); break ; case "00"://7bit $ sms ok = $this->decode_7bit($str); break; default: $smsok = $str; } return $smsok; } private function encode_7bit($sms){ $smsa = str_split($sms, 1); foreach ($smsa as $k=>$sv) { $s = base_convert(ord($sv), 10, 2); if( strlen ($s)<7){ $sv = "0".$s; }else{ $sv = $s; } $smsa[$k] = $sv; } for($i=0;$i$sav){ $hexres = base_convert($sav, 2, 16); $smsa[$k] = str_pad($hexres,2,"0",STR_PAD_LEFT); } $smscontent = implode(" ",$smsa); return strtoupper($smscontent); } }
本文只讨论了7bit的编码,如果有朋友对ucs-2编码感兴趣,我们下次再讲。
使用方法:
$conv = new CharsetConv(); $content = $conv->encode_pdu("00",$sms);//内容为英文,编码格式7bit
上面代码中,$sms为待编码的字符,$content为编码后的7bit内容。
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~