数据库里有一列 ip, 存储内容是经过转换的ip, 比如
192.168.1.1, 数据库里存的是  192* 256^3 + 168* 256^2 + 1* 256^1 + 1* 256^0
如果想去数据库查询  192.168.1.* 的话,
192.168.1.0 === 192* 256^3 + 168* 256^2 + 1* 256^1 + 0* 256^0  === MIN
192.168.1.254 === 192* 256^3 + 168* 256^2 + 1* 256^1 + 254* 256^0  === MAX
可以用这个sql条件语句:
.... where ip >= MIN  and  ip <= MAX
但如果用 192.*.1.* 这样来查的话,就不能用简单的 >=  <= 了,  请教有啥好办法?
谢谢。

解决方案 »

  1.   

    能想到的就是拆分再组合查。
    这个和你的存储形式有关,别的不用考虑,XXX.XXX.XXX.XXX的IP地址本身不重复全表示就需要四个字节,而这种压缩存储形式最大占用2字节。可能有别的好办法,一时未想出来。
      

  2.   

    sql 语法忘了C语法:192.*.1.* 可表示为 ((ip / 256^3) == 192) && ((ip % 256^2) / 256 == 1)如果数据库中中采用 192* 10^9 + 168* 256^6 + 1* 10^3 + 1* 10^0 表示*.*2*.*2*.*2* 可表示为 ((ip % 10^2) / 10 == 2) && ((ip % 10^4) / 10^3 == 2) && ((ip % 10^5) / 10^4 == 2)
      

  3.   


    2个字节只能表示65536个数,你觉得这可能表示了全部的IP吗?xxx.xxx.xxx.xxx这种四个字节表示法有压缩的可能性吗?
      

  4.   

    其实这种表示法就是原本的socket的表示IP的in_addr结构体的表示法,只不过字节序可能有差异罢了
      

  5.   


    LZ提到的存储方法和in_addr有啥关系?
    typedef struct in_addr {
    union {
    struct {
    u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
    u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
    } S_un;
    } in_addr;
      

  6.   

    就看这个吧
    192* 256^3 + 168* 256^2 + 2* 256^1 + 1* 256^0 我们反过来看更便于理解:1 * 256^0 + 2 * 256^1 + 168 * 256^2 + 192 * 256^3第一个加号前面的就不说了第二个加号前面的:
    2 * 256^1 = 1 * 2^8 = 1 << 8 
    同理
    168 * 256^2 = 168 * 2^16 = 168 << 16
    192 * 256^3 = 192 * 2^24 = 192 << 24
    最后加起来的效果就是
    1放在整数的第一个字节
    2放在整数的第二个字节
    168放在整数的第三个字节
    192放在整数的第四个字节
    总之,一个四个字节整数可以表示这个ip,其中每个字节放了ip四个段中的一段。这种存储方式不是和in_addr的存储方式一样吗?只不过字节序有差别而已,楼主用的是主机字节序,而in_addr用的是网络字节序
      

  7.   


    乘的优先级比异或高
    192* 256^3 + 168* 256^2 + 1* 256^1 + 1* 256^0 
    =(192 << 8)^3 + ...
      

  8.   


    我压根就没想到乘方,呵呵
    怕啥,讨论越说越清楚,所以我奇怪LZ的那个压缩方式如何还原,或者LZ忘了括号?