根据IP地址自动识别省份城市
来源:互联网 发布:java shiro盐值加密 编辑:程序博客网 时间:2024/05/02 01:53
功能说明:需要获取客户端的IP地址,自动识别省份
代码如下:
获取IP地址:
public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) ip = request.getHeader("Proxy-Client-IP"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) ip = request.getHeader("WL-Proxy-Client-IP"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) ip = request.getHeader("HTTP_CLIENT_IP"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) ip = request.getHeader("HTTP_X_FORWARDED_FOR"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) ip = request.getRemoteAddr(); if ("0:0:0:0:0:0:0:1".equals(ip.trim())) { ip = "127.0.0.1"; } return ip; }调用String clientIp = PortalToolsUtil.getIpAddr(portalRequest);
根据IP地址获取省份类:
public class IpAddress { private Logger LogUtil = Logger.getLogger(IpAddress.class); // 随机文件访问类 private RandomAccessFile ipFile = null; // 单一模式实例 private static IpAddress instance = new IpAddress(); // ip开始结束位置 private long ipBegin = 0L; private long ipEnd = 0L; // ip总数 private long ipSum = 0L; // 国家,地区 private String country = ""; private String area = ""; // 一些固定常量,比如记录长度等等 private static final int RECORD_LENGTH = 7; private static final byte AREA_FOLLOWED = 0x01; private static final byte NO_AREA = 0x02; /* * 私有构造函数 */ private IpAddress() { // 数据库地址 String dataPath = PropUtil.getProp("ipfile"); try { ipFile = new RandomAccessFile(new File(dataPath).getAbsolutePath(),"r"); } catch (FileNotFoundException e) { LogUtil.error("IP地址信息文件没有找到(QQWry.Dat),IP显示功能将无法使用"); } if (ipFile != null) { try { ipBegin = byteArrayToLong(readBytes(0, 4)); ipEnd = byteArrayToLong(readBytes(4, 4)); if (ipBegin == -1 || ipEnd == -1) { ipFile.close(); ipFile = null; } } catch (IOException e) { LogUtil.error("IP地址信息文件格式有错误,IP显示功能将无法使用"); } } ipSum = (ipEnd - ipBegin) / RECORD_LENGTH + 1; } /** * 在指定位置读取一定数目的字节 * * @param offset * 位置 * @param num * 多少个字节 * @return ret */ private byte[] readBytes(long offset, int num) { byte[] ret = new byte[num]; try { ipFile.seek(offset); for (int i = 0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { LogUtil.error("读取文件失败_readBytes"); return ret; } } /** * 当前位置读取一定数目的字节 * * @param num * 多少个字节 * @return ret */ private byte[] readBytes(int num) { byte[] ret = new byte[num]; try { for (int i = 0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { LogUtil.error("读取文件失败_readBytes"); return ret; } } /** * 对little-endian字节序进行了转换 byte[]转换为long * * @param b * @return ret */ private long byteArrayToLong(byte[] b) { long ret = 0; for (int i = 0; i < b.length; i++) { ret |= (b[i] << (0x8 * i) & (0xFF * (long) (Math.pow(0x100, i)))); } return ret; } /** * 对little-endian字节序进行了转换 * * @param ip * ip的字节数组形式 * @return ip的字符串形式 */ private String byteArrayToStringIp(byte[] ip) { StringBuffer sb = new StringBuffer(); for (int i = ip.length - 1; i >= 0; i--) { sb.append(ip[i] & 0xFF); sb.append("."); } sb.deleteCharAt(sb.length() - 1); return sb.toString(); } /** * 把ip字符串转换为long型 * * @param ip * @return long */ private long StingIpToLong(String ip) { String[] arr = ip.split("\\."); return (Long.valueOf(arr[0]).longValue() * 0x1000000 + Long.valueOf(arr[1]).longValue() * 0x10000 + Long.valueOf(arr[2]).longValue() * 0x100 + Long.valueOf( arr[3]).longValue()); } /** * 搜索ip,二分法 * * @param ip * @return long ip所在位置 */ public long seekIp(String ip) { long tmp = StingIpToLong(ip); long i = 0; long j = ipSum; long m = 0; long lm = 0L; while (i < j) { m = (i + j) / 2; lm = m * RECORD_LENGTH + ipBegin; if (tmp == byteArrayToLong(readBytes(lm, 4))) { return byteArrayToLong(readBytes(3)); } else if (j == (i + 1)) { return byteArrayToLong(readBytes(3)); } else if (tmp > byteArrayToLong(readBytes(lm, 4))) { i = m; } else/* if( tmp < byteArrayToLong(readBytes(lm, 4))) */{ j = m; } } //LogUtil.error("没有找到ip"); return -1L; } private String readArea(long offset) throws IOException { ipFile.seek(offset); byte b = ipFile.readByte(); if (b == 0x01 || b == 0x02) { long areaOffset = byteArrayToLong(readBytes(offset + 1, 3)); // if(areaOffset == 0) // return "未知"; // else return readString(areaOffset); } else return readString(offset); } /** * 通过ip位置获取国家地区, 参照纯真ip数据库结构 * * @param offset * @return 国家+地区 */ private String seekCountryArea(long offset) { try { ipFile.seek(offset + 4); byte b = ipFile.readByte(); if (b == AREA_FOLLOWED) { long countryOffset = byteArrayToLong(readBytes(3)); ipFile.seek(countryOffset); b = ipFile.readByte(); if (b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); ipFile.seek(countryOffset + 4); } else country = readString(countryOffset); // area = readArea(ipFile.getFilePointer()); } else if (b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); // area = readArea(offset + 8); } else { country = readString(ipFile.getFilePointer() - 1); // area = readArea(ipFile.getFilePointer()); } // return country + " " + area; String country1; if (country.length() >= 2) // 只取前两个字 country1 = country.substring(0, 2); else country1 = country; return country1; // return CountryMap.getBranchCodeByCountryName(country1); } catch (IOException e) { return null; } } /** * 从offset偏移处读取一个以0结束的字符串 * * @param offset * @return ret 读取的字符串,出错返回空字符串 */ private String readString(long offset) { try { ipFile.seek(offset); byte[] b = new byte[128]; int i; for (i = 0; (b.length != i) && ((b[i] = ipFile.readByte()) != 0); i++) ; <span style="background-color: rgb(51, 0, 51);"> <span style="color:#FF0000;">String ret = new String(b, 0, i, "GBK");</span></span> ret = ret.trim(); return (ret.equals("") || ret.indexOf("CZ88.NET") != -1) ? "未知" : ret; } catch (IOException e) { LogUtil.error("读取文件失败_readString"); } return ""; } /** * 包含字符串的ip记录 * * @param addr * 地址 * @return IpRecord ip记录 */ public ArrayList stringToIp(String addr) { ArrayList ret = new ArrayList(); try { FileChannel fc = ipFile.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length()); mbb.order(ByteOrder.LITTLE_ENDIAN); // 上面3代码未使用,内存映射文件功能未写 for (long i = ipBegin + 4; i != ipEnd + 4; i += RECORD_LENGTH) { String sca = seekCountryArea(byteArrayToLong(readBytes(i, 3))); if (sca.indexOf(addr) != -1) { IpRecord rec = new IpRecord(); rec.address = sca; rec.beginIp = byteArrayToStringIp(readBytes(i - 4, 4)); rec.endIp = byteArrayToStringIp(readBytes(i + 3, 4)); ret.add(rec); } } } catch (IOException e) { LogUtil.error(e.getMessage()); } return ret; } /** * 封装ip记录,包括开始ip,结束ip和地址 */ private class IpRecord { public String beginIp; public String endIp; public String address; public IpRecord() { beginIp = endIp = address = ""; } public String toString() { return beginIp + " - " + endIp + " " + address; } } /** * @return 单一实例 */ public static IpAddress getInstance() { return instance; } /** * @param ip * @return ret */ public String IpStringToAddress(String ip) { // 这里要添加ip格式判断 // public boolean isIP(Strin ip) long ipOffset = seekIp(ip); String ret = seekCountryArea(ipOffset); return ret; } /** * @return IpSum */ public long getIpSum() { return ipSum; } public static void main(String[] args) throws UnsupportedEncodingException { IpAddress ipAddr = IpAddress.getInstance(); // //ip总数 // long l = ipAddr.getIpSum(); // LogUtil.error(l); // 测试 String str = ipAddr.IpStringToAddress("218.65.88.101"); System.out.println(str); //LogUtil.error(str); /* * java.net.InetAddress addr = null; try{ addr = * java.net.InetAddress.getLocalHost(); * }catch(java.net.UnknownHostException e){ e.printStackTrace(); } * String ip=addr.getHostAddress().toString();//获得本机IP * System.out.print(ip); String * address=addr.getHostName().toString();//获得本机名称 * System.out.print(address); str = ipAddr.IpStringToAddress(ip); * LogUtil.error(str); */ // ArrayList<IpRecord> al = ipAddr.stringToIp("网吧"); // Iterator it = al.iterator(); // // File f = new File("ipdata.txt"); // try { // if (!f.exists()) { // f.createNewFile(); // } // BufferedWriter out = new BufferedWriter( // new OutputStreamWriter( // new FileOutputStream(f, true) // ) // ); // int i = 0; // while (it.hasNext()) { // out.write(it.next().toString()); // out.newLine(); // i++; // } // out.write(new Date().toString()); // out.write("总共搜索到 " + i); // out.close(); // } catch (IOException e) { // e.printStackTrace(); // } }}
注意事项:QQWry.Dat可以百度从网上下载,但该文件为GBK编码,读取时需要加编码,如代码中红色标注
0 0
- 根据IP地址自动识别省份城市
- 根据ip地址查询城市
- 根据IP地址定位城市
- 通过IP地址获取省份城市位置信息
- Java 通过Request请求获取IP地址对应省份、城市
- 根据IP地址查询其所属城市
- 根据IP地址查出对应城市
- 根据Ip地址获取城市名
- C#根据IP地址获取城市
- Android 根据IP地址获取城市
- 根据IP地址判断所属城市
- js根据IP地址判断城市
- C#根据IP查询省份、城市,纯真IP库实现方式+无IP库实现方式
- PHP 获取IP 并根据IP获取 城市省份等信息
- 根据不规范填写的地址,城市名自动判断省份,生成省名+城市名的地址栏
- Java利用Request请求获取IP地址对应的省份、城市
- 百度地图接口,根据IP地址定位当前城市
- 主要省份城市的DNS服务器地址
- Android 开源项目
- [密码学]格密码学(3)-Babai算法以及GGH公钥密码体制介绍
- 第17周 项目6 读取学生成绩及筛选
- (原创)实战渗透学校
- Linux信号(signal) 机制分析
- 根据IP地址自动识别省份城市
- 使用UDL文件获得数据库连接字符串
- VS2008环境下C++调用Python模块函数----一封邮件引发的关机
- EPS
- 剑指offer 面试题25 输出和为某值的路径
- vc++6.0中文档、视图与框架的互相调用
- (原创)实战渗透河北经贸大学
- 适配器模式
- Android 程序打包及签名