JavaScript中IPV6地址的获取、校验与转换实现

作者:百宝袋时间:2026-10-30 08:54:34浏览:625

本文介绍如何在JavaScript中处理IPV6地址。首先简述IPV6与IPV4的区别及前缀概念,重点提供IPV6地址的完整化补全、正则表达式校验方法,以及将IPv4地址转换为IPv6格式(含::ffff前缀)的具体JS代码实现,支持多种掩码格式。

IPV6基础概念与地址格式

1、什么是IPV6?

关于该概念,可通过搜索引擎查询获取详细信息。其核心目的是解决IPV4地址资源枯竭的问题。IPV4采用32位地址格式,例如常见的192.168.1.1;而IPV6采用128位地址格式,地址空间相比IPV4大幅扩展。

2、IPV6有子网掩码吗?

这一概念在IPV6中表现为“前缀”(Prefix),其作用类似于IPV4中的子网掩码,只是命名不同。由于IPV6地址空间极其庞大,理论上可为地球上的每一粒沙子分配一个地址,因此子网划分的概念被淡化,实际应用中常直接忽略传统子网掩码的需求。

3、IPV6的地址

IPV6的书写格式在网络上已有大量资料,此处不再赘述。典型格式如1205::fff0:ffd1:1021/120,其中斜杠后的数字“120”代表前缀长度,对应IPV4中的子网掩码概念。

4、IP地址的计算方式

IPV6与IPV4在网段计算原理上是一致的。以IPV4为例,如192.168.1.1/255.255.255.0,其网段范围是192.168.1.0至192.168.1.255。起始地址由IP地址与子网掩码进行按位与运算得出;终止地址由IP地址与子网掩码取反(忽略符号位)后进行按位或运算得出。

IPV6同样遵循此原理,但由于前缀长度极长,无法使用255.255.255.0的形式表示,故通常直接书写数字前缀(如120或128)。例如“120”表示前120位为1,后续位为0,这相当于IPV4的子网掩码,计算方式与IPV4相同。

IPV6地址处理与转换实现

上述内容简要说明了IPV6的基础知识,接下来重点讨论IPV6地址的处理方法。

IPV6地址书写需兼容零压缩法,因此需要对IPV6地址进行格式转换。以下是JavaScript的转换代码:


function transitIp(ipaddr)//将IPV6地址补全
{
 var ipaddress = ipaddr.split("/");
 var ipaddrs = ipaddress[0].split(":");
 if(ipaddrs.length<8)
 {
 var count = 0;
 for(var i=0;i<ipaddrs.length;i++)
 {
 if(ipaddrs[i]=="")
 {
 if(count==1)
 {
  ipaddrs[i] = addZero(4);
  continue;
 }
 ipaddrs[i] = addZero((9-ipaddrs.length)*4);
 count++;
 }
 else
 {
 ipaddrs[i] += ":";
 }
 }
 }
 else if(ipaddrs.length==8)
 {
 for(var i=0;i<8;i++)
 {
 ipaddrs[i] += ":";
 }
 }
 ////上述补齐完成,将内容放置于ipaddrs中,但不标准
 return initaddr(ipaddrs);//获得了ip地址的完整字符串
}
function addZero(num)
{
 var zerostr = "";
 for(var i=1;i<num+1;i++)
 {
 zerostr+="0";
 if(i%4==0)
 {
 zerostr+=":";
 }
 }
 return zerostr;
}
function initaddr(ipaddrs)
{
 var iparray ="";
 for(var i=0;i<ipaddrs.length;i++)
 {
 iparray+=ipaddrs[i];
 }
 if(iparray.charAt(iparray.length-1)==':')
 {
 iparray = iparray.substr(0,iparray.length-1);
 }
 //var iparrays = iparray.split(":");
 //return iparrays;
 return iparray;
}

IPV6地址判断的正则表达式为:


function isIPv6(str)//IPV6地址判断 
{ 
 return /:/.test(str) 
 &&str.match(/:/g).length<8
 &&/::/.test(str)
 ?(str.match(/::/g).length==1
 &&/^::$|^(::)?([\da-f]{1,4}(:|::))*[\da-f]{1,4}(:|::)?$/i.test(str))
 :/^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i.test(str);
}

接着说明IPv4到IPv6的转换逻辑:

IPv4转IPv6地址相对简单,只需将IPv4地址转换为十六进制格式,以两组为一组,并在前面添加“::ffff”前缀即可。

JS代码如下:


function four2six(fouraddr,fourmask)//IPV4转IPV6,包括地址和掩码
{
 var reg = fouraddr.match(/^(\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])$/);
 if(reg==null)
 {
 alert("IP地址不正确!");
 return;
 }
 if(fourmask.indexOf(".")!=-1)
 {
 reg = fourmask.match(/^(254|252|248|240|224|192|128|0)\.0\.0\.0$|^(255\.(254|252|248|240|224|192|128|0)\.0\.0)$|^(255\.255\.(254|252|248|240|224|192|128|0)\.0)$|^(255\.255\.255\.(255|254|252|248|240|224|192|128|0))$/);
 if(reg==null)
 {
 alert("子网掩码不正确!");
 return;
 }
 }
 else
 {
 var mask = parseInt(fourmask, 10);
 if(mask<0 || mask > 32)
 {
 alert("子网掩码不正确!");
 return;
 }
 }
 /***
 IPV4转IPV6的方法很简单
 1、先将其每段转为16进制
 2、不足两位的前面添加0
 3、V4一共会产生4个16进制数字,比前两个和后两个分别组合
 4、地址前面加上"0000:0000:0000:0000:0000:ffff:"即可
 **/
 var sixtemp = "";
 var fouraddrs = fouraddr.split(".");
 for (var i=0; i<fouraddrs.length; i++)
 {
 var addr4ip = parseInt(fouraddrs[i], 10);
 var addrtemp = addr4ip.toString(16);
 if(addrtemp.length==1)
 {
 addrtemp = "0" + addrtemp;
 }
 sixtemp += addrtemp;
 if(i==1)
 {
 sixtemp += ":";
 }
 }
 //以上产生V6地址段正确
 sixtemp = "0000:0000:0000:0000:0000:ffff:" + sixtemp;
 /***
 下面处理子网掩码,子网掩码可以有两种写法,数字或者255.255.255.0写法
 1、第一种处理比较简单,只需此数值加96(128-32)即可
 2、第二种需要分为四段,每段转为2进制,看哪一位最开始变为0
 **/
 var masktemp = 96;
 if(fourmask.indexOf(".")==-1)
 {
 masktemp += parseInt(fourmask);
 }
 else
 {
 var masks = fourmask.split(".");
 for ( var i=0; i<masks.length; i++)
 {
 var mask4ip = parseInt(masks[i], 10);
 var mask4temp = mask4ip.toString(2);
 if(mask4temp.length!=8)
 {
 for(var j=0;j<8-mask4temp;j++)
 {
  mask4temp = "0"+mask4temp;
 }
 }
 //下面判断位置
 var flagtemp = false;
 for(var j=0;j<8;j++)
 {
 if(mask4temp.charAt(j)=='0')
 {
  flagtemp = true;
  masktemp += i*8 + j;
  break;
 }
 if(j==7&&i==3)
 {
  flagtemp = true;
  masktemp = 128;
  break;
 }
 }
 if(flagtemp)
 {
 break;
 }
 }
 }
 return sixtemp + "/" + masktemp;
}
function four2sixip(fouraddr)//IPV4转IPV6,只转地址
{
 var reg = fouraddr.match(/^(\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])$/);
 if(reg==null)
 {
 alert("IP地址不正确!");
 return;
 }
 var sixtemp = "";
 var fouraddrs = fouraddr.split(".");
 for (var i=0; i<fouraddrs.length; i++)
 {
 var addr4ip = parseInt(fouraddrs[i], 10);
 var addrtemp = addr4ip.toString(16);
 if(addrtemp.length==1)
 {
 addrtemp = "0" + addrtemp;
 }
 sixtemp += addrtemp;
 if(i==1)
 {
 sixtemp += ":";
 }
 }
 //以上产生V6地址段正确
 sixtemp = "0000:0000:0000:0000:0000:ffff:" + sixtemp;
 return sixtemp;
}

上述方法中包含了针对IPv4地址和掩码的正则判断,支持两种掩码格式:一种是传统的255.255.255.0形式,另一种是斜杠加数字的/32形式。

作者最新文章