#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. discuz回贴通知插件实现-页面嵌入点(钩子)

    1.如何保证主题被回复时业务代码被执行. 2.获得主题,主题发布者,贴子等信息. 3.discuz发送email邮件.   discuz使用嵌入点(钩子)来处理代码的执行时机. 当用户开启插件开发者模 ...

  2. 菜刀连接webshell

    中国菜刀,一个非常好用而又强大的webshell,它可不是用来切菜的做饭的道具哦,是一款专业的网站管理软件,大小只有300多KB,真是小巧实用啊!不过被不法分子利用到,就是一个黑站的利器了.我记得以前 ...

  3. mvcpager 表单提交时无法获取pageindex的值

    1.将分布页包含到form中 2.在分布页中新增一个表单hidden元素,name为pageIndex(与控制器中的pageindex保持一尺),将后台获取到的pageindex值通过viewbag初 ...

  4. [BAT]cmd命令之 cd /d %~dp0

    cd /d %~dp0是什么意思啊?批处理文件中的一条语句意思是 更改当前目录为批处理本身的目录 有些晕吧?不急,我举例 比如你有个批处理a.bat在D:\qq文件夹下 a.bat内容为 cd /d ...

  5. 创建DB2数据库联合对象

    db2 1.db2 =>update dbm cfg using Federated YES 2. db2 =>db2stop force3. db2 =>db2start 4.创建 ...

  6. Python 的stat 模块

    #!/usr/bin/env python#-*- encoding:UTF-8 -*- import os,time,stat fileStats = os.stat ( 'test.txt' )  ...

  7. kallinux2.0安装网易云音乐

    安装 dpkg -i netease-cloud-music_1.0.0_amd64.kali2.0(yagami).deb apt-get -f install dpkg -i netease-cl ...

  8. 20155212 2016-2017-2 《Java程序设计》第7周学习总结

    20155212 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 Chapter13 取得系统时间的方法之一是System.currentTimeMillis ...

  9. Java多线程-并发协作(生产者消费者模型)

    对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...

  10. (转)Entity Framework Extended Library (EF扩展类库,支持批量更新、删除、合并多个查询等)

    转自:http://www.cnblogs.com/jinzhao/archive/2013/05/31/3108755.html 今天乍一看,园子里居然没有关于这个类库的文章,实在是意外毕竟已经有很 ...