社区
数据结构与算法
帖子详情
IPV6路由算法时遇到一个处理IPV6地址的问题
zw24127
2008-10-31 12:34:15
使用的C++,想对一个IPV6地址(128位,采用冒号分16进制)字符串进行处理,变成一个int数组中(存放16进制),不知道有没有什么好的方法?欢迎大家讨论!
如:IPV6地址:2002:AD72::33b2 转换成int数组为:{0x2002,0xAD72,0x0000,0x0000,0x0000,0x0000,0x0000,0x33B2}
或者有没有什么对IPV6地址好的处理方法,路由查询是按前缀长度进行匹配的
...全文
387
4
打赏
收藏
IPV6路由算法时遇到一个处理IPV6地址的问题
使用的C++,想对一个IPV6地址(128位,采用冒号分16进制)字符串进行处理,变成一个int数组中(存放16进制),不知道有没有什么好的方法?欢迎大家讨论! 如:IPV6地址:2002:AD72::33b2 转换成int数组为:{0x2002,0xAD72,0x0000,0x0000,0x0000,0x0000,0x0000,0x33B2} 或者有没有什么对IPV6地址好的处理方法,路由查询是按前缀长度进行匹配的
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
zw24127
2008-11-30
打赏
举报
回复
//通过前缀长度找到该前缀长度在树中的位置下标
int findIndex(int t){
int i=0;
for(i=0;i<treeLen;i++){
if(tree[i].len==t){
return i;
}
}
return i;
}
//对IPV6地址进行转化,从一个字符串转化为一个整形数组,路由中的地址只取其前缀即可
int* convertToInt(char* address,int len){
int reLen=(int)((len-1)/16)+1;
int *re=new int[reLen];
char ad[40];
int firstM=0;
int mNum=0;//:的个数
int mm=-1;//::在字符串数组中的下标
bool b=false;//用于判断中:还是::
int i;
int length=strlen(address);
for(i=0;i<length;i++){//遍历字符串(IPV6地址)数组,确定mNum和mm的值
if(address[i]==':'){
if(b==true){
mm=i;
}
b=true;
mNum++;
}else{
b=false;
}
ad[i]=address[i];
}
ad[i]='\0';
if(mm!=-1){//有::即0地址压缩时,添加未输入的0
if(mm==(length-1)){
mNum--;
ad[mm]='\0';
}
if(mm==1){//::在开始位置
ad[0]='0';
int k=i;
for(;k>=mm;k--){
ad[k+1]=ad[k];
}
}
int j=2*(8-mNum)-1;
for(;i>=mm;i--){
ad[i+j]=ad[i];
}
for(i=0;i<j;i++){
if((i%2)==0){
ad[mm+i]='0';
}else{
ad[mm+i]=':';
}
}
}
length=strlen(ad);//添加0后的IPV6地址所占字符串的长度
char p[5];//IPV6地址采用冒号分16进制,每段最多4位
int pI=0;//p所用到的位数
int tempI=0;
int indexRe=0;
for(i=0;i<length;i++){
if(ad[i]==':'){
p[pI]='\0';
istringstream in(p);
in >> hex >>tempI;//16进制字符串转化成10进制
re[indexRe]=tempI;//转化成16进制
indexRe++;
if(indexRe==reLen){
break;
}
pI=0;
}else{
p[pI]=ad[i];
pI++;
}
}
p[pI]='\0';
istringstream in(p);
in >> hex >>tempI;//16进制字符串转化成10进制
re[indexRe]=tempI;//转化成16进制
return re;
}
//产生一个Marker
struct Marker* makeMarker(int len,int *a){
struct Marker *temp=new struct Marker();
temp->prefix=new int[(len-1)/16+1];
for(int i=0;i<((len-1)/16+1);i++){
temp->prefix[i]=a[i];
}
temp->next=NULL;
return temp;
}
//建立二分查找树
void build(int start,int end){
if(start<end){
int mid=(start+end)/2;
build(mid+1,end);//建立后面的树,即后面的marker
int temp=(mid+1+end)/2;
while(temp!=(mid+1)){//mid的marker是由它的右子树和它右子的往左一直到底所有marker在mid所在前缀长度的合集
checkNode(mid,temp);
temp=(temp+mid)/2;
}
checkNode(mid,temp);
build(start,mid-1);
}
}
//把temp结点加到mid的Marker表中去
void checkNode(int mid,int temp){
if(tree[temp].marker!=NULL){//temp的Marker加到mid的Marker表中去
struct Marker *m=tree[temp].marker;
struct Marker *mMid=tree[mid].marker;
while(m!=NULL){
mMid=tree[mid].marker;
if(mMid==NULL){
mMid=makeMarker(tree[mid].len,m->prefix);
tree[mid].marker=mMid;
}else{
while(mMid!=NULL){
if(isEquils(mMid->prefix,m->prefix,tree[mid].len)==true){
break;
}
mMid=mMid->next;
}
if(mMid==NULL){
mMid=makeMarker(tree[mid].len,m->prefix);
mMid->next=tree[mid].marker;
tree[mid].marker=mMid;
}
}
m=m->next;
}
}
for(int i=0;i<tree[temp].startLen;i++){
struct Node *m=&node[tree[temp].start[i]];
struct Marker *mMid=tree[mid].marker;
if(mMid==NULL){
mMid=makeMarker(tree[mid].len,m->prefix);
tree[mid].marker=mMid;
}else{
while(mMid!=NULL){
if(isEquils(mMid->prefix,m->prefix,tree[mid].len)==true){
break;
}
mMid=mMid->next;
}
if(mMid==NULL){
mMid=makeMarker(tree[mid].len,m->prefix);
mMid->next=tree[mid].marker;
tree[mid].marker=mMid;
}
}
}
}
//给定两个前缀长度在给定长度的时候判断是否相等
bool isEquils(int *a,int *b,int len){
int temp1=len/16;
int temp2=16-len%16;
int i;
for(i=0;i<temp1;i++){
if(a[i]!=b[i]){
return false;
}
}
if(i==temp1&&i!=0){
return true;
}
int a1=a[i]&((0xffff)<<temp2);
int a2=b[i]&((0xffff)<<temp2);
if(a1!=a2){
return false;
}
return true;
}
//依次进行查询
int query(int *qAddress,int start,int end){
int re=-1,i;
if(start>=end){//叶子结点无marker表
for(i=0;i<tree[start].startLen;i++){
if(isEquils(node[tree[start].start[i]].prefix,qAddress,tree[start].len)==true){
re=tree[start].start[i];//记住在node中的下标
break;
}
}
}else{
int mid=(start+end)/2;
for(i=0;i<tree[mid].startLen;i++){
if(isEquils(node[tree[mid].start[i]].prefix,qAddress,tree[mid].len)==true){
re=tree[mid].start[i];
break;
}
}
struct Marker *mk=tree[mid].marker;
while(mk!=NULL){
if(isEquils(mk->prefix,qAddress,tree[mid].len)==true){//marker表中前缀相同
break;
}
mk=mk->next;
}
int reB=-1;
if(mk!=NULL){//marker表中前缀相同,去右子查查看
reB=query(qAddress,mid+1,end);
}
if(reB==re){//即都为-1,那么只能在左子树中查找
re=query(qAddress,start,mid-1);
}else{
re=(reB==-1) ? re:reB;
}
}
return re;
}
//输出树,检查树是否构造出来时用的
void outTree(){
cout<<"----------------------------------------------------------"<<endl;
for(int i=0;i<treeLen;i++){
cout<<"tree "<<i<<"\t"<<endl;
cout<<"len="<<tree[i].len<<"\t startLen="<<tree[i].startLen<<endl;
for(int j=0;j<tree[i].startLen;j++){cout<<tree[i].start[j]<<"\t如下:";
// for(int k=0;k<(tree[i].len-1)/16+1;k++){
// cout<<node[tree[i].start[j]].prefix[k]<<"\t";
// }
cout<<node[tree[i].start[j]].nextHop<<endl;
}
cout<<endl;
cout<<"marker如下:"<<endl;
if(tree[i].marker==NULL){
cout<<"NO";
}else{
struct Marker *m=tree[i].marker;
while(m!=NULL){
for(int k=0;k<(tree[i].len-1)/16+1;k++){
cout<<m->prefix[k]<<"\t";
}
cout<<endl;
m=m->next;
}
}
cout<<endl;}
cout<<"----------------------------------------------------------"<<endl;
}
void output(){
// outTree();
int s;
for(int i=0;i<m;i++){
s=query(convertToInt((char*)queryIPAddress[i].c_str(),128),0,treeLen-1);
cout<<queryIPAddress[i]<<" ";
if(s>=0){
cout<<node[s].nextHop;
}else{
cout<<"No Route";
}
cout<<endl;
}
}
};
void main(){
//使用课件上给定的数据测试通过
RouterQuery rq=RouterQuery();
rq.start();
}
zw24127
2008-11-30
打赏
举报
回复
已解决,贴个我的算法:
------------------------------------------
#include<iostream>
#include<cstring>
#include<string>
#include<sstream>
#include<fstream>
//auth challenge email:yongzwl@qq.com
using namespace std;
//二分查找树中,每个要判断结点的Marker数据结构
struct Marker{
int *prefix;//存放IPV6地址的前缀
struct Marker *next;
};
//路由中每一条路由信息的数据结构
struct Node{
int *prefix;//IPV6地址的前缀
char nextHop;//路由记录中的下一跳
};
//二分查找树的数据结构
struct BTree{
int len;//前缀长度
int *start;//在长度在排序好的路由信息数组中的开始下标
int startLen;//前缀长度为len的IP地址的个数
struct Marker *marker;
};
class RouterQuery{
private:
int n,m,treeLen;//n路由的表总共的个数,m要查询的IPV6地址的个数,treeLen是tree的长度即无重复前缀长度的个数
string *queryIPAddress;//记录要查询的IPV6地址
struct Node *node;//记录所有输入的路由结点
struct BTree *tree;//二分查找树
public:
//构造函数
RouterQuery(){
n=0;
m=0;
}
//析构函数,释放指针空间
~RouterQuery(){
// delete queryIPAddress;
// delete node;
// delete tree;
}
//入口
void start(){
incc();
// input();//输入
build(0,treeLen-1);//建树
output();//输出
}
//data.txt
void incc(){
ifstream in("data.txt");
char ch;
in>>n;
//cout<<n;
in.get(ch);
//cout<<ch;
node=new struct Node[n];
//前缀长度数组
int *len=new int[n];
//输入的一个IPV6地址
char *address=new char[40];
int i,j;
//用来存储每个前缀长度共有多少个IPV6地址
int *temp=new int[129];
for(i=0;i<129;i++){
temp[i]=0;
}
for(i=0;i<n;i++){
m=0;
in.get(ch);
//cout<<ch;
while((*(address+m)=ch)!='/'){
in.get(ch);
//cout<<ch;
m++;
}
in>>len[i];
//cout<<len[i];
in.get(ch);
//cout<<ch;
in.get(ch);
//cout<<ch;
node[i].nextHop=ch;
*(address+m)='\0';
temp[len[i]]++;
node[i].prefix=convertToInt(address,len[i]);
in.get(ch);
//cout<<ch;
// len[i]=inLen[i];temp[len[i]]++;
// node[i].nextHop=inNextHop[i];
// node[i].prefix=convertToInt(inAddress[i],len[i]);
}
in>>m;
//cout<<m;
in.get(ch);
//cout<<ch;
queryIPAddress=new string[m];
char ttt[40];
for(i=0;i<m;i++){
j=0;
in.get(ch);
//cout<<ch;
while(ch!='\n'){
ttt[j]=ch;
j++;
in.get(ch);
//cout<<ch;
}
ttt[j]='\0';
queryIPAddress[i]=ttt;
// queryIPAddress[i]=qAdd[i];
// cin>>queryIPAddress[i];
}
//前缀长度的个数
int index=0;
//无重复的前缀长度
int *temp1=new int[129];
for(i=0;i<129;i++){
if(temp[i]!=0){
temp1[index]=i;
index++;
}
}
tree=new struct BTree[index];
treeLen=index;
for(i=0;i<index;i++){
tree[i].len=temp1[i];
tree[i].start=new int[temp[temp1[i]]];
tree[i].startLen=0;
tree[i].marker=NULL;
}
for(i=0;i<n;i++){
index=findIndex(len[i]);
tree[index].start[tree[index].startLen]=i;
tree[index].startLen++;
}
delete(address);
delete(temp);
delete(temp1);
delete(len);
}
//protected:
//获取输入数据
void input(){
// char *inAddress[]={"2001:250:f007:31::","2001:250:f007:32::","2001:250:f007::/48","2001:250:f007:31:25::","2001:250:f007:31:ff25::"};
// int inLen[]={64,64,48,72,72};
// char inNextHop[]={'A','B','C','D','E'};
// string qAdd[]={"2001:250:f007:31::200","2001:250:f007:ffff::200","2001:250:fe07::200"};
cin>>n;
node=new struct Node[n];
//前缀长度数组
int *len=new int[n];
//输入的一个IPV6地址
char *address=new char[40];
int i;
//用来存储每个前缀长度共有多少个IPV6地址
int *temp=new int[129];
for(i=0;i<129;i++){
temp[i]=0;
}
for(i=0;i<n;i++){
m=0;
while((*(address+m)=getchar())!='/'){
m++;
}
cin>>len[i];
getchar();
cin>>node[i].nextHop;
*(address+m)='\0';
temp[len[i]]++;
node[i].prefix=convertToInt(address,len[i]);
// len[i]=inLen[i];temp[len[i]]++;
// node[i].nextHop=inNextHop[i];
// node[i].prefix=convertToInt(inAddress[i],len[i]);
}
cin>>m;
queryIPAddress=new string[m];
for(i=0;i<m;i++){
// queryIPAddress[i]=qAdd[i];
cin>>queryIPAddress[i];
}
//前缀长度的个数
int index=0;
//无重复的前缀长度
int *temp1=new int[129];
for(i=0;i<129;i++){
if(temp[i]!=0){
temp1[index]=i;
index++;
}
}
tree=new struct BTree[index];
treeLen=index;
for(i=0;i<index;i++){
tree[i].len=temp1[i];
tree[i].start=new int[temp[temp1[i]]];
tree[i].startLen=0;
tree[i].marker=NULL;
}
for(i=0;i<n;i++){
index=findIndex(len[i]);
tree[index].start[tree[index].startLen]=i;
tree[index].startLen++;
}
delete address;
delete temp;
delete temp1;
delete len;
}
meng_jian
2008-11-26
打赏
举报
回复
关注!!
oo
2008-11-08
打赏
举报
回复
up
IPv6
路由
算法
技术的分析与仿真
通过业务自适应组播
路由
和组播
路由
树的重构的方法来分析
IPv6
报文的QoS组播
路由
算法
,分析了一种基于
IPv6
的QoS(quality of service)控制组播
路由
机制。仿真试验表明,该种
路由
算法
是可行的,能够满足
IPv6
网络对相应QoS的...
IPv6
路由
查找
算法
探究
有关
ipv6
的所有的查找
算法
,软件方法硬件方法等等
基于和树的高速查找和快速增量更新
路由
算法
设计与实现.doc
本论文针对这一
问题
,提出了一种基于Hash和Trie树的
IPv6
高速查找和快速增量更新
路由
算法
的设计与实现方法。
IPv6
地址
的
路由
查找是网络数据传输过程中的关键步骤,传统的
路由
查找
算法
如最长前缀匹配(Longest Prefix...
基于二分查找和Trie的
IPv6
路由
查找
算法
(2012年)
分析基于前缀长度的二分
路由
查找
算法
和基于Trie的
路由
查找
算法
的优缺点,在此基础上提出
一个
改进的
路由
查找
算法
,并给出其在
IPv6
下的实现方案,由于基于前缀长度的二分
路由
查找
算法
扩展性好、查找速度快,而基于Trie...
一种基于ABV的
IPV6
快速
路由
查找
算法
(2006年)
综上所述,《一种基于ABV的
IPV6
快速
路由
查找
算法
》不仅深入分析了
IPv6
路由
结构的特点,还介绍了一系列现有的
IPv6
路由
查找技术,并在此基础上提出了一种基于聚合位向量的快速
路由
查找
算法
。通过详细的性能分析比较,...
数据结构与算法
33,027
社区成员
35,335
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章