この方法はマスク範囲1〜31でのみ機能します。あなたが保存できるネットワークアドレスの単純なプロパティを使用して、完全な範囲のための高速なバイナリ検索を行うことが(0-32)あなたはおそらく64ビットの整数の内側にマスクとアドレスを保存する必要があります(例のために。このstd::vector<unsigned long long> networkAddrs(bases.size());
のように... networkAddrs[i] = (bases[i] << 32) + masks[i];
)
ネットワークアドレスの未使用ビットの内部にあるマスクを使用して、単一の32ビット整数の中にマスクとベースを格納し、そのベクトルをソートしてバイナリ検索を行うことができます。このような何か:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
unsigned int insertMask(unsigned int ip, unsigned int mask)
{
unsigned int longMask = (~0) << (32-mask);
unsigned int netAdd = (ip & longMask) + (1 << (31-mask));
return netAdd;
}
bool isInNetwork(std::vector<unsigned int>& nAs, unsigned int ip, unsigned int mask)
{
unsigned int netAdd = insertMask(ip, mask);
auto pos = std::lower_bound(nAs.begin(), nAs.end(), netAdd);
return pos != nAs.end() && *pos == netAdd;
}
int main()
{
std::vector<unsigned int> bases {
(192u<<24)+(168<<16)+(0<<8)+(0)
,190u<<24
,191u<<24
,192u<<24
,193u<<24
,194u<<24
,195u<<24
,196u<<24
};
std::vector<unsigned int> masks {24,24,24,24,24,16,8,4};
std::vector<unsigned int> networkAddrs(bases.size());
for(int i=0; i<bases.size(); i++)
{
networkAddrs[i] = insertMask(bases[i], masks[i]);
}
std::sort (networkAddrs.begin(), networkAddrs.end());
unsigned int ip_addr = (192u<<24)+(168<<16)+(0<<8)+(17);
unsigned int mask = 24;
if(isInNetwork(networkAddrs, ip_addr, mask))
std::cout << "TRUE";
else
std::cout << "FALSE";
std::cout << '\n';
}
EDIT:
のIP XXX.XXX.YYY.YYYため
/16
0B XXXXXXXX XXXXXXXX 10000000 00000000
用: は、私はこのようなようなコードマスクに方法を変更IP(XXX.XXX.0xXY.YYY/12)
0B XXXXXXXX XXXXXXXX XXXX1000 00000000
プレフィックスの総数があまり多くない場合は、最上位ビットから最下位ビットまでを表す単純なバイナリツリーで十分です。 –
私は多数のプレフィックスでも効率を保証しなければならないのは心配です。 – user3613919
64bit unsigned intとして保存できますか? – Logman