开源库:
LCCChinaIP
pod 'LCCChinaIP'
1. 获取IP地址
获取IP地址见:看这里
- 应为本地地址可能为局域网的地址,所以还得处理一下
/// 获取本地IP 地址,可能是局域网的地址
@objc public static func getIphoneIpAddress() -> String{
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr
while (ptr != nil) {
let flags = Int32(ptr!.pointee.ifa_flags)
var addr = ptr!.pointee.ifa_addr.pointee
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),nil, socklen_t(0), NI_NUMERICHOST) == 0) {
if let address = String(validatingUTF8:hostname) {
addresses.append(address)
}
}
}
}
ptr = ptr!.pointee.ifa_next
}
freeifaddrs(ifaddr)
}
return addresses.first ?? "0.0.0.0"
}
/// 获取手机的网络的Ip 地址
@objc public static func getNetIpAddress() -> String {
let url = URL(string: "https://ifconfig.me/ip")
let ip = try? String(contentsOf: url!, encoding: .utf8)
return ip ?? "0.0.0.0"
}
/// 获取ip 地址
@objc public static func getIPAddress() -> String {
let phoneIpAddress = getIphoneIpAddress()
if phoneIpAddress.hasPrefix("10.")
|| phoneIpAddress.hasPrefix("172.")
|| phoneIpAddress.hasPrefix("192.168") {
return getNetIpAddress()
}else {
return phoneIpAddress
}
}
1.加载中国地址列表
转换IP地址为Int64或者longlong
- 首先,我们需要思考一个地址是不是在给定的地址范围内,怎么处理?比如 192.0.0.23 在192.0.0.0~192.0.0.255 范围内?
- 其实ip 地址就是 256 进制的数字,我们只要转化为longlong 类型就可处理了
192.0.0.23
->3221225495
192.0.0.0
->3221225472
192.0.0.255
->3221225727
- 现在就只需要比较两个数字的大小就简单多了
/// 将ip 地址转换为Int 类型 @objc public static func covertIPToInt64(ip:String) -> Int64 { // 去空格 let ipStr = ip.replacingOccurrences(of: " ", with: "") if ipStr.count == 0 { return 0 } let splitArr = ipStr.split(separator: ".") var result: Int64 = 0 for (idx,subIp) in splitArr.enumerated() { let num : Int64 = Int64(subIp) ?? 0 let scale = pow(Double(256), Double(3-idx)) result = result + num * Int64(scale) } return result }
- 其实ip 地址就是 256 进制的数字,我们只要转化为longlong 类型就可处理了
遍历查找
- 接下来是考虑怎么在给到的地址范围一一对比的问题,给到地址范围共有8000多个,要是一个一个比较,显然是不合理的,所有我们得小小的处理一下
- 我们可以去ip 地址的第一段作为
KEY
建立一个map,这样就可以做一个简单的分类索引,是不是会快很多呢?存储结构如下
{
"192":[
{
"from":"192.0.0.0"
"fromV":"3221225472"
"to":"192.0.0.255"
"toV":"3221225727"
},
...
],
.....
}
- 处理以后,大部分ip段都只有几十个了,只需要稍微便利一下就好