inet_aton是把ip地址轉爲數字的函數,記憶小技巧,inet表示網絡相關,在c語言中a習慣性表明字符串,to就是轉換的,n表明數字,aton就是字符串轉數字,同理inet_ntoa是把數字轉換爲字符串IP。java
SELECT inet_aton('192.168.0.1') as ip2num,inet_ntoa(3232235521) as num2ip FROM DUAL;
假設IP地址爲:a.b.c.d算法
那麼對應的num爲:sql
a * 256^3 + b * 256^2 + c * 256^1 + d * 256^0 # 等價於 a * 2^24 + b * 2^16 + c * 2^8 + d
爲何這麼轉換呢?網絡
由於ip地址原本就是4字節,每個字節最大值就是255,因此徹底可使用一個4字節的無符號整型來存放。函數
2的冪運算就至關於移位運算,因此2^24就至關於向左移了24位,a一個字節最大11111111, 移位運算以後:code
11111111 00000000 00000000 00000000
同理,其餘位也同樣。orm
注意:必須是無符號整型,由於有符合的整型除了最高位符號位,只有31位,放不下blog
這樣也方便還原,從數字到ip取對應字節轉換爲數字就能夠了。ip
public static long ipToNum(String ip) { String[] parts = ip.split("\\."); assert parts.length == 4; Long num = 0L; for(int i=0;i<parts.length;i++){ num += (Long.parseLong(parts[i]) << (24 - i * 8)); } return num; }
java由於沒有無符號整型,因此使用long,下面給一個更加直觀的實現。字符串
public static long ipToNum(String ip) { String[] parts = ip.split("\\."); assert parts.length == 4; return (Long.parseLong(parts[0]) << 24) + (Long.parseLong(parts[1]) << 16) + (Long.parseLong(parts[2]) << 8) + Long.parseLong(parts[3]); }
public static String numToIP(long ipNum){ String result = String.format("%d.%d.%d.%d", ipNum >>> 24, (ipNum & 0x00FFFFFF) >>> 16, (ipNum & 0x0000FFFF) >>> 8, ipNum & 0x000000FF); return result; }
數字到ip須要注意的是,須要清除高位,由於低位在移位以後已經被丟棄了,因此不須要清除。
清除位利用的技巧是&運算中0與任何位進行&都爲0。