反向DNS查找是使用Internet IP地址来查找域名。例如,如果您在浏览器中键入74.125.200.106,它将自动重定向到google.in。
如何实现反向DNS查找缓存?以下是缓存中所需的操作:
- 将IP地址添加到缓存中的“ URL映射”。
- 查找给定IP地址的URL。
一种解决方案是使用哈希。
在本文中,将讨论基于Trie的解决方案。基于Trie的解决方案的一个优势是,对于Trie,最坏情况的上限是O(1),对于哈希,最好的平均情况下时间复杂度是O(1)。同样,使用Trie,我们可以实现前缀搜索(为IP地址的公共前缀查找所有url)。
Trie的一般缺点是需要大量内存,这在这里不是主要问题,因为此处的字母大小仅为11。从’0’到’9’的数字需要十个字符,而对于点(’。’)则需要一个字符。
这个想法是将IP地址存储在Trie节点中,而在最后一个节点中,我们存储相应的域名。以下是C++中的C样式实现。
CPP
// C based program to implement reverse DNS lookup
#include
#include
#include
// There are atmost 11 different chars in a valid IP address
#define CHARS 11
// Maximum length of a valid IP address
#define MAX 50
// A utility function to find index of child for a given character 'c'
int getIndex(char c) { return (c == '.')? 10: (c - '0'); }
// A utility function to find character for a given child index.
char getCharFromIndex(int i) { return (i== 10)? '.' : ('0' + i); }
// Trie Node.
struct trieNode
{
bool isLeaf;
char *URL;
struct trieNode *child[CHARS];
};
// Function to create a new trie node.
struct trieNode *newTrieNode(void)
{
struct trieNode *newNode = new trieNode;
newNode->isLeaf = false;
newNode->URL = NULL;
for (int i=0; ichild[i] = NULL;
return newNode;
}
// This method inserts an ip address and the corresponding
// domain name in the trie. The last node in Trie contains the URL.
void insert(struct trieNode *root, char *ipAdd, char *URL)
{
// Length of the ip address
int len = strlen(ipAdd);
struct trieNode *pCrawl = root;
// Traversing over the length of the ip address.
for (int level=0; levelchild[index])
pCrawl->child[index] = newTrieNode();
// Move to the child
pCrawl = pCrawl->child[index];
}
//Below needs to be carried out for the last node.
//Save the corresponding URL of the ip address in the
//last node of trie.
pCrawl->isLeaf = true;
pCrawl->URL = new char[strlen(URL) + 1];
strcpy(pCrawl->URL, URL);
}
// This function returns URL if given IP address is present in DNS cache.
// Else returns NULL
char *searchDNSCache(struct trieNode *root, char *ipAdd)
{
// Root node of trie.
struct trieNode *pCrawl = root;
int len = strlen(ipAdd);
// Traversal over the length of ip address.
for (int level=0; levelchild[index])
return NULL;
pCrawl = pCrawl->child[index];
}
// If we find the last node for a given ip address, print the URL.
if (pCrawl!=NULL && pCrawl->isLeaf)
return pCrawl->URL;
return NULL;
}
//Driver function.
int main()
{
/* Change third ipAddress for validation */
char ipAdd[][MAX] = {"107.108.11.123", "107.109.123.255",
"74.125.200.106"};
char URL[][50] = {"www.samsung.com", "www.samsung.net",
"www.google.in"};
int n = sizeof(ipAdd)/sizeof(ipAdd[0]);
struct trieNode *root = newTrieNode();
// Inserts all the ip address and their corresponding
// domain name after ip address validation.
for (int i=0; i %s",
ip, res_url);
else
printf("Reverse DNS look up not resolved in cache ");
return 0;
}
Java
/* http://www.geeksforgeeks.org/implement-reverse-dns-look-cache/ */
import java.util.HashMap;
import java.util.Map;
public class ReverseDNSLookup
{
public void insert(TrieNode node, String[] ipAdd, String[] urls)
{
for(int i=0;i child;
String url;
TrieNode()
{
this.child = new HashMap<>();
}
public String toString()
{
return child.toString()+" : "+url;
}
}
// This code is contributed by Akhilesh Singla
Python3
# Trie Node
class TrieNode:
def __init__(self):
self.child = [None] * 11
self.url = None
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def getIndex(self, c):
# For the . (dot) in IP address, we'll use the 10th index in child list
return 10 if c == '.' else int(c)
def insert(self, ip, domain):
cur = self.root
n = len(ip)
for level in range(n):
# We'll use the digits of IP address to form the trie structure
idx = self.getIndex(ip[level])
if cur.child[idx] is None:
# Create a new trie node if not available for a particular digit
# and assign to the respective index
cur.child[idx] = TrieNode()
cur = cur.child[idx]
# At the end, we'll map the domain name and mark the end node
cur.url = domain
cur.is_end = True
def search_domain(self, ip):
cur = self.root
n = len(ip)
# Traverse through the trie structure with all digits in ip address
for level in range(n):
idx = self.getIndex(ip[level])
if cur.child[idx] is None:
return "Domain name not found"
cur = cur.child[idx]
# Returns the url when all the digits in ip found
if cur and cur.url:
return cur.url
return "Domain name not found"
# Driver Code
ip = ["107.108.11.123", "107.109.123.255", "74.125.200.106"]
domain = ["www.samsung.com", "www.samsung.net", "www.google.co.in"]
trie = Trie()
for idx in range(len(ip)):
trie.insert(ip[idx], domain[idx])
print(trie.search_domain("107.109.123.255"))
print(trie.search_domain("107.109.123.245"))
# This code is contributed by Abhilash Pujari
输出:
Reverse DNS look up resolved in cache:
107.108.11.123 --> www.samsung.com
输出:
Reverse DNS look up resolved in cache:
107.108.11.123 --> www.samsung.com
注意,上面的Trie实现假定给定IP地址不包含{‘0’,’1’,…..’9’,’。’}以外的字符。如果用户提供的无效IP地址包含其他一些字符怎么办?可以通过在将输入的IP地址插入到Trie中之前验证输入的IP地址来解决此问题。我们可以将此处讨论的方法用于IP地址验证。
Java实现如下:
Java
/* http://www.geeksforgeeks.org/implement-reverse-dns-look-cache/ */
import java.util.HashMap;
import java.util.Map;
public class ReverseDNSLookup
{
public void insert(TrieNode node, String[] ipAdd, String[] urls)
{
for(int i=0;i child;
String url;
TrieNode()
{
this.child = new HashMap<>();
}
public String toString()
{
return child.toString()+" : "+url;
}
}
// This code is contributed by Akhilesh Singla
输出:
74.125.200.106 : www.google.in
107.109.123.245 : No url associated/Invalid IP address
Python3实现:
Python3
# Trie Node
class TrieNode:
def __init__(self):
self.child = [None] * 11
self.url = None
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def getIndex(self, c):
# For the . (dot) in IP address, we'll use the 10th index in child list
return 10 if c == '.' else int(c)
def insert(self, ip, domain):
cur = self.root
n = len(ip)
for level in range(n):
# We'll use the digits of IP address to form the trie structure
idx = self.getIndex(ip[level])
if cur.child[idx] is None:
# Create a new trie node if not available for a particular digit
# and assign to the respective index
cur.child[idx] = TrieNode()
cur = cur.child[idx]
# At the end, we'll map the domain name and mark the end node
cur.url = domain
cur.is_end = True
def search_domain(self, ip):
cur = self.root
n = len(ip)
# Traverse through the trie structure with all digits in ip address
for level in range(n):
idx = self.getIndex(ip[level])
if cur.child[idx] is None:
return "Domain name not found"
cur = cur.child[idx]
# Returns the url when all the digits in ip found
if cur and cur.url:
return cur.url
return "Domain name not found"
# Driver Code
ip = ["107.108.11.123", "107.109.123.255", "74.125.200.106"]
domain = ["www.samsung.com", "www.samsung.net", "www.google.co.in"]
trie = Trie()
for idx in range(len(ip)):
trie.insert(ip[idx], domain[idx])
print(trie.search_domain("107.109.123.255"))
print(trie.search_domain("107.109.123.245"))
# This code is contributed by Abhilash Pujari
输出:
www.samsung.net
Domain name not found