#include <stdio.h>
#include <string.h>
#include <math.h> //ipv4地址转换
int ipv4_to_i(const char *ip, unsigned int *ipv4_addr)
{
char str_ip_index[] = {'\0'};
unsigned int ip_int, ip_add = ;
unsigned int j = , a = , i = ; for(i = ; i <= strlen(ip); i++) {
if (ip[i] == '\0' || ip[i] == '.') {
ip_int = atoi(str_ip_index);
if (ip_int > )
return ; ip_add += (ip_int * pow(, a));
a--;
memset(str_ip_index, , sizeof(str_ip_index)); j = ;
continue;
} str_ip_index[j] = ip[i];
j++;
} *ipv4_addr = ip_add; return ;
} /* ipv6 无符号整型数组转化为字符串 */
void ipv6_to_str(char *addr_str, unsigned int ipv6_addr[])
{
/* ipv6地址128位,数组ip维数默认为4 */
/* 输出格式为: A:B:C:D:E:F:G:H. */
int i;
unsigned short msw, lsw;
char *addr_str_end_ptr; addr_str[] = '\0';
addr_str_end_ptr = addr_str;
for (i = ; i < ; i++)
{
msw = ipv6_addr[i] >> ;
lsw = ipv6_addr[i] & 0x0000ffff;
addr_str_end_ptr += sprintf(addr_str_end_ptr, "%X:%X:", msw, lsw);
}
*(addr_str_end_ptr - ) = '\0';
} char * string_white_space_trim(char *str)
{
/* 移除字符串中空格 */
int index;
int new_index;
int str_length; str_length = strlen(str); for (index = , new_index = ; index < str_length; index++)
{
if (!isspace((unsigned char)str[index]))
{
str[new_index] = str[index];
new_index++;
}
} str[new_index] = '\0'; return str;
} int string_char_count(const char *string, char character)
{
/* 计算字符串中,给定字符的数量 */
int i;
int str_length;
int count = ; str_length = strlen(string);
for (i = ; i < str_length; i++)
if (string[i] == character)
count++; return count;
} int ipv6_address_field_type_get(const char * field_str)
{
/* 判断ipv6地址域类型 */
int i = ;
int length;
int type;
unsigned int ipv4_addr; /* 通过长度判断 */
/* 16进制数字域: 1-4 */
/* "::"域:0 */
/* ipv4地址域: 7-15 */ length = strlen(field_str); if ( == length)
{
type = ;
}
else if (length <= )
{
// 确保每个数字为16进制
for (i = ; i < length; i++)
if (!isxdigit((unsigned char)field_str[i]))
return -;
type = ;
}
else if((length >= ) && (length <= ))
{
//确保是有效的ipv4地址
if (ipv4_to_i(field_str, &ipv4_addr))
type = ;
else
type = -;
}
else
{
type = -;
} return type;
} int ipv6_to_i(const char *addr_str, int length, unsigned int ipv6_addr_ptr[])
{
/***************************************************************************/
/* 功能:解析ipv6地址字符串,转换为无符号整形,存入4个无符号整形的一维数组 */
/* ipv6地址 128位,prefix length: */
/* - 64 for EUI-64 addresses */
/* - 128 for non-EUI-64 addresses */
/* 输入:ipv6地址字符串,地址位数,默认为128位 */
/* 输出:返回解析成功或失败;指向4个无符号整形的一维数组的指针 */
/****************************************************************************/ char addr_str_copy[];
int i, num_fields;
//unsigned int *ret_addr_ptr;
unsigned short int addr_field_arr[];
int addr_index;
char *ith_field; // 指向地址当前域
int ith_field_type; // 地址域类型
char *next_field;
int double_colon_field_index = -; // 字符串地址中"::"的位置
unsigned int ipv4_address; // ipv6地址中的ipv4部分
unsigned int msw, lsw;
int error = ; //复制一份,以便操作
strcpy(addr_str_copy, addr_str); // 移除字符串中的空格字符
string_white_space_trim(addr_str_copy); /* IPv6地址可能几种格式: */
/* 1) 2006:DB8:2A0:2F3B:34:E35:45:1 用16进制表示每个域的值(16位) */
/* 2) 2006:DB8::E34:1 , "::" 代表0,且只能出现一次 */
/* 3) 2002:9D36:1:2:0:5EFE:192.168.12.9 带有ipv4地址 */ // 计算字符串中冒号,字符串中地址域数比冒号多一个
num_fields = string_char_count(addr_str_copy, ':') + ; // 域最大数量为length/16 + 2
// 如 ::0:0:0:0:0:0:0:0.
if (num_fields > ((length >> ) + ))
{
ipv6_addr_ptr = NULL;
return ;
} // 初始化
ith_field = addr_str_copy; for (i = , addr_index = ; i < num_fields; i++)
{
// 获得下一个域的指针
next_field = strchr(ith_field, ':'); /* 若当前是最后一个域, next_field 是 NULL */
/* 否则,替换':'为'\0', 字符串可以结束,从而ith_field指向当前域 */
/* next_field指向下一个域头部 */
if (NULL != next_field)
{
*next_field = '\0';
++next_field;
} // 发现这个域的类型
ith_field_type = ipv6_address_field_type_get(ith_field); switch (ith_field_type)
{
case :
// 域类型为16进制表示 if (addr_index >= (length >> ))
{
error = ;
break;
}
// 字符串转换为16进制
addr_field_arr[addr_index] = (unsigned short)strtoul(ith_field, NULL, );
++addr_index;
break; case :
// 域类型为 "::" // 若出现在字符串的开头或结尾,忽略
if (( == i) || (i == num_fields - ))
{
break;
} // 若出现大于一次,错误
if (double_colon_field_index != -)
{
error = ;
break;
} // 记下位置
double_colon_field_index = addr_index; break; case :
// 域类型为ipv4地址 // 确保在地址中还有两个未设置的域
if (addr_index >= )
{
error = ;
break;
} // ipv4地址解析
ipv4_to_i(ith_field, &ipv4_address); // 存储高16位
addr_field_arr[addr_index] = (unsigned short)(ipv4_address >> ); // 存储低16位
addr_field_arr[addr_index + ] = (unsigned short)(ipv4_address & 0x0000ffff); addr_index += ; break;
default:
error = ;
break;
} if (error)
{
ipv6_addr_ptr = NULL;
return ;
} ith_field = next_field;
} // 计算的域不是8,并且没有"::",错误
if ((addr_index != (length >> )) && (- == double_colon_field_index))
{
ipv6_addr_ptr = NULL;
return ;
} if ((addr_index != (length >> )) && (- != double_colon_field_index))
{
// 设置相应"::"对应addr_field_arr中位置为0
memmove(addr_field_arr + (double_colon_field_index + (length >> ) - addr_index),
addr_field_arr + double_colon_field_index, (addr_index - double_colon_field_index) * );
memset(addr_field_arr + double_colon_field_index, , ((length >> ) - addr_index) * );
} for (i = ; i < ; i++)
{
msw = addr_field_arr[ * i];
lsw = addr_field_arr[ * i + ]; (ipv6_addr_ptr)[i] = (msw << | lsw);
} return ;
} int main(void)
{
char addr[] = {""};
unsigned int ip_v4 = ;
unsigned int ipv6[] = {, , , };
unsigned int ipv61[] = {, , , }; char *ipv6_str1 = "1:2:3:4:5:6:7:8";
char *ipv6_str2 = "1:2:3:4:5:6:7:8::";
char *ipv6_str3 = "::1:2:3:4:5:6:7:8";
char *ipv6_str4 = "1:2:3:4:5:6:192.168.1.100";
char *ipv6_str5 = "1:2::5:6:7:8";
char *ipv6_str6 = "1::3:4:5:6:7:8";
char *ipv6_str7 = "1::4:5:6:7:8";
char *ipv6_str8 = "1::8"; unsigned int ipv6_addr[];
unsigned int ipv4_addr;
unsigned int ipv6_addr_sum = ;
int flag;
int i; ipv6_to_str(addr, ipv61);
printf("ipv6: %s\n", addr); flag = ipv4_to_i("192.168.1.100", &ipv4_addr);
if (flag)
{
printf("ipv4_addr: %u\n", ipv4_addr);
} flag = ipv6_to_i(ipv6_str1, , ipv6_addr);
if (flag)
{
for (i = ; i < ; i++)
{
printf("ipv6_addr: %u\n", ipv6_addr[i]);
ipv6_addr_sum += ipv6_addr[i];
} printf("ipv6_addr_sum: %u\n", ipv6_addr_sum);
} return ;
}

编译运行:

[root@node1 ~]# gcc ddd.c -lm
[root@node1 ~]# ./a.out
ipv6: 1:2:3:4:5:6:7:8
ipv4_addr: 3232235876
ipv6_addr: 65538
ipv6_addr: 196612
ipv6_addr: 327686
ipv6_addr: 458760
ipv6_addr_sum: 1048597

C语言 IPv6 十六进制 转 十进制的更多相关文章

  1. Go语言十六进制转十进制

    Go语言十六进制转十进制 代码Demo import ( "fmt" "strconv" "testing" ) func Test_1(t ...

  2. C语言的本质(2)——二进制、八进制、十六进制与十进制

    二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二",由18世纪德国数理哲 ...

  3. [No000071]C# 进制转换(二进制、十六进制、十进制互转)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. C# 进制转换(二进制、十六进制、十进制互转)

    原文地址:https://www.cnblogs.com/icebutterfly/p/8884023.html C# 进制转换(二进制.十六进制.十进制互转)由于二进制数在C#中无法直接表示,所以所 ...

  5. C# 进制转换(二进制、十六进制、十进制互转) 转载 https://www.cnblogs.com/icebutterfly/p/8884023.html

    C# 进制转换(二进制.十六进制.十进制互转)由于二进制数在C#中无法直接表示,所以所有二进制数都用一个字符串来表示例如: 二进制: 1010 表示为 字符串:"1010" int ...

  6. 十六进制转十进制函数_C编程

    /**************************十六进制转十进制函数**************************//*函数原型:uint htd(uint a)/*函数功能:十六进制转十 ...

  7. UTC格式转换 & 十六进制换算为十进制

    UTC格式转换成北京时间格式: /// <summary> /// UTC格式与datatime的转换 /// </summary> /// <param name=&q ...

  8. BCD码、十六进制与十进制互转

    在做嵌入式软件的设计中,常常会遇到十六进制.BCD码与十进制之间的转换,近期做M1卡的应用中,涉及了大量的十六进制.BCD码与十进制之间的转换.通过对BCD码.十六进制 权的理解,轻松的实现了他们之间 ...

  9. C 语言实例 - 二进制与十进制相互转换

    C 语言实例 - 二进制与十进制相互转换 C 语言实例 C 语言实例 二进制转与十进制相互转换. 实例 - 二进制转换为十进制 #include <stdio.h> #include &l ...

随机推荐

  1. linux 下 php 安装 ZeroMQ 扩展

    一.下载安装源码包 ZeroMQ源码包下载地址: http://zeromq.org/area:download 如:zeromq-4.1.4.tar.gz   php的zmq扩展源码包 https: ...

  2. tp中引入js、css、img的问题

    方法一: 直接把js.css.img放到网站公共目录/Public/下. 然后直接在模板文件中使用__PUBLIC__进行替换. 方法二: 在模块配置文件config.php中配置指定的路径,如下: ...

  3. iframe父窗口和子窗口之间的调用

    1>父窗口获取子窗口 js方法 document.getElementById('if1').contentWindow.document: window.frames["if1&qu ...

  4. 【转】Hadoop HDFS分布式环境搭建

    原文地址  http://blog.sina.com.cn/s/blog_7060fb5a0101cson.html Hadoop HDFS分布式环境搭建 最近选择给大家介绍Hadoop HDFS系统 ...

  5. 【转】Repository 返回 IQueryable?还是 IEnumerable?

    这是一个很有意思的问题,我们一步一步来探讨,首先需要明确两个概念(来自 MSDN): IQueryable:提供对未指定数据类型的特定数据源的查询进行计算的功能. IEnumerable:公开枚举数, ...

  6. code1213 解的个数 扩展欧几里得

    很不错的题,加深了我对exgcd的理解 (以前我认为做题就是搜索.dp...原来数学也很重要) 理解了几个小时,终于明白了.但我什么都不打算写. 看代码吧: #include<iostream& ...

  7. 21个ui设计技巧,让你的设计不落伍

    1.功能性极简主义 不少移动端APP和网站开始基于极简主义设计风来设计,而极简主义本身并非关注所有的信息,而是通过减少非关键信息来突出特定的内容,它是有着极强的功能性和偏向的.它有着如下的特征: ・简 ...

  8. 2018.09.25 bzoj1856: [Scoi2010]字符串(组合数学)

    传送门 如果有n==m的条件就是卡特兰数. 但现在n不一定等于m. 我们可以考虑用求卡特兰数一样的方法来求答案. 我们知道有一种求卡特兰数的方法是转到二维平面求答案. 这道题就可以这样做. 我们将这个 ...

  9. Linux命令:ps

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  10. 程序员面试50题(1)—查找最小的k个元素[算法]

    题目:输入n个整数,输出其中最小的k个.例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数 ...