溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

IP轉(zhuǎn)換器的使用

發(fā)布時間:2021-07-12 14:58:24 來源:億速云 閱讀:167 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“IP轉(zhuǎn)換器的使用”,在日常操作中,相信很多人在IP轉(zhuǎn)換器的使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”IP轉(zhuǎn)換器的使用”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習吧!

今天做的這個題目是:IP轉(zhuǎn)換器。實際上只是實現(xiàn)一個IP轉(zhuǎn)換的方法而已。

題目(難度6kyu:IPv4 to int32):

簡單翻譯一下:

有一個IPv4地址: 128.32.10.1。 這個地址實際由4個8位的字節(jié)組成:

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

所以, 128.32.10.1 相當于 10000000.00100000.00001010.00000001

這樣的話,IP地址就是由32位的了,于是我們就根據(jù)這32位字節(jié)得到一個數(shù)字:2149583361。

要求:

寫一個函數(shù):ip_to_int32(ip) 可以讓這個IPv4的地址返回那個數(shù)字:
iptoint32("128.32.10.1") = 2149583361


解題思路:

可以看得出來,codewars的題目,多是來源于實踐中的一些基礎(chǔ)知識。這里隱含的知識是:

為什么要把IP轉(zhuǎn)換為一個數(shù)字呢? 
TCP/IP協(xié)議規(guī)定,IP地址是由32位二進制數(shù)組成,簡單來說,是為了便于查詢或做一些根據(jù)IP設(shè)置的登陸限制,比如一些IP數(shù)據(jù)庫,里面存儲的就是根據(jù)32位二進制轉(zhuǎn)化成的數(shù)。

在知道這個基礎(chǔ)知識的前提下,這個題目才變得有意義。

那么我最初的解題思路是這樣的:
1. 需要把"128.32.10.1"這個字符串里的每一個ip數(shù)字轉(zhuǎn)換為二進制。
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)+/,這個正則不太嚴謹,只是取數(shù)字,但沒有判斷不合法的IP地址,這里就不考慮那么多了。 
2. "0"*(8-i.size)<< i 這段代碼是個笨方法,是為了給轉(zhuǎn)換為二進制的IP數(shù)字補足8位。
3. 128.to_s(2)是十進制轉(zhuǎn)二進制的一個方法, "1010".to_i(2)是二進制轉(zhuǎn)十進制的方法。


答案通過以后,就可以看到別人寫的答案了,大致看了一下,有幾個很有啟發(fā):

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

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

解釋:
1. "%02x"是把一個字符串格式化為16進制,2為指定的輸出字段的寬度.如果位數(shù)小于2,則左端補0
2. % 操作符, 用于字符串格式化。
3. to_i(16), 把16進制轉(zhuǎn)換為10進制。

受這個思路的啟發(fā),我又改了下我的代碼:

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

解釋:
1. 使用2進制、8進制、16進制的指示符分別是(b',o', x',X')
2. 所以,"%08b"是把一個十進制數(shù)格式化為一個二進制數(shù),8位寬度,如果位數(shù)小于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

當然,可以直接把這個等式寫成代碼,也可以求得結(jié)果,但是我們用位操作更快:

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

當然還有其他解法,都是一般的數(shù)組拼接,我就不羅列了。

從十進制數(shù)字轉(zhuǎn)換為IP地址的方法,就是一個逆向過程,我也不多寫了。

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

到此,關(guān)于“IP轉(zhuǎn)換器的使用”的學(xué)習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習,快去試試吧!若想繼續(xù)學(xué)習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI