majianyu
11/1/2017 - 6:31 AM

ip_python

ip

import socket
import struct
import pandas as pd
from src import conf


def ip2i(ip: str) -> int:
    # 转换IP段
    try:
        return socket.ntohl(struct.unpack("I", socket.inet_aton(ip))[0])
    except:
        return None

def i2ip(num: int) -> str:
    # long 转换为 ip
    try:
        return socket.inet_ntoa(struct.pack('!L', num))
    except:
        return None

def loadIpk(path: str) -> list:
    # 加载IP库
    iplib = []
    with open(path) as ip_file:
        for line in ip_file:
            data = {}
            data['s_ip'] = int(line.split(',')[0])
            data['e_ip'] = int(line.split(',')[1])
            data['r_id'] = line.split(',')[2].strip()
            iplib.append(data)
    return iplib


def loadRegionDict(path: str) -> pd.DataFrame:
    # 加载region_dict, return DataFrame格式
    df = pd.read_csv(path, dtype={'code': 'str', 'f_code': 'str'})
    return df


def getRegionCode(iplibPath: str):
    # 使用闭包处理多版本 iplib
    iplib = loadIpk(iplibPath)

    def getRegionCode2(ip: str):
        ipNum = ip2i(ip)
        # 使用二分法,根据ip段判断地域Code
        if ipNum is None:
            return None
        end = len(iplib)
        start = 0
        while True:
            mid = (start + end) // 2
            mid_dict = iplib[mid]
            if ipNum < mid_dict['s_ip']:
                end = mid - 1
            elif ipNum > mid_dict['e_ip']:
                start = mid + 1
            else:
                return mid_dict['r_id']
    return getRegionCode2
 def ip2i(ip:str) -> int:
    l = [int(i) for i in ip.split(".")]
    res = 0
    res += l[0] << 24
    res += l[1] << 16
    res += l[2] << 8
    res += l[3]
    return res

def i2ip(n:int) -> str:
    s = []
    for i in range(4):
        s.append(str(n % 256))
        n >>= 8
    return ".".join(s[::-1])