zoukankan      html  css  js  c++  java
  • 由项目中一个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]) * 16777216 + intval($dotips[1]) * 65536 + intval($dotips[2]) * 256 + intval($dotips[3]);
    }
  • 相关阅读:
    del:根据索引值删除元素
    Python insert()方法插入元素
    Python extend()方法添加元素
    Python append()方法添加元素
    Python list列表添加元素的3种方法
    什么是序列,Python序列详解(包括序列类型和常用操作)
    Python运算符优先级和结合性一览表
    Python print()函数高级用法
    Python input()函数:获取用户输入的字符串
    Python变量的定义和使用
  • 原文地址:https://www.cnblogs.com/bai-jimmy/p/4192676.html
Copyright © 2011-2022 走看看