面試題:請用代碼實現ip地址與int之間互換?

作者:dadiyang 
公眾號:Java面試那些事兒


面試官:Ipv4地址可以轉為Long類型的數字知道吧?你寫一下這個轉換的代碼。

對計算機基礎逐漸模糊的小黃一臉懵逼,畢竟工作中很少會用到,只記得ip地址和整數是可以相互轉換的,但是從來沒有自己實現過。於是在大腦中飛速計算。過了一會,思路出現了:ip 地址分為四段,每段都是 0~255 之間的數,每段可以用 8 位來裝下它,4x8=32位,也就是可以將ip地址轉為 32 位的整數。咦?面試官居然讓轉成 Long,但是 Long 有 64 位啊!一個 int 就搞定了,為什麼要轉為Long呢?但是自己沒實現過,心裡沒底,再一犯嘀咕,然後回答不出來。面試沒通過。

之後小黃一直心心念念這個問題,回來立馬自己寫了代碼實現了一下,果然是 int 就搞定了,之前的思路一點都沒錯!

面試有時考驗的不只是技術,還有自信心。

解決

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 地址本身就是一個32位的二進制數,只是通常被以 a.b.c.d 的形式表示而已。原理在這,解決也就容易得很了。

那麼為什麼要將 ip 轉為數字呢?其實就是時間換空間的一種方式。String類型的ip佔用 7 (如0.0.0.0) 到 15 (如 255.255.255.255) 個字節,而 int 只需要 4 個字節!

那麼要如何轉換呢?

ip 字符串轉換為 int

我們用位運算,只需 7 行代碼,即可實現。

面試題:請用代碼實現ip地址與int之間互換?


有一個技巧,就是 或運算。就是將每段的 int 值左移到恰當的位置後跟保存結果的 int 值進行或運算。

以 255.255.255.255 這個地址為例,上面的或運算過程如下。

面試題:請用代碼實現ip地址與int之間互換?

那麼如何將 int 再轉為字符串的表示法呢?

int 位轉換為 ip 字符串

其實也很簡單,思路是一樣的,將 int 值的 32 位分為 4 個 8 位數字,然後這 4 個 8 位的數字用 0~255 的數字進行表示,用點號分隔即可。我們也基於位運算,7 行代碼即可實現。

面試題:請用代碼實現ip地址與int之間互換?

這裡使用與運算來取每次處理的 ip 片段。取最高的 8 位時,涉及到符號的處理,因此在將每段 8 位轉為 0~255 的數字時必須使用無符號右移運算,否則最後處理的部分因為符號問題會不準確。

測試一下

我們拿一組 ip 地址來測試一下。

面試題:請用代碼實現ip地址與int之間互換?

輸出結果如下。

用於測試的ip地址: 0.0.0.0, int表示: 0, 二進制: 0, 轉回String: 0.0.0.0,與測試 ip 地址是否相等: true
用於測試的ip地址: 127.0.0.1, int表示: 16777343, 二進制: 1000000000000000001111111, 轉回String: 127.0.0.1,與測試 ip 地址是否相等: true
用於測試的ip地址: 192.168.1.1, int表示: 16885952, 二進制: 1000000011010100011000000, 轉回String: 192.168.1.1,與測試 ip 地址是否相等: true

用於測試的ip地址: 255.0.0.255, int表示: -16776961, 二進制: 1111111111111111111111111111111111111111000000000000000011111111, 轉回String: 255.0.0.255,與測試 ip 地址是否相等: true
用於測試的ip地址: 255.255.255.255, int表示: -1, 二進制: 1111111111111111111111111111111111111111111111111111111111111111, 轉回String: 255.255.255.255,與測試 ip 地址是否相等: true

注意,這裡相互轉換的算法是配套的,不同的轉換算法計算的 int 值可能會不一樣,因為雖然都是處理 ip 的 4 個部分,但是它們的結合順序可以不一樣,因此以怎樣的順序搭配轉為 int,就應該以相同的順序解析為 String。


分享到:


相關文章: