字符串的地址_面试题:我有一批IPv6地址,你帮我想个办法来存储?
之前寫了一篇《面試題:請用代碼實現(xiàn)ip地址與int之間互換?》,有讀者評論問到 IPv6 的轉(zhuǎn)換方法,于是抽時間也自己實現(xiàn)了一下。
面試官:我有一批IPv6地址,你幫我想個辦法來存儲?
我:啊。。。
面試官:……嗯。好的。回去等通知吧。
# 什么是IPv6?
IPv6是英文“Internet Protocol Version 6”(互聯(lián)網(wǎng)協(xié)議第6版)的縮寫,是互聯(lián)網(wǎng)工程任務(wù)組(IETF)設(shè)計的用于替代IPv4的下一代IP協(xié)議,其地址數(shù)量號稱可以為全世界的每一粒沙子編上一個地址。IPv6的地址長度為128位,它有3種表示方法,分別是冒分十六進制表示法、0位壓縮表示法、內(nèi)嵌IPv4地址表示法。
# 思考
首先,IPv6 的地址長度為 128 位,而 Java 中沒有 128 位的原生數(shù)字,int 為 32 位,long 是 64 位,因此若要將 IPv6 地址直接轉(zhuǎn)為 long, 則會丟掉一半的信息,這肯定是不能接受的。
因此,解決方式有兩種思路。第一,使用 BigInteger;第二,將 IPv6 地址的 128 位拆分為兩個 64 位的地址,即可存到兩個 long 整數(shù)組成的數(shù)組中。本文采用后者,即將 IPv6 地址轉(zhuǎn)換為 long 數(shù)組。
# 實現(xiàn)篇
另外,為簡便起見,我們只考慮冒分十六進制表示法的情況,即完整的ip地址,如 0:0:0:0:0:0:0:0,0位壓縮表示法和內(nèi)嵌 IPv4 地址表示法暫不考慮。
將IPv6地址轉(zhuǎn)為long數(shù)組,代碼如下。
將long數(shù)組轉(zhuǎn)為IPv6地址,代碼如下。
小試牛刀。
輸出結(jié)果如下所示。
本次測試 ipv6 地址: FFFF:FFFF:7654:FEDA:1245:BA98:3210:4562, 轉(zhuǎn)為 long 數(shù)組: [-82623535708635137, 4999613583766065733], 再轉(zhuǎn)回 ipv6 字符串: ffff:ffff:7654:feda:1245:ba98:3210:4562, 是否與原字符串相等: true本次測試 ipv6 地址: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF, 轉(zhuǎn)為 long 數(shù)組: [-1, -1], 再轉(zhuǎn)回 ipv6 字符串: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff, 是否與原字符串相等: true本次測試 ipv6 地址: 7654:0:FFFF:7654:562:222:7622:0, 轉(zhuǎn)為 long 數(shù)組: [8526721465200965204, 129888436749666], 再轉(zhuǎn)回 ipv6 字符串: 7654:0:ffff:7654:562:222:7622:0, 是否與原字符串相等: true本次測試 ipv6 地址: 0:0:0:0:0:0:0:0, 轉(zhuǎn)為 long 數(shù)組: [0, 0], 再轉(zhuǎn)回 ipv6 字符串: 0:0:0:0:0:0:0:0, 是否與原字符串相等: true好了,我在這里拋磚引玉了,實現(xiàn)了IPv6的轉(zhuǎn)換,相信聰明的你一定知道接下來該怎么存儲這個long數(shù)組了。
其實,現(xiàn)在很多數(shù)據(jù)庫,都內(nèi)置了專門的函數(shù)來轉(zhuǎn)換IP地址。比如從mysql5.6開始,可以直接使用inet6_aton()函數(shù)來轉(zhuǎn)換,見下圖。
總之,直接保存字符串,雖然可讀性最好,但浪費了不少的存儲空間;轉(zhuǎn)換后再存儲,雖然節(jié)約了存儲空間,但可讀性較差。該如何取舍,還是根據(jù)具體的應(yīng)用場景來決定。
如果你有更好的方案,歡迎在留言區(qū)一起探討。
總結(jié)
以上是生活随笔為你收集整理的字符串的地址_面试题:我有一批IPv6地址,你帮我想个办法来存储?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【LeetCode笔记】143. 重排链
- 下一篇: sqlserver2000给账户授予所有