多种语言实现IP与Int转换
备注:本文中所有转换均是主机字节序IP地址的转换,需要网络字节序IP地址处理需自行修改代码。 相关资料可参考这里
Shell
- IP转int
#!/bin/bash
IP_ADDR=$1
IP_LIST=${IP_ADDR//./ };
read -a IP_ARRAY <<<${IP_LIST}; # 把点分十进制地址拆成数组(read的-a选项表示把输入 读入到数组, 下标从0开始)
echo $(( ${IP_ARRAY[0]}<<24 | ${IP_ARRAY[1]}<<16 | ${IP_ARRAY[2]}<<8 | ${IP_ARRAY[3]} ));
- Int转IP
#!/bin/bash
N=$1
H1=$(($N & 0x000000ff))
H2=$((($N & 0x0000ff00) >> 8))
L1=$((($N & 0x00ff0000) >> 16))
L2=$((($N & 0xff000000) >> 24))
echo $L2.$L1.$H2.$H1
- 子网掩码长度转换地址表示
#!/bin/bash
declare -i FULL_MASK_INT=4294967295
declare -i MASK_LEN=$1
declare -i LEFT_MOVE="32 - ${MASK_LEN}"
declare -i N="${FULL_MASK_INT} << ${LEFT_MOVE}"
declare -i H1="$N & 0x000000ff"
declare -i H2="($N & 0x0000ff00) >> 8"
declare -i L1="($N & 0x00ff0000) >> 16"
declare -i L2="($N & 0xff000000) >> 24"
echo "$L2.$L1.$H2.$H1"
- 子网掩码转换成长度
awk '$0>0&&$0<33{for(i=0;i++<4;){if(i<=int($0/8))printf i<4?"255.":"255\n";else if (i==int($0/8)+1 && $0%8){for(n=0;n++<$0%8;)a+=2**(8-n);printf i<4?a".":a"\n"}else printf i<4?0".":0"\n"}}' <<<16
- 根据IP地址和子网掩码转换CIDR表示的地址
ip1=$(echo $1 | awk -F "." '{print $1}')
ip2=$(echo $1 | awk -F "." '{print $2}')
ip3=$(echo $1 | awk -F "." '{print $3}')
ip4=$(echo $1 | awk -F "." '{print $4}')
mask1=$(echo $2 | awk -F "." '{print $1}')
mask2=$(echo $2 | awk -F "." '{print $2}')
mask3=$(echo $2 | awk -F "." '{print $3}')
mask4=$(echo $2 | awk -F "." '{print $4}')
gate1=$(($ip1&$mask1))
gate2=$(($ip2&$mask2))
gate3=$(($ip3&$mask3))
gate4=$(($ip4&$mask4))
len=$(echo "$2" | awk -F. '{l=0;for(i=1;i<=NF;i++){s=0;for(j=7;j>=0;j--){s+=2**j;if(s==$i){l+=8-j}}}print l}')
echo "$gate1.$gate2.$gate3.$gate4/$len"
- 根据CIDR地址计算起始IP地址
off=0;
data=0;
for part in $(echo $IP|sed 's/[^0-9]/ /g'); do
if [ $off -lt 4 ]; then
data=$(($data * 256 + $part));
else
mask=$(((1 << (32 - $part)) - 1));
fi;
off=$(($off + 1))
done;
hostval=$(($data & $mask));
netval=$(($data - $hostval + 1))
echo $(($netval >> 24)).$((($netval >> 16) % 256)).$((($netval >> 8) % 256)).$((($netval >> 0) % 256))
C语言
- IP转int
unsigned int ip2int(char* ipStr){
unsigned int ipInt = 0;
int tokenInt = 0;
char * token;
token = strtok(ipStr, ".");
int i = 3;
while(token != NULL){
tokenInt = atoi(token);
ipInt += tokenInt * pow(256, i);
token = strtok(NULL, ".");
i--;
}
return ipInt;
}
- Int转IP(注意考虑内存泄漏,用出参形式构成函数)
static void int2ip(uint32_t ipInt, char * dstStr) {
int tokenInt = 0;
uint32_t leftValue = ipInt;
char *ipStr = (char *)malloc(256);
memset(ipStr, 0, 256);
char *ipToken = (char *)malloc(256);
for(int i = 0; i < 4; i++){
int temp = pow(256, 3 - i);
tokenInt = leftValue / temp;
leftValue %= temp;
snprintf(ipToken, TOKEN_LEN, "%d", tokenInt);
if(i != 3){
strcat(ipToken, ".");
}
strncat(ipStr, ipToken, strlen(ipToken));
}
strcpy(dstStr, ipStr);
free(ipStr);
ipStr = NULL;
free(ipToken);
ipToken = NULL;
}
C++
- IP转Int
void split(const string& s, vector<string>& sv, const char flag = ' ') {
sv.clear();
istringstream iss(s);
string temp;
while (getline(iss, temp, flag)) {
sv.push_back(temp);
}
return;
}
unsigned int ip2int(string& ip){
vector<string> ipSecs;
split(ip, ipSecs, '.');
vector<string>::iterator it = ipSecs.begin();
unsigned int ipInt = 0;
int i = 3;
stringstream ss;
for (; it != ipSecs.end(); it++){
int ipSecInt = 0;
ss << *it;
ss >> ipSecInt;
//must ss.clear()
ss.clear();
ipInt += ipSecInt * pow(256,i);
i--;
}
return ipInt;
}
- Int转IP
string int2ip(unsigned int ipInt){
string ip;
string ipSec;
stringstream ss;
unsigned int leftValue = ipInt;
cout<<leftValue<<endl;
for(int i = 3; i >= 0; i--){
int temp = pow(256, i);
int sectionValue = leftValue / temp;
leftValue %= temp;
ss << sectionValue;
ss >> ipSec;
ss.clear();
if(i != 0){
ipSec.append(".");
}
ip.append(ipSec);
ipSec.clear();
}
return ip;
}
Lua
- IP转Int
function ip2int(ip)
local t = {}
for num in string.gmatch(ip, "%d+") do
t[#t + 1] = tonumber( num )
end
local ret = (((t[1]*256+t[2]))*256+t[3])*256+t[4]
return ret
end
- Int转IP
local bit = require("bit")
function int2ip( ip )
local n1 = bit.band(bit.rshift(ip, 24), 0x000000FF)
local n2 = bit.band(bit.rshift(ip, 16), 0x000000FF)
local n3 = bit.band(bit.rshift(ip, 8), 0x000000FF)
local n4 = bit.band(bit.rshift(ip, 0), 0x000000FF)
return string.format("%d.%d.%d.%d", n1, n2, n3, n4)
end