先看看什么是IP地址:

IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

为什么要转化IP地址:

点分十进制表示法只是为了让人好记忆,并不能用于电脑运算;

数据库中跟IP地址有的字段一般都会存成整数,这样便于查询,也可以提高了查询速度;

javascript中转换的几种方案:

首先说一下IP地址的验证,

这里就用正则表达式验证的方式,表达式如下

var REG =/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;

后面代码中用到 REG 就是这个了 , 虽然这个正则表达式有点长,但用它可以把验证和分割一步到位,后面转换的时候就省掉了分割IP地址的步骤;

方案1:每8位转成16进制字符,拼接后转成整数

当IP地址通过用“.”分割后,每一段都因该是8位,所以我们刚好可以转成两位的16进制数,然后拼接16进制的字符串,再转为数字就OK了。

 
function ipToInt(IP){
var xH = "",result = REG.exec(ip);
if(!result) return -1;
for (var i = 1; i <= 4; i++) {
var h = parseInt(result[i]);
xH += (h > 15 ? "" : "0") + h.toString(16);
}
return parseInt(xH, 16);
}

如果不要验证的话就可以换一个帅气一点的写法:

function ipToInt(IP){
return parseInt(IP.replace(/\d+\.?/ig,function(a){
a = parseInt(a);
return (a > 15 ? "" : "0") + a.toString(16);
}),16);
}

方案2:直接计算

知道了IP地址的结构,不难想到只要给分割之后的数字乘以相应的数,再加起来就OK了;

function ipToInt(IP){
var xH = "",result = REG.exec(ip);
if(!result) return -1;
return (parseInt(result[1]) * 0x1000000
+ parseInt(result[2]) * 0x10000
+ parseInt(result[3]) * 0x100
+ parseInt(result[4]));
}

方案3:按位计算

直接记算还不如按位运算,那不是更快?

function ipToInt(IP){
var xH = "",result = REG.exec(ip);
if(!result) return -1;
return (parseInt(result[1]) << 24
| parseInt(result[2]) << 16
| parseInt(result[3]) << 8
| parseInt(result[4]));
}

如果看不明白,还请回去补一下2进制的课哦。

上面按位运算看起来没什么问题,
试了几个IP地址之后就发现不对了, 最后发现 当IP的值大于0x7fffffff(127.255.255.255)时变负数了,
原因是JS在按位运算的时候都是当成32位的整型来算的,本来刚好32位,结果最左边一位成了符号位,不够用了
是不是很多同学在发现溢出之后就放弃这个安案了呐。

我来本打算放弃的时候一想,不对啊,符号位不也就是0,1吗,不是还有">>>"无符号右移运算符吗,我无符号右移0位行不行呐:

function ipToInt(IP){
var xH = "",result = REG.exec(ip);
if(!result) return -1;
return (parseInt(result[1]) << 24
| parseInt(result[2]) << 16
| parseInt(result[3]) << 8
| parseInt(result[4]))>>>0;
}

测试之后果然OK,万幸IP地址是32位,刚刚好,不然这个方案只能放弃了。

方案4:按位,字符串拼接结合(纯属于瞎折腾)

function ipToInt(IP) {
var xH = "",
result = REG.exec(ip);
if (!result) return - 1;
var ip2 = "000000" + ((parseInt(result[2]) << 16) | (parseInt(result[3]) << 8) | parseInt(result[4])).toString(16);
return parseInt(parseInt(result[1]).toString(16) + ip2.substr(ip2.length - 6), 16);
}

你肯定在问为什么会有这么怪的想法,其实是安位运算出现了符号位的问题不甘心放弃,这个想法就这么出来了.

总结

照道理说"方案3"因该是最有效率的方法.
但最后100万次的运算测试表明"方案2"的效率和"方案3"相差无几,难道是因为V8?

附上一个反函数:

function intToIp(INT){
if(INT < 0 || INT > 0xFFFFFFFF){
throw ("The number is not normal!");
}
return (INT>>>24) + "." + (INT>>16 & 0xFF) + "." + (INT>>8 & 0xFF) + "." + (INT & 0xFF);
}

转载请注明出处 http://www.cnblogs.com/whyoop,谢谢!

javascript把IP地址转为数值几种方案,来挑战一下效率吧的更多相关文章

  1. [LeetCode] IP to CIDR 将IP地址转为CIDR无类别域间路由

    Given a start IP address ip and a number of ips we need to cover n, return a representation of the r ...

  2. JavaScript按IP地址排序

    JavaScript按IP地址列表排序,主要思路就是分割每个点号部分,然后ip1和ip2分别对不够三位数的进行补0操作,然后转换为数字类型进行一一比较. 上代码: 正序: var arr=[ {ip: ...

  3. ArcGIS JavaScript API4.8 底图选择的几种方案

    创建一个HTML页面,引入ArcGIS JavaScript API,在<body>标签内创建一个div并添加ID值,在<head>标签内设置样式<style>,在 ...

  4. JavaScript实现IP地址的输入框方式

    最近遇到一些这样的需求:实现一种IP地址的输入方式,就是输入3个字符或自动跳到下一个输入框内,删除的时候,一个输入框没有了字符,自动跳回上一个输入框.看到这里,相信大家都有一些想法了,没错,这种方法就 ...

  5. IP地址及子网--四种IP广播地址

    国际规定:把所有的IP地址划分为 A,B,C,D,E. 类默认子网掩码:A类为 255.0.0.0; B类为 255.255.0.0; C类为 255.255.255.0.子网掩码是一个32位地址,用 ...

  6. C#中IP地址转换为数值的方法

    任何语言都通用的方法转换 IP 地址 a.b.c.d ==> a***+b**+c*+d ===> *(c+*(b+*a)) +d 示例: ***+**+*+ ===> *( +*( ...

  7. linux,windows下检测指定的IP地址是否可用或者检测IP地址冲突的3种方式(批处理程序,python程序,linux shell 批量ping)

    本文中的脚本适用范围: 1)检测某些IP地址是否被占用: 2)检测网络中某些设备是否存活: 3)在分配新的ip地址之前,批量检测环境中是否存在冲突的机器 以上检测基于ICMP Ping报文,要求所有的 ...

  8. IP地址转为二进制,去掉0b补齐八位拼接,再转为十进制

    #!/usr/bin/env python# -*- coding:utf-8 -*- ip = '192.168.0.1' # 转为二进制:# 方法一'''eve = ip.split('.')s ...

  9. PHP获取用户访问IP地址的5种方法

    IP地址获得的五种方法: <?php //方法1: $ip = $_SERVER["REMOTE_ADDR"]; echo $ip; //方法2: $user_IP = ($ ...

随机推荐

  1. Tomcat配置HTTPS方式生成安全证书

    在Tomcat 6中配置SSL双向认证是相当容易的,本文将介绍如何使用JDK的keytool来为Tomcat配置双向SSL认证.并实现批量生成证书 系统需求:JDK 5.0Tomcat 6.0.16启 ...

  2. python-转换成exe文件(py2exe)

    一.简介: py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样,你就可以不用装python而在windows系统上运行这个可执行程序.py2e ...

  3. [geeksforgeeks] Bottom View of a Binary Tree

    http://www.geeksforgeeks.org/bottom-view-binary-tree/ Bottom View of a Binary Tree Given a Binary Tr ...

  4. kerberos+ladp+hadoop-ha 安全认证部署配置

    随着hadoop集群里的数据量越来越大,各业务数据都集中了里面,自然要为各业务都要提供数据支持,又希望各业务数据是相对独立安全的,这最时候就需要做安全认证了 hadoop ha 测试集群部署规划 ha ...

  5. AJAX实现仿Google Suggest效果

    修复了一些细节代码(支持持续按键事件) *项目名称:AJAX实现类Google Suggest效果*作者:草履虫(也就是蓝色的ecma)*联系:caolvchong@gmail.com*时间:2007 ...

  6. 驱动笔记 - file_operations

    #include <linux/fs.h> struct file_operations { struct module *owner; loff_t (*llseek) (struct ...

  7. ”sql Server2008 应用程序无法启动,因为应用程序的并行配置不正确。 找不到从属程序集。“C:\windows\SysWOW64\DTSPipelinePerf100.dll”的激活上下文生成失败“的解决方案

    一:控制面板->管理工具->事件查看器->windows日志->应用程序   查看错误原因: 二:在其他机子上拷贝一个DTSWizard.exe.config文件替换本机上已经 ...

  8. Sqli-labs less 55

    Less-55 本关的sql语句为: $sql="SELECT * FROM security.users WHERE id=($id) LIMIT 0,1"; 其余和less54 ...

  9. c++11 内存模型解读

    c++11 内存模型解读 关于乱序 说到内存模型,首先需要明确一个普遍存在,但却未必人人都注意到的事实:程序通常并不是总按着照源码中的顺序一一执行,此谓之乱序,乱序产生的原因可能有好几种: 编译器出于 ...

  10. 使用tomcat7创建异步servlet

    该篇文章翻译自:http://developerlife.com/tutorials/?p=1437 一.简介 Servlet API 3.0 之前,需要使用类似Comet的方式来实现创建异步的Ser ...