1. 程式人生 > >Trie樹的應用:查詢IP地址的ISP

Trie樹的應用:查詢IP地址的ISP

1. 問題描述

給定一個IP地址,如何查詢其所屬的ISP,如:中國移動(ChinaMobile),中國電信(ChinaTelecom),中國鐵通(ChinaTietong)?現有ISP的IP地址區段可供下載,比如中國移動的IP地址段

103.20.112.0/22
103.21.176.0/22
111.0.0.0/20
112.0.0.0/10
117.128.0.0/10
120.192.0.0/10
183.192.0.0/10
211.103.0.0/17
211.136.0.0/14
211.140.0.0/15
211.142.0.0/17
211.142.128.0/17
211.143.0.0/16
218.200.0.0/14
218.204.0.0/15
218.206.0.0/15
221.130.0.0/15
221.176.0.0/13
223.112.0.0/14
223.116.0.0/15
223.120.0.0/13
223.64.0.0/11
223.96.0.0/12
36.128.0.0/10
39.128.0.0/10

上述網路地址是CIDR記法:IP地址/網路id位數,其中IP地址分為兩部分

  • 網路id
  • 主機id

比如,192.168.23.35/21,其子網掩碼為11111111 11111111 11111000 00000000即255.255.248.0,網路ID:192.168.00010111。IP地址103.20.112.168與地址段103.20.112.0/22前22位相匹配,則此IP地址屬於中國移動。

2. Trie樹實現查詢

Trie樹使用公共字首,降低查詢時間,減小了儲存空間。為了構建Trie樹,將IP地址二進位制化(32位的二進位制)。用於查詢的Trie樹一棵二叉樹,滿足以下性質:

  • 非葉子節點的左孩子節點為0,右孩子節點為1;
  • 葉子節點儲存IP地址所對應的ISP。

Trie樹的Java實現

/*
 * Trie樹,用於儲存、檢索ip地址
 * 葉子節點標記為ip地址對應的ISP
 */
public class TrieTree {
    private Node root = null;   //根節點
    
    /*二叉樹的節點*/
    private static class Node {
        String element;  //非葉子節點為空 葉子節點標記為ISP
        Node[] children; //左孩子節點為0 右孩子節點為1
        
        public Node() {
            element = "";
            children = new Node[2];
            for (int i = 0; i < children.length; i++) {
                children[i] = null;
            }
        }
    }

    public TrieTree() {
        root = new Node();
    }   

    /*插入ip地址*/
    public void insert(Node root, String ipAddress, String isp) {
        if(ipAddress.length() > 32) {
            System.out.println("ip地址處理錯誤");
        } else {
            Node crawl = root;
            for(int i=0; i<ipAddress.length(); i++) {
                int index = (int) ipAddress.charAt(i) - '0';
                if(crawl.children[index] == null) {
                    crawl.children[index] = new Node();
                }
                crawl = crawl.children[index];              
            }
            crawl.element = isp;
        }
    }
    
    public void insert(String ipAddress, String isp) {
        insert(root, ipAddress, isp);
    }
    
    /*
     * 檢索ip地址,返回其所對應的ISP
     * 若不在Trie樹中,則返回null
     * */
    public String search(String binaryIP) {
        Node crawl = root;
        for(int i = 0; crawl.element.length() == 0; i++) {
            int index = (int) binaryIP.charAt(i) - '0';
            if(crawl.children[index] == null) {
                return null;
            }
            crawl = crawl.children[index];
        }
        return crawl.element;
    }
}

IP地址格式化

下面的IPFormat給出兩個方法,實現

  • 將IP地址轉變成二進位制
  • 從CIDR記法的IP地址中得到網路ID部分
/*
 * IP地址CIDR記法:network.host/size
 * 比如:103.20.112.0/22
 * 功能:將IP地址轉換成其network地址
 */

public class IPFormat {
    /*將ip地址轉換成32位的二進位制*/
    public static String toBinaryNumber(String ipAddress) {
        String[] octetArray = ipAddress.split("\\.");
        String binaryNumber = "";
        for(String str: octetArray) {
            int octet = Integer.parseInt(str, 10);
            String binaryOctet = Integer.toBinaryString(octet);
            int bolength = binaryOctet.length();
            if(bolength < 8) {
                for (int i = 0; i < 8 - bolength; i++) {
                    binaryOctet = '0' + binaryOctet;            //補前導0
                }
            }
            binaryNumber += (binaryOctet);
        }
        return binaryNumber;
    }
    
    /*獲取network地址部分*/
    public static String getNetworkAddress(String cidrAddress) {
        String[] cidrArray = cidrAddress.split("/");
        String binaryNumber = toBinaryNumber(cidrArray[0]);
        int size = Integer.parseInt(cidrArray[1]);
        return binaryNumber.substring(0, size);
    }
    
    /*main方法用於測試*/
    public static void main(String[] args) {
        String ip = "103.20.112.0/20";
        String bn = getNetworkAddress(ip);
        System.out.println(bn);
    }
}

相關推薦

Trie應用查詢IP地址ISP

1. 問題描述 給定一個IP地址,如何查詢其所屬的ISP,如:中國移動(ChinaMobile),中國電信(ChinaTelecom),中國鐵通(ChinaTietong)?現有ISP的IP地址區段可供下載,比如中國移動的IP地址段 103.20.112.0/22 103.21.176.0/22 111.0

字首( 又名TRIE、單詞查詢、字典) 和 字尾(Suffix)

概念 字首樹:將海量字串儲存在一棵樹中。 字尾樹:將一個字串分解成一棵樹。 字首樹 節點的結構體: struct trieNode { bool isEnd;//是否可以作為字串的終結節點 trieNode *child[26]; } 字首樹:

【VB.NET】利用純真IP數據庫查詢IP地址及信息

ipv targe expr ext 不支持 分享 回收 sys 部分 幾年前從某個博客抄來的,已經忘記原地址了,如果需要C#版的,可以在博客園搜到吧。我因為自己用,所以轉換為了VBNET代碼,而且也放置了很久,今天無意間翻出來,就分享給大家吧。 首先,先下載 純真數據庫

【VB.NET】通過 IPIP.NET 數據庫來查詢IP地址

exit utf try 付費 utf8 地址 .com href 使用方法 上一次介紹了利用純真數據庫查詢IP地址詳細信息的方法。然而純真數據庫是由網友反饋所提供的,很多數據描述並不準確,所以我上網找了一些其他的IP數據庫,最後就找到了 ipip.net 這個網站所提供的

利用python實現批量查詢ip地址歸屬地址

proc shadow 手動 color sys copy lis rip image 今天需要查詢nginx訪問的客戶端ip是否和調度一樣!先是用shell把文件中的ip截取出來: python腳本如下:(哈哈,新手寫的很草率)#!/usr/bin/env#-- codi

練習-爬取某圖片及查詢IP地址

AI for AR 信息 enc 查詢 ext text 建立 爬取某圖片的程序: #圖片爬取全代碼 import requests import os url=‘http://img0.dili360.com/rw9/ga/M01/4A/3D/wKgBy1p6qJ6AL

python學習-使用requests模塊查詢ip地址

IP地址查詢思路是,使用requests模塊調用阿裏的ip接口查詢ip歸屬地關於requests模塊的使用,可以查詢相關文檔,很強大,本次不做描述#!/usr/bin/python #coding=utf-8 import requests def checkip(ip): URL = 

python學習-使用ip138查詢ip地址歸屬地

ip查詢#!/usr/bin/python #coding:utf-8 import urllib import re import sys def ISIP(s): return len([i for i in s.split('.') if (0<= int(i)<

Trie 應用於統計和排序

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

線段應用掃描線

掃描線暴力解決的話時間和空間複雜度往往是不夠的。 所以,掃描線也就成了線段樹很大的應用。 具體原理解釋(寫得很好): https://blog.csdn.net/u013480600/article/details/22548393 https://blog.csdn.net/z

Java查詢IP地址所在地

package ip; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; im

[Xcode10 實際操作]八、網絡與多線程-(11)使用同步Post方式查詢IP地址信息

定位 created 錯誤代碼 可能 輸出日誌 receive override n) 導航 本文將演示如何通過Post請求,同步獲取IP地址信息。 一旦發送同步請求,程序將停止用戶交互,直至服務器返回數據。 在項目導航區,打開視圖控制器的代碼文件【ViewContro

[Xcode10 實際操作]八、網路與多執行緒-(11)使用同步Post方式查詢IP地址資訊

本文將演示如何通過Post請求,同步獲取IP地址資訊。 一旦傳送同步請求,程式將停止使用者互動,直至伺服器返回資料。 在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】 1 import UIKit 2 3 class ViewController:

[Xcode10 實際操作]八、網路與多執行緒-(12)使用非同步Post方式查詢IP地址資訊

本文將演示如何通過Post請求,非同步獲取IP地址資訊。 非同步請求與同步請求相比,不會阻塞程式的主執行緒,而會建立一個新的執行緒。 在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】 1 import UIKit 2 3 class ViewCont

正則表示式練習IP地址進行排序

import java.util.TreeSet; public class RegexTest { public static void main(String[] args) { Method2();//2.對IP進行排序 } //2.對IP進行排序 priv

Python3爬蟲查詢IP地址歸屬地

文章目錄測試環境安裝環境原始碼測試 測試環境 Python3.6.4 依賴: requests == 2.19.1 bs4 == 4.6.3 lxml == 4.2.5 安裝環境 pip3 inst

Trie,加快單詞查詢效率

為了提高我的單詞查詢的速度,我拜讀了@Rshcaroline的程式碼,發現trie樹是一個很好解決這個問題的方法 Trie樹,又叫字典樹、字首樹(Prefix Tree)、單詞查詢樹 或 鍵樹,是一種多叉樹結構 Trie樹的基本性質: 根節點不包含字元,除根節

PHP 純真IP資料庫查詢IP地址資訊

先下載一個純真IP資料庫, 安裝完整後,將qqwry.dat即IP資料庫放在專案拓展位置,例: 呼叫: //use net\IpLocation; include 'IpLocation.php'; $ip = '219.152.56.66'; $ipadress = new IpL

trie實現模糊查詢

        在上一篇部落格裡簡單的說了一下標準trie樹的建立,本來說要做一個小型詞典來用試試,結果這段時間有事就一直耽誤到現在,今天抽了一點時間看看,首先我想到的是在我們輸入某些單詞的前面幾個字母的時候下面的提示,那是trie樹的模糊查詢,便想了想去實現這個功能。  

win10系統電腦IP地址怎麼查詢,教程來啦,Windows10系統如何查詢ip地址

電腦ip地址是我們經常需要用到的,ip在電腦中的應用也是尤為的顯著,ip就想我們日常生活中的身份證一般,想要連結有網路配置的電腦,那麼就必須要有一個唯一的ip地址,只有固定的ip才能夠,讓我們享受快捷的網路。以下便是如何在Windows10系統中查詢ip地址。 在Windows