ipv6字符串地址转换为16个unsigned char.

练手的,可能转换过程麻烦了一点.初步验证了下,功能应该是没有问题的.
ipv6地址格式介绍:

http://zh.wikipedia.org/wiki/IPv6
#include <iostream >
#include<cstdio >
#include <cstring >
#include <cassert >
using namespace std;


#define H(x) ((unsigned char *) & (x) )[0]
#define L(x) ((unsigned char *) & (x) )[1]

//char * abbr, ipv6字符串
//unsigned char * ret_buff,返回和引用的buff
//return 传入buff的指针
unsigned char * ipv6_to_u (char * abbr,unsigned char * ret_buff){
char buff[40]={0};
int ipv6_int[8]={0};
int two_colon = -1;
int ipv6_char_len = strlen(abbr);

assert(abbr!=NULL && ret_buff!=NULL);
//查找是否有缩写的情况
// two_colon=abbr.find_first_of("::");
if( (ipv6_char_len<3 )
||(abbr[0] ==':' && abbr[1]!=':')
||(abbr[ipv6_char_len-1]==':' && abbr[ipv6_char_len-2]!=':' ) ){
printf(" Invalid ipv6 addr[%s]! ",abbr);
return 0;
}

for(int i=0,j=0;i<ipv6_char_len;i++){
if(abbr[i]!=':'){
j++;
}else{
j=0;
}
if(abbr[i] == ':' && abbr[i+1] == ':'){
if(two_colon == -1){
two_colon =i;
}else{
printf(" Invalid ipv6 addr[%s],:: appears once! ",abbr);
return 0;
}
}
if(j>4){
printf(" Invalid ipv6 addr[%s], every 2Bytes not more than 4 chars! ",abbr);
return 0;
}
}

//处理缩写的情况.
if(two_colon>=0){
int pos = 0;
int start_colon_num = 0;
int end_colon_num = 0;
int add_colon_num = 0;
//找:: 前面:的个数
for(int i=0;i<two_colon;i++){
if(abbr[i] == ':' ){
start_colon_num ++;
}
}
//找:: 后面:的个数
for(int i=two_colon+2;i<ipv6_char_len;i++){
if(abbr[i] == ':' ){
end_colon_num ++;
}
}
//计算需要添加 "0:" 的个数,总共只有7个冒号.
add_colon_num = 7 - start_colon_num - end_colon_num ;
for(pos =0;pos <two_colon;pos ++){
buff[pos] = abbr[pos];
}

while(add_colon_num>0){
buff[pos++] =':';
add_colon_num --;
if(add_colon_num!=0)
buff[pos++] ='0';
}
for(int i=two_colon+2; i<ipv6_char_len; ){
buff[pos++] = abbr[i++];
}
buff[pos] = '';
}//end
else //标准格式
if(two_colon == -1){
strncpy(buff,abbr,ipv6_char_len);
}

// printf("%s ",buff);
int colon_num = sscanf (buff,"%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x",&ipv6_int[0],&ipv6_int[1],&ipv6_int[2],&ipv6_int[3],
&ipv6_int[4],&ipv6_int[5],&ipv6_int[6],&ipv6_int[7]);
if(colon_num<=0 || (two_colon==-1 && colon_num !=8 ) ){
printf("Invalid ipv6 addr [%s] format! ",abbr);
return 0 ;
}
#if 0
printf("colon_num:%d,two_colon:%d ",colon_num,two_colon);
for(int k=0;k<8;k++){
printf("%3d,",ipv6_int[k]);
}
#endif
//获取标准化后的值
for(int i=0;i<8;i++){
ret_buff[i*2] = L(ipv6_int[i]);
ret_buff[i*2+1] = H(ipv6_int[i]);

}
return ret_buff;


}

void print_ipv6_buff(const char * ipv6_str, unsigned char *ipv6_std_buf){
if(ipv6_str==NULL || ipv6_std_buf==NULL)
return;
printf("ipv6 string[%s]: ",ipv6_str);
for(int i=0;i<15;i++){
printf("%02d-",i);
}
printf("15 ");
for(int i=0;i<16;i++){
printf("%02x ",ipv6_std_buf[i]);
}
printf(" ");
}

int main(int argc,char ** argv)
{
unsigned char ipv6_long_buf[16]={0};

if(argc!=2){
printf("Useage:prog "ipv6_addr" ");
/*
char ipv6_l[] = "fe80:1:0:0:c05:4fc6:bb33:9d8f";

char ipv6_s1[] = "fe80:1::c05:4fc6:bb33:9d8f";
char ipv6_s2[] = "::c05:4fc6:bb33:9d8f";
char ipv6_s3[] = "f8:1::c05:0:0:9d8f";
char ipv6_s4[] = "fe80:1:c05:4fc6:bb33:9d8f::";

char ipv6_s5[] = "fe80::1::fc6:bb33:9d8f::";
char ipv6_s6[] = "fe80::::fc6:bb33:9d8f::";
char ipv6_s7[] = "fe80:fc6:bb33:9d8f:";
char ipv6_s8[] = ":fe80:fc6:bb33:9d8f";
//std
print_ipv6_buff(ipv6_l,ipv6_to_u (ipv6_l,ipv6_long_buf));
//abbr
print_ipv6_buff(ipv6_s1,ipv6_to_u (ipv6_s1,ipv6_long_buf));
print_ipv6_buff(ipv6_s2,ipv6_to_u (ipv6_s2,ipv6_long_buf));
print_ipv6_buff(ipv6_s3,ipv6_to_u (ipv6_s3,ipv6_long_buf));
print_ipv6_buff(ipv6_s4,ipv6_to_u (ipv6_s4,ipv6_long_buf));
//error
print_ipv6_buff(ipv6_s5,ipv6_to_u (ipv6_s5,ipv6_long_buf));
print_ipv6_buff(ipv6_s6,ipv6_to_u (ipv6_s6,ipv6_long_buf));
print_ipv6_buff(ipv6_s7,ipv6_to_u (ipv6_s7,ipv6_long_buf));
print_ipv6_buff(ipv6_s8,ipv6_to_u (ipv6_s8,ipv6_long_buf));
*/
}else{
print_ipv6_buff(argv[1],ipv6_to_u (argv[1],ipv6_long_buf));
}
return 0;
}

运行截图:
~/programming/ipv6test$ ./ip "aaa1:aaa2:aaa3:aaa4:aaa5:aaa6:aaa7:aaa8"
ipv6 string[aaa1:aaa2:aaa3:aaa4:aaa5:aaa6:aaa7:aaa8]:
00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15
aa a1 aa a2 aa a3 aa a4 aa a5 aa a6 aa a7 aa a8
| 291个评论