网创优客建站品牌官网
为成都网站建设公司企业提供高品质网站建设
热线:028-86922220
成都专业网站建设公司

定制建站费用3500元

符合中小企业对网站设计、功能常规化式的企业展示型网站建设

成都品牌网站建设

品牌网站建设费用6000元

本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...

成都商城网站建设

商城网站建设费用8000元

商城网站建设因基本功能的需求不同费用上面也有很大的差别...

成都微信网站建设

手机微信网站建站3000元

手机微信网站开发、微信官网、微信商城网站...

建站知识

当前位置:首页 > 建站知识

IP转换器的使用

这篇文章主要介绍“IP转换器的使用”,在日常操作中,相信很多人在IP转换器的使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”IP转换器的使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

专注于为中小企业提供成都做网站、网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业玉屏免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了成百上千家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

今天做的这个题目是:IP转换器。实际上只是实现一个IP转换的方法而已。

题目(难度6kyu:IPv4 to int32):

简单翻译一下:

有一个IPv4地址: 128.32.10.1。 这个地址实际由4个8位的字节组成:

第一个128,它的二进制是: 10000000
第二个32, 它的二进制是: 00100000
第三个10, 它的二进制是: 00001010
第四个1, 它的二进制是: 00000001

所以, 128.32.10.1 相当于 10000000.00100000.00001010.00000001

这样的话,IP地址就是由32位的了,于是我们就根据这32位字节得到一个数字:2149583361。

要求:

写一个函数:ip_to_int32(ip) 可以让这个IPv4的地址返回那个数字:
iptoint32("128.32.10.1") = 2149583361


解题思路:

可以看得出来,codewars的题目,多是来源于实践中的一些基础知识。这里隐含的知识是:

为什么要把IP转换为一个数字呢? 
TCP/IP协议规定,IP地址是由32位二进制数组成,简单来说,是为了便于查询或做一些根据IP设置的登陆限制,比如一些IP数据库,里面存储的就是根据32位二进制转化成的数。

在知道这个基础知识的前提下,这个题目才变得有意义。

那么我最初的解题思路是这样的:
1. 需要把"128.32.10.1"这个字符串里的每一个ip数字转换为二进制。
2. 把4段二进制拼接在一起形成一个32位二进制串。
3. 把32位二进制串变成十进制。

于是我得到了下面这个方法:

def ip_to_int32(ip)
  ip.gsub(/(\d+)/){|i|i = i.to_i.to_s(2); "0"*(8-i.size)<< i} \        .gsub(/\./, "")\ 
    .to_i(2)
end

测试是成功的:

Test.assert_equals(ip_to_int32("128.32.10.1"), 2149583361)

解释:
1. gsub方法有一个用法就是可以传递块, 这样就避免了我另外去迭代处理。/(\d)+/,这个正则不太严谨,只是取数字,但没有判断不合法的IP地址,这里就不考虑那么多了。 
2. "0"*(8-i.size)<< i 这段代码是个笨方法,是为了给转换为二进制的IP数字补足8位。
3. 128.to_s(2)是十进制转二进制的一个方法, "1010".to_i(2)是二进制转十进制的方法。


答案通过以后,就可以看到别人写的答案了,大致看了一下,有几个很有启发:

第一个:使用字符串格式化的思路:

 
def ip_to_int32(ip)
  ("%02x%02x%02x%02x" % ip.split('.')).to_i(16)
end

解释:
1. "%02x"是把一个字符串格式化为16进制,2为指定的输出字段的宽度.如果位数小于2,则左端补0
2. % 操作符, 用于字符串格式化。
3. to_i(16), 把16进制转换为10进制。

受这个思路的启发,我又改了下我的代码:

 
def ip_to_int32(ip)
  ("%08b"*4 % ip.split('.')).to_i(2)
end

解释:
1. 使用2进制、8进制、16进制的指示符分别是(b',o', x',X')
2. 所以,"%08b"是把一个十进制数格式化为一个二进制数,8位宽度,如果位数小于8,则左端补0.

这种写法比我之前那种简洁多了。

第二个: 使用位操作:
看到有一个人用了位移操作,是这样的:

 
def ip_to_int32(ip)
  ip.split('.').inject(0) { |total, val| (total << 8) + val.to_i}
end

这是我用他的思路改的代码:

 
def ip_to_int32(ip)
  ip.split('.').each_with_index.inject(0) do |total, (ip, index)|
    total += (ip.to_i << (8*(3 - index)))
  end
end

解释:
IP地址都是基于256来计算的:

128 * (256)**3 + 32 * (256)**2 + 10 * (256)**1 + 1 * (256)**0 = ?
2147483648 + 2097152 + 2560 + 1 = 2149583361

当然,可以直接把这个等式写成代码,也可以求得结果,但是我们用位操作更快:

 
//  128 << 24//  32  << 16//  10  << 8//  1   << 0

当然还有其他解法,都是一般的数组拼接,我就不罗列了。

从十进制数字转换为IP地址的方法,就是一个逆向过程,我也不多写了。

感兴趣的朋友,可以去玩玩CodeWars。

到此,关于“IP转换器的使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!


当前名称:IP转换器的使用
网页URL:http://bjjierui.cn/article/jjggei.html

其他资讯