首页 > 代码库 > 由项目中一个hash2int函数引发的思考
由项目中一个hash2int函数引发的思考
hash2int
/** * 计算一个字符串的md5折算成int返回 * @param type $str * @return type */function hash2int($str) { $md5str = md5($str, true); $one = unpack(‘l‘, substr($md5str, 0, 4)); $two = unpack(‘l‘, substr($md5str, 4, 4)); $three = unpack(‘l‘, substr($md5str, 8, 4)); $four = unpack(‘l‘, substr($md5str, 12, 4)); return current($one) + current($two) + current($three) + current($four);}
思考一:这个函数有没有优化的空间,直接上代码
function hash2int2($str) { $md5str = md5($str, true); $arr = unpack(‘la/lb/lc/ld‘, $md5str); return array_sum($arr);}
效率大约是上一个函数的4倍(当然这种程度的优化对于一个设计到db等的大项目的效率影响很小)
思考二:pack/unpack在php中的使用
首先熟悉几个概念
计算机当中通常采用的自己存储方式(字节序)有:大端和小端 大端序(网络字节序):①多字节传输时,先传高字节;②存储时高位字节在低地址 小端序:①多直接传输时,先传低位字节;②存储时低位字节放在低地址 栗子:0x12345678 大端序:0x12 0x34 0x56 0x78 小端序:0x78 0x56 0x34 0x12 主机字节序:本机的字节序
pack的参数:
格式字符翻译a -- 将字符串空白以 NULL 字符填满A -- 将字符串空白以 SPACE 字符 (空格) 填满h -- 16进制字符串,低位在前以半字节为单位H -- 16进制字符串,高位在前以半字节为单位c -- 有符号字符C -- 无符号字符s -- 有符号短整数 (16位,主机字节序)S -- 无符号短整数 (16位,主机字节序)n -- 无符号短整数 (16位, 大端字节序)v -- 无符号短整数 (16位, 小端字节序)i -- 有符号整数 (依赖机器大小及字节序)I -- 无符号整数 (依赖机器大小及字节序)l -- 有符号长整数 (32位,主机字节序)L -- 无符号长整数 (32位,主机字节序)N -- 无符号长整数 (32位, 大端字节序)V -- 无符号长整数 (32位, 小端字节序)f -- 单精度浮点数 (依计算机的范围)d -- 双精度浮点数 (依计算机的范围)x -- 空字节X -- 倒回一位@ -- 填入 NULL 字符到绝对位置
关于pack和unpack推荐3篇博客,写得非常好
http://my.oschina.net/goal/blog/195749
http://my.oschina.net/goal/blog/202378
http://my.oschina.net/goal/blog/202381
后续我会结合自己项目当中php跟C模块通过Nshead协议的交互来补充这块
思考三:有各种数字想到了ip2long这个函数
php中的ip2long函数的原理:将每一段看成256进制的数字
function ip2int($ip) { list($ip1, $ip2, $ip3, $ip4) = explode(".", $ip); return ($ip1 << 24) | ($ip2 << 16) | ($ip3 << 8) | ($ip4);}
问题就出现了,2int之后可能出现负数,所以我们一般使用 sprintf(‘%u‘,ip2long($ip))
php是只支持有符号的整数的,32 64的系统所支持最大的整型数是不同的,所以在不同操作系统使用ip2long的时候得到的结果可能是不一样的,这个问题值得注意
由项目中一个hash2int函数引发的思考
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。