* 查询接口

http://api.k780.com:88/?app=ip.get&ip=47.96.133.100&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json

{"success":"1","result":{"status":"OK","ip":"47.96.133.100","ip_str":"47.96.133.1","ip_end":"47.96.133.254","inet_ip":"794854756","inet_str":"794854657","inet_end":"794854910","areano":"0571","postno":"310000","operators":"阿里云","att":"中国,浙江,杭州","detailed":"中国浙江杭州 阿里云/电信/联通/移动/铁通/教育网","area_style_simcall":"中国,浙江,杭州","area_style_areanm":"中华人民共和国,浙江省,杭州市"}}

 

* IP地址转化为整数 (js实现)

function ip2int(ip) {
    var i = ip.split('.').map(function(s) {
        return s.split('').reduce(function(a, c, i) {
            return (a = 10*a + c.charCodeAt(0)-48)
        }, 0);
    }).reduce(function(a, c, i, array) {
		a |= c << (array.length-i-1)*8;
        return a;
    }, 0);
	if (i < 0) {
		i += 0x0000000100000000;
	}
	return i;
}
var ip_int = ip2int("47.96.133.100");
console.log(ip_int);

Output:

794854756

console.log( ip2int("172.16.0.224") );

2886729952

通过http://www.bejson.com/convert/ip2int/验证

 

参考ECMA-262

12.8.3.1 Runtime Semantics: Evaluation 
ShiftExpression : ShiftExpression << AdditiveExpression 
1. Let lref be the result of evaluating ShiftExpression. 
2. Let lval be GetValue(lref). 
3. ReturnIfAbrupt(lval). 
4. Let rref be the result of evaluating AdditiveExpression. 
5. Let rval be GetValue(rref). 
6. ReturnIfAbrupt(rval). 
7. Let lnum be ToInt32(lval). 
8. ReturnIfAbrupt(lnum). 
9. Let rnum be ToUint32(rval). 
10. ReturnIfAbrupt(rnum). 
11. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute 
rnum & 0x1F. 
12. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

172.16.0.1 会变为负数

根据ECMA-262文档,移位操作返回值 是 signed int 32位, 所以没法通过 &= 0x00000000ffffffff 把32bit最高位置为0, - 转换为正数 - 只能加上4294967296

 

* IP 整数转换为字符串

function int2ip(bytes) {
	var a = bytes >> 24, b = bytes >> 16 & 0x00ff,
		c = bytes >> 8 & 0x000000ff, d = bytes & 0x000000ff;
	return a +'.' + b + '.' +c + '.' +d;
}

test case: 3083241027

"-73.198.134.67"

最前面一个字节出现了负值 ,因为最高位为1,所以需要 & 0x00ff,把高位置为0

function int2ip(bytes) {
	var a = (bytes >> 24)&0x00ff, b = bytes >> 16 & 0x00ff,
		c = bytes >> 8 & 0x000000ff, d = bytes & 0x000000ff;
	return a +'.' + b + '.' +c + '.' +d;
}

 

php 实现:

* long2ip.php

<?php
function mylong2ip($long) {
    $long &= 0xffffffff;
    $a = [ ($long >> 24)&0x00ff, ($long >> 16)&0x00ff, ($long >> 8)&0x0000ff, $long & 0xff ];
    return implode('.', $a);
}

function myip2long($ip) {
    $arr = explode('.', $ip);
    $s2i = function($s) {
        $n = strlen($s);
        $acc = 0;
        for ($i = 0; $i < $n; $i++) {
            $acc = 10 * $acc + (ord($s[$i]) - 48);
        }
        return $acc;
    };
    list($a, $b, $c, $d) = array_map($s2i, $arr);
    return ($a<<24) | ($b << 16) | ($c <<8) | $d;
}

// test:

$ip = mylong2ip(794854756); // 47.96.133.100
echo $ip.PHP_EOL;

$long = myip2long($ip);
echo $long.PHP_EOL;

// run:

ubuntu@et-dev-mingzhanghui:~/code/php$ php long2ip.php
47.96.133.100
794854756

 

ip地址换化为整数为负数?  + 4294967296  

2 * (2147483647+1)

 

相关的php函数:

http://php.net/manual/en/function.list.php

http://php.net/manual/en/function.array-map.php

http://php.net/manual/en/function.ord.php

http://php.net/manual/en/function.explode.php

http://php.net/manual/en/function.strlen.php