根据IP地址查出对应城市

来源:互联网 发布:手机麻将透视软件 编辑:程序博客网 时间:2024/04/29 17:43
package com.jd.train.service.util;import com.jd.common.util.StringUtils;import com.jd.train.manager.util.impl.HttpClientUtilManagerImpl;import org.apache.log4j.Logger;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.DocumentHelper;import org.dom4j.Element;import javax.servlet.http.HttpServletRequest;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.RandomAccessFile;public class IPParser {    private final Logger log = Logger.getLogger(IPParser.class);    private String url; //ip查询请求地址    private String dbPath; //本地IP数据库地址    private String country, localStr;    private long IPN;    private int recordCount, countryFlag;    private long rangE, rangB, offSet, startIP, endIP, firstStartIP,lastStartIP, endIPOff;    private RandomAccessFile fis;    private byte[] buff;    private long B2L(byte[] b) {        long ret = 0;        for (int i = 0; i < b.length; i++) {            long t = 1L;            for (int j = 0; j < i; j++)                t = t * 256L;            ret += ((b[i] < 0) ? 256 + b[i] : b[i]) * t;        }        return ret;    }    private long ipToInt(String ip) {        String[] arr = ip.split("\\.");        long ret = 0;        for (int i = 0; i < arr.length; i++) {            long l = 1;            for (int j = 0; j < i; j++)                l *= 256;            try {                ret += Long.parseLong(arr[arr.length - i - 1]) * l;            } catch (Exception e) {                ret += 0;            }        }        return ret;    }    private void seek(String ip) throws Exception {        IPN = ipToInt(ip);        fis = new RandomAccessFile(dbPath, "r");        buff = new byte[4];        fis.seek(0);        fis.read(buff);        firstStartIP = B2L(buff);        fis.read(buff);        lastStartIP = B2L(buff);        recordCount = (int) ((lastStartIP - firstStartIP) / 7);        if (recordCount <= 1) {            localStr = country = "未知";            throw new Exception();        }        rangB = 0;        rangE = recordCount;        long RecNo;        do {            RecNo = (rangB + rangE) / 2;            getStartIP(RecNo);            if (IPN == startIP) {                rangB = RecNo;                break;            }            if (IPN > startIP)                rangB = RecNo;            else                rangE = RecNo;        } while (rangB < rangE - 1);        getStartIP(rangB);        getEndIP();        getCountry(IPN);        fis.close();    }    private String getFlagStr(long OffSet) throws IOException {        int flag = 0;        do {            fis.seek(OffSet);            buff = new byte[1];            fis.read(buff);            flag = (buff[0] < 0) ? 256 + buff[0] : buff[0];            if (flag == 1 || flag == 2) {                buff = new byte[3];                fis.read(buff);                if (flag == 2) {                    countryFlag = 2;                    endIPOff = OffSet - 4;                }                OffSet = B2L(buff);            } else                break;        } while (true);        if (OffSet < 12) {            return "";        } else {            fis.seek(OffSet);            return getStr();        }    }    private String getStr() throws IOException {        long l = fis.length();        ByteArrayOutputStream byteout = new ByteArrayOutputStream();        byte c = fis.readByte();        do {            byteout.write(c);            c = fis.readByte();        } while (c != 0 && fis.getFilePointer() < l);        return byteout.toString();    }    private void getCountry(long ip) throws IOException {        if (countryFlag == 1 || countryFlag == 2) {            country = getFlagStr(endIPOff + 4);            if (countryFlag == 1) {                localStr = getFlagStr(fis.getFilePointer());                if (IPN >= ipToInt("255.255.255.0")                        && IPN <= ipToInt("255.255.255.255")) {                    localStr = getFlagStr(endIPOff + 21);                    country = getFlagStr(endIPOff + 12);                }            } else {                localStr = getFlagStr(endIPOff + 8);            }        } else {            country = getFlagStr(endIPOff + 4);            localStr = getFlagStr(fis.getFilePointer());        }    }    private long getEndIP() throws IOException {        fis.seek(endIPOff);        buff = new byte[4];        fis.read(buff);        endIP = B2L(buff);        buff = new byte[1];        fis.read(buff);        countryFlag = (buff[0] < 0) ? 256 + buff[0] : buff[0];        return endIP;    }    private long getStartIP(long RecNo) throws IOException {        offSet = firstStartIP + RecNo * 7;        fis.seek(offSet);        buff = new byte[4];        fis.read(buff);        startIP = B2L(buff);        buff = new byte[3];        fis.read(buff);        endIPOff = B2L(buff);        return startIP;    }    private String getUserIp(HttpServletRequest request) {        String ip = CodesUtil.getIpAddr(request);        if (ip != null && ip.indexOf(",") > 0) {            log.info("取到客户多个ip1====================" + ip);            String[] arr = ip.split(",");            ip = arr[arr.length - 1].trim();//有多个ip时取最后一个ip            log.info("取到客户多个ip2====================" + ip);        }        return ip;    }    private String findCity(HttpServletRequest request , String ipStr) {        if(null == request && StringUtils.isEmpty(ipStr)){            log.info("IPParser,findIpAddr(), request and ip is empty !");            return null;        }        String ip = ipStr;        if(request != null){            ip = getUserIp(request);        }        if(StringUtils.isEmpty(ip)){            log.info("IPParser,findIpAddr(), ip is empty !");            return null;        }        String result;        String location;        try {            seek(ip.trim());        } catch (Exception e) {            log.error("IPParser,findIpAddr() error ! " + e);        }        location = country;        //查不到1        if (StringUtils.isEmpty(location)) {            log.info("IPParser,findIpAddr(), location is empty ! Trying remote interface ...");            location = findIpAddrRemote(ip);            if (StringUtils.isEmpty(location)) {                log.info("IPParser,findIpAddr(), location is empty !");                return null;            }        }        //查不到2        location = location.trim();        if (location.length() == 0) {            log.info("IPParser,findIpAddr(), location length is 0 ! Trying remote interface ...");            location = findIpAddrRemote(ip);            if (StringUtils.isEmpty(location)) {                log.info("IPParser,findIpAddr(), location is empty !");                return null;            }            if (location.length() == 0) {                log.info("IPParser,findIpAddr(), location length is 0 !");                return null;            }        }        //查不到3        if (location.contains("未知")) {            log.info("IPParser,findIpAddr(), location is not found ! Trying remote interface ...");            location = findIpAddrRemote(ip);            if (StringUtils.isEmpty(location)) {                log.info("IPParser,findIpAddr(), location is empty !");                return null;            }            if (location.contains("未知")) {                log.info("IPParser,findIpAddr(), location is not found !");                return null;            }        }        int cityIndex = location.indexOf("市");        int cityIndex2 = location.indexOf("市", cityIndex + 1);        int provinceIndex = location.indexOf("省");        if (cityIndex > -1 && cityIndex2 == -1) {            if (provinceIndex > -1) {                location = location.substring(provinceIndex + 1, cityIndex);            } else {                location = location.substring(0, cityIndex);            }        }        //处理有2个市的地址        if (cityIndex > -1 && cityIndex2 > -1) {            location = location.substring(cityIndex + 1, cityIndex2);        }        //自治区处理        if (location.contains("宁夏")) {            location = location.replaceAll("宁夏", "");        }        if (location.indexOf("内蒙古") > -1) {            location = location.replaceAll("内蒙古", "");            int districtIndex = location.indexOf("盟");            if (districtIndex > -1) {                location = location.substring(districtIndex + 1, location.length());            }        }        if (location.indexOf("广西") > -1) {            location = location.replaceAll("广西", "");        }        if (location.indexOf("西藏") > -1) {            location = location.replaceAll("西藏", "");        }        if (location.indexOf("新疆") > -1) {            location = location.replaceAll("新疆", "");            int districtIndex = location.indexOf("州");            if (districtIndex > -1) {                location = location.substring(districtIndex + 1, location.length());            }        }        //港澳台处理        if (location.contains("省")) {            location = location.replaceAll("省", "");        }        //其他        if (location.startsWith("清华大学")) {            location = "北京";        }        //去掉CZ88.NET字样,去掉空格        location = location.replaceAll("CZ88.NET", "");        result = location.replaceAll(" ", "");        log.info(ip + " --> " + location);        return result;    }    private String findIpAddrRemote(String ip) {        String result;        HttpClientUtilManagerImpl httpClientUtilManager = new HttpClientUtilManagerImpl();        httpClientUtilManager.setTimeout(1000); //超时时间 1s        String ipXML = httpClientUtilManager.executeHttpRequestString(url + ip, null);        if (ipXML == null) {            log.info("IPParser,findIpAddrRemote(),ipXML is null !");            return null;        }        Document doc;        try {            doc = DocumentHelper.parseText(ipXML.trim());        } catch (DocumentException e) {            log.error("IPParser,findIpAddrRemote() error !" + e);            return null;        }        if (doc == null) {            log.info("IPParser,findIpAddrRemote(),doc is null !");            return null;        }        Element rootElement = doc.getRootElement();        Element productElement = rootElement.element("product");        if (productElement == null) {            log.info("IPParser,findIpAddrRemote(),productElement is null !");            return null;        }        Element element = productElement.element("location");        if (element == null) {            log.info("IPParser,findIpAddrRemote(),element is null !");            return null;        }        result = element.getTextTrim();        return result;    }    /**     * 根据ip获得城市名称     * @param ip     * @return     */    public String ipToCity(String ip){        return findCity(null , ip);    }    /**     * 根据请求获得城市名称     * @param request     * @return     */    public String ipToCity(HttpServletRequest request){        return findCity(request, null);    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    public String getDbPath() {        return dbPath;    }    public void setDbPath(String dbPath) {        this.dbPath = dbPath;    }    public String getCountry() {        return country;    }    public void setCountry(String country) {        this.country = country;    }    public String getLocalStr() {        return localStr;    }    public void setLocalStr(String localStr) {        this.localStr = localStr;    }    public long getIPN() {        return IPN;    }    public void setIPN(long IPN) {        this.IPN = IPN;    }    public int getRecordCount() {        return recordCount;    }    public void setRecordCount(int recordCount) {        this.recordCount = recordCount;    }    public int getCountryFlag() {        return countryFlag;    }    public void setCountryFlag(int countryFlag) {        this.countryFlag = countryFlag;    }    public long getRangE() {        return rangE;    }    public void setRangE(long rangE) {        this.rangE = rangE;    }    public long getRangB() {        return rangB;    }    public void setRangB(long rangB) {        this.rangB = rangB;    }    public long getOffSet() {        return offSet;    }    public void setOffSet(long offSet) {        this.offSet = offSet;    }    public long getStartIP() {        return startIP;    }    public void setStartIP(long startIP) {        this.startIP = startIP;    }    public long getFirstStartIP() {        return firstStartIP;    }    public void setFirstStartIP(long firstStartIP) {        this.firstStartIP = firstStartIP;    }    public long getLastStartIP() {        return lastStartIP;    }    public void setLastStartIP(long lastStartIP) {        this.lastStartIP = lastStartIP;    }    public long getEndIPOff() {        return endIPOff;    }    public void setEndIPOff(long endIPOff) {        this.endIPOff = endIPOff;    }    public RandomAccessFile getFis() {        return fis;    }    public void setFis(RandomAccessFile fis) {        this.fis = fis;    }    public byte[] getBuff() {        return buff;    }    public void setBuff(byte[] buff) {        this.buff = buff;    }    public static void main(String[] args) throws Exception {        long initUsedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());        long start = System.currentTimeMillis();        IPParser w = new IPParser();        // w.setPath(new File("QQWry2.Dat").getAbsolutePath());//w.seek("125.10.100.17");//        String ip = "211.161.190.171";//        String ip = "14.192.60.1";//        w.findRequestPhysAddr(ip);        long end = System.currentTimeMillis();        long endUsedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());        System.out.println("time spent:" + (end - start) + " ms");        System.out.println("memory consumes:" + (endUsedMemory - initUsedMemory));    }}

原创粉丝点击