由專案中一個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的时候得到的结果可能是不一样的,这个问题值得注意

可以用sprintf('%u',ip2long($ip)),需要注意的是,sprintf返回的都是字符串

function dotip2uint($cip) {
    $dotips = explode('.', $cip, 4);
    return intval($dotips[0]) * 16216 + intval($dotips[1]) * 65536 + intval($dotips[2]) * 256 + intval($dotips[3]);
}

 

更多相关文章
一周排行
  • python 的 getopt 模块是一个简单实用的命令行参数解析模块.实现命令解析功能的为模块中的getopt 方法.下面主要介绍一下这个getopt方法的使用. 查看getopt 模块的幫助可以得到 getopt ...
  • @Entity     将一个 POJO 类注解成一个实体 bean ( 持久化 POJO 类 )@Table    为实体 bean 映射指定具体的表,如果该注解没有被声明,系统将使用默认值 ( 即实体 bean ...
  • <hibernate-mapping> 允许嵌套多个<hibernate-mapping>映射. 推荐一个持久化类对应一个映射文件,并以持久化类的超类名命名. 1. schema(可选) 数据 ...
  • <PC World>日前评选出了影响全球互联网的50名人.以下是具体的排名情况: 第一:Google联合创始人拉里·佩奇与塞吉·布林,以及公司首席执行官埃里克·施密特: 第二:苹果首席执行官史蒂夫·乔布斯 ...
  • leetcode Ch7Graph Search
     1. Clone Graph BFS: 1 class Solution { 2 pub
  • 


    		    轉 Apache文檔rotatelogs滾動日志
    提到了awstats来分析日志,那么有关apache日志的知识是必须要了解的.现在我就将a
  • 我只能说的亏没做,要不就挂0了.. 本来想四色定理,肯定4就可以的...然后准备爆,发现3的时候不好爆,又想了老一会,嗯,数据范围不小,应该不是暴力,直接找规律,貌似最大就是3,有一个3连块,输出3,其他输出2什么的
  •   描述: A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given n ...
  • S=a + (a + 1) + (a + 2) + ...... + b(其中a, b > 0) 现在我们要求,给定一个正整数S,求有多少种不同的<a,b>,使得上述的等式成立. 这个问题很有意思, ...
  • 翻譯 LiquidFloatingActionButton
    LiquidFloatingActionButton   https://github.c