在产品中可能存在不同客户端,请求同一个服务端接口的场景。

例如小程序和App或者浏览器中,如果需要对请求的归属地进行分析,前提是需要先获取请求所在的国家或城市,这种定位通常需要主动授权,而用户一般是不愿意提供的,就需要通过请求的IP来进行归属地计算。

IP地址一般分为两种,IPV4和IPV6,相应的计算方式也有差异,以国家维度来参考,每个国家都有对应的网段范围,计算网段中的最小和最大IP地址的对应数值,然后对比请求的IP地址,来判断属于哪个国家的网段范围。

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.StrUtil;
import java.math.BigInteger;
import java.net.InetAddress; public class IpCalculate {
public static void main(String[] args) throws Exception {
// IPv4 网段
String ipv4Network = "IPv4 网段";
String[] ipv4Param = StrUtil.splitToArray(ipv4Network, "/"); // IPv4 起始和结束IP
String ipv4StartIp = Ipv4Util.getBeginIpStr(ipv4Param[0],Integer.parseInt(ipv4Param[1]));
String ipv4OverIp = Ipv4Util.getEndIpStr(ipv4Param[0],Integer.parseInt(ipv4Param[1]));
System.out.println(ipv4StartIp);
System.out.println(ipv4OverIp); // IPv4 起始和结束IP对应的Long值
System.out.println(Ipv4Util.ipv4ToLong(ipv4StartIp));
System.out.println(Ipv4Util.ipv4ToLong(ipv4OverIp)); // IPv6 网段
String ipv6Network = "IPv6 网段";
String[] ipv6Param =ipv6Network.split("/");
int prefixLength = Integer.parseInt(ipv6Param[1]); // IPv6 起始和结束IP
InetAddress baseAddress = InetAddress.getByName(ipv6Param[0]);
BigInteger baseValue = new BigInteger(1, baseAddress.getAddress());
BigInteger mask = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE)
.shiftRight(128 - prefixLength).shiftLeft(128 - prefixLength);
BigInteger minIp = baseValue.and(mask);
BigInteger maxIp = minIp.add(BigInteger.ONE.shiftLeft(128 - prefixLength).subtract(BigInteger.ONE));
System.out.println(toIPv6String(minIp));
System.out.println(toIPv6String(maxIp)); // IPv6 起始和结束IP对应的Long值
System.out.println(minIp);
System.out.println(maxIp);
} private static String toIPv6String(BigInteger value) throws Exception {
byte[] bytes = value.toByteArray();
byte[] ipv6Bytes = new byte[16];
int start = bytes.length > 16 ? bytes.length - 16 : 0;
int length = Math.min(bytes.length, 16);
System.arraycopy(bytes, start, ipv6Bytes, 16 - length, length);
return InetAddress.getByAddress(ipv6Bytes).getHostAddress();
}
}

不过网段地址和国家的对应关系需要进行维护,如果归属地分析不需要非常精准,可以直接使用开源的字典库,比如使用比较多的就是GeoIP2组件。

<dependency>
<groupId>com.maxmind.geoip2groupId>
<artifactId>geoip2</artifactId>
</dependency>

通过组件中提供的API加载相应的文件字典,然后传入IP地址进行归属地判断,这里要注意争议和敏感地区的处理,如果出错产品可不止是上热搜的问题了。

import com.maxmind.geoip2.DatabaseReader;
import java.io.File;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress; public class GeoIpTool {
public static void main(String[] args) throws Exception { // 读取IP库文件
File ipFile = new File("IP文件库");
DatabaseReader reader = new DatabaseReader.Builder(ipFile).build(); // IPV4地址
InetAddress ipV4 = InetAddress.getByName("IPV4");
if (ipV4 instanceof Inet4Address){
System.out.println(reader.country(ipV4));
System.out.println(reader.country(ipV4).getCountry());
// 默认英文名
System.out.println(reader.country(ipV4).getCountry().getName());
// 查询中文名
System.out.println(reader.country(ipV4).getCountry().getNames().get("zh-CN"));
} // IPV6地址
InetAddress ipV6 = InetAddress.getByName("IPV6");
if (ipV6 instanceof Inet6Address){
System.out.println(reader.country(ipV6));
System.out.println(reader.country(ipV6).getCountry());
// 默认英文名
System.out.println(reader.country(ipV6).getCountry().getName());
// 查询中文名
System.out.println(reader.country(ipV6).getCountry().getNames().get("zh-CN"));
}
}
}

如果需要非常精确的实时归属地分析,可以购买专业的IP网段数据,实时更新到本地的数据库中,作为IP字典使用,获取请求的IP后,直接范围匹配即可。

CREATE TABLE `ip_place` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`network` varchar(100) DEFAULT NULL COMMENT '网段区间',
`min_ip` bigint(20) DEFAULT NULL COMMENT '最小IP',
`max_ip` bigint(20) DEFAULT NULL COMMENT '最大IP',
`min_ip_number` bigint(20) DEFAULT NULL COMMENT '最小IP数值',
`max_ip_number` bigint(20) DEFAULT NULL COMMENT '最大IP数值',
`ip_place` varchar(100) DEFAULT NULL COMMENT '归属地',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='IP归属地';

最后需要补充说一句,对于很多标准的数据,尽可能在项目最初就设计好字典枚举或者数据表,避免后续规范时面临数据清洗的问题。

通过IP计算分析归属地的更多相关文章

  1. TCP、UDP、IP 协议分析

    http://rabbit.xttc.edu.cn/rabbit/htm/artical/201091145609.shtml  http://bhsc881114.github.io/2015/06 ...

  2. TCP、UDP、IP协议分析

    此篇文章的原创作者是:草根老师博客(程姚根) chengyaogen.blog.chinaunix.net 感谢原作者! 互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如: ...

  3. TCP/IP协议分析

    一;前言 学习过TCP/IP协议的人多有一种感觉,这东西太抽象了,没有什么数据实例,看完不久就忘了.本文将介绍一种直观的学习方法,利用协议分析工具学习TCP/IP,在学习的过程中能直观的看到数据的具体 ...

  4. TCP/IP协议分析(推荐)

    一;前言 学习过TCP/IP协议的人多有一种感觉,这东西太抽象了,没有什么数据实例,看完不久就忘了.本文将介绍一种直观的学习方法,利用协议分析工具学习TCP/IP,在学习的过程中能直观的看到数据的具体 ...

  5. [SuProxy]Ngnix+Lua 实现SSH2,LDAP,ORACLE,SQLSERVER等TCP/IP协议分析,劫持,代理,会话及负载

    目录 目录 目录 前言 介绍 安装 下载并拷贝 使用LuaRocks安装 运行测试 使用简介 处理器(processor)创建 通道(channel)创建 负载均衡 会话信息和会话管理 Event H ...

  6. floating IP 原理分析 - 每天5分钟玩转 OpenStack(107)

    上一节我们通过 Web UI 创建为 cirros-vm3 分配了浮动 IP,今天将分析其工作原理. 首先查看 router 的 interface 配置: 可以看到,floating IP 已经配置 ...

  7. Linux内核TCP/IP参数分析与调优

    转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0225/167.html?1456482565 如下图展示的是TCP的三个阶段.1,TCP三次握手. ...

  8. C# 根据IP查询地址归属地

    必备文件:IPLocation.dll.QQWry.Dat 下载地址:http://pan.baidu.com/s/1jG1dlOy (可百度下载) 之前有过将 QQWry.Dat 转为 Access ...

  9. tcpdump使用和TCP/IP包分析

    关于tcpdump如何抓包,本文不再总结,可以查看 tcpdump的官方地址查看http://www.tcpdump.org 本文重点记录两个部分:           第一部分:tcpdump所抓包 ...

  10. 软考计算机网络原理之IP计算问题汇总

    转自 http://www.cnblogs.com/jyh317/archive/2013/04/14/3018650.html 1.IP地址 分类: ①A类IP地址 ②B类IP地址 ③C类IP地址 ...

随机推荐

  1. 使用iceberg-使用Iceberg数据湖需要注意的点

    一.资料准备 1.mysql地址选择 因为阿里云只读节点binlog保留时间短,需要用读写集群地址.可以登录阿里云控制台查看地址是只读还是读写,不清楚的话可以找dba要读写地址. 二.Iceberg概 ...

  2. Luogu P1784 数独 [ 模板 ] / P1074 靶形数独 题解 [ 蓝 ] [ 深搜 ] [ 剪枝 ] [ 卡常 ]

    数独模板 , 靶形数独 卡了 2h ,再也不想写数独了. 普通数独 思路 显然是对每个格子进行枚举,类似八皇后的方法去做,朴素方法是由 \((1,1)\) 到 \((9,9)\) 遍历过去. 优化 我 ...

  3. Aspire+扣子智能体实现AI自动CodeReview

    一.引言 Code Review在软件开发中扮演着至关重要的角色,它不仅能够提升代码质量,确保代码的可维护性和一致性,还能促进团队成员之间的知识共享和技术提升. 传统的代码审查过程面临着诸多挑战和局限 ...

  4. [SDOI2008] 洞穴勘测 题解

    似乎所有的线段树分治题都能被 \(LCT\) 平替掉? 一眼动态树,直接 \(LCT\). Connect x y 操作用 \(link(x,y)\) 实现,Destroy x y 操作用 \(cut ...

  5. pagehelper分页查询的一个坑,明明下一页没有数据了却还是返回了数据

    pagehelper分页查询的一个坑,明明下一页没有数据了却还是返回了数据 解决:关闭这该死的合理化,如下配置: pagehelper:# helperDialect: mysql reasonabl ...

  6. 【效能提升】测试人员提bug,应该提供哪些信息以便排查问题?

    背景 我们在运维企业级应用时,会遇到很多Bug. 有时候,测试人员或业务方反馈bug,描述得不够详细,我们基于他的描述很难清晰地了解情况,以解决bug. 一般情况下,我们会跟他询问更多的详情,才能知悉 ...

  7. Android设备基础信息获取 源码修改方式 APK开发

    APK 获取设备信息 头文件 import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import ...

  8. Normalizing flow 流模型 | CS236深度生成模型Lec8学习笔记

    主要参考资料:Stanford University CS236: Deep Generative Models Lec8. 这篇blog基本上是CS236 Lec8的刷课总结/刷课笔记. VAE 这 ...

  9. 一文搞懂 MCP Servers

    一文搞懂 MCP Servers 什么是MCP MCP概念 MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 提出并于 2024 年 11 月开源的一种通 ...

  10. 【ABAQUS文档笔记】ABAQUS刚体单元和可变形单元的review

    学习笔记,帮助文档学习笔记 目录 A. finite element DOF of Elem Order of Elem Formulation of Elem Integration A.1 con ...