c++ 判断一个 IP 地址(可能是 IPv6 或 IPv4)是否属于特定范围

在 C++ 中,判断一个 IP 地址(可能是 IPv6 或 IPv4)是否属于特定范围时,需要考虑两种不同的地址格式和它们的范围比较。IPv6 和 IPv4 地址结构完全不同,因此需要分别处理这两种地址类型。

实现思路:

识别 IP 地址类型:首先,需要检测输入的 IP 地址是 IPv4 还是 IPv6 地址。
将地址转换为适当的格式:根据 IP 类型,将其转换为 in6_addr 或 in_addr 类型。
范围比较:
对于 IPv4 地址,进行简单的范围比较。
对于 IPv6 地址,进行字节级的范围比较。
支持混合范围比较:需要处理包含 IPv4 和 IPv6 的情况,例如判断一个 IPv4 地址是否在一个 IPv6 范围内,或者判断一个 IPv6 地址是否与一个 IPv4 地址相比较。
示例代码:
下面是一个 C++ 示例程序,判断 IPv6 和 IPv4 地址是否在特定范围内,并支持混合比较(例如 IPv4 地址与 IPv6 地址范围比较)。

#include <iostream>
#include <string>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>// 判断 IPv4 地址是否在范围内
bool isIPv4InRange(const std::string& ip, const std::string& rangeStart, const std::string& rangeEnd) {struct in_addr ipAddr, startAddr, endAddr;if (inet_pton(AF_INET, ip.c_str(), &ipAddr) != 1) {std::cerr << "Invalid IPv4 address format\n";return false;}if (inet_pton(AF_INET, rangeStart.c_str(), &startAddr) != 1 || inet_pton(AF_INET, rangeEnd.c_str(), &endAddr) != 1) {std::cerr << "Invalid IPv4 range format\n";return false;}return ntohl(ipAddr.s_addr) >= ntohl(startAddr.s_addr) && ntohl(ipAddr.s_addr) <= ntohl(endAddr.s_addr);
}// 判断 IPv6 地址是否在范围内
bool isIPv6InRange(const std::string& ip, const std::string& rangeStart, const std::string& rangeEnd) {struct in6_addr ipAddr, startAddr, endAddr;if (inet_pton(AF_INET6, ip.c_str(), &ipAddr) != 1) {std::cerr << "Invalid IPv6 address format\n";return false;}if (inet_pton(AF_INET6, rangeStart.c_str(), &startAddr) != 1 || inet_pton(AF_INET6, rangeEnd.c_str(), &endAddr) != 1) {std::cerr << "Invalid IPv6 range format\n";return false;}// 比较每个字节return memcmp(&ipAddr, &startAddr, sizeof(struct in6_addr)) >= 0 &&memcmp(&ipAddr, &endAddr, sizeof(struct in6_addr)) <= 0;
}// 判断 IPv4 是否在 IPv6 范围内
bool isIPv4InIPv6Range(const std::string& ip, const std::string& rangeStart, const std::string& rangeEnd) {struct in6_addr ipAddr, startAddr, endAddr;struct in_addr ipv4Addr;if (inet_pton(AF_INET, ip.c_str(), &ipv4Addr) != 1) {std::cerr << "Invalid IPv4 address format\n";return false;}// 将 IPv4 地址转换为 IPv6 地址,填充高 96 位为 0,低 32 位为 IPv4 地址memset(&ipAddr, 0, sizeof(ipAddr));memcpy(&ipAddr.s6_addr[12], &ipv4Addr, sizeof(ipv4Addr));if (inet_pton(AF_INET6, rangeStart.c_str(), &startAddr) != 1 || inet_pton(AF_INET6, rangeEnd.c_str(), &endAddr) != 1) {std::cerr << "Invalid IPv6 range format\n";return false;}// 比较每个字节return memcmp(&ipAddr, &startAddr, sizeof(struct in6_addr)) >= 0 &&memcmp(&ipAddr, &endAddr, sizeof(struct in6_addr)) <= 0;
}// 主函数
int main() {// 示例:IPv6 地址范围std::string ipv6Addr = "2001:db8::1";std::string ipv6RangeStart = "2001:db8::";std::string ipv6RangeEnd = "2001:db8::ffff";if (isIPv6InRange(ipv6Addr, ipv6RangeStart, ipv6RangeEnd)) {std::cout << ipv6Addr << " is within the IPv6 range.\n";} else {std::cout << ipv6Addr << " is outside the IPv6 range.\n";}// 示例:IPv4 地址范围std::string ipv4Addr = "192.168.1.10";std::string ipv4RangeStart = "192.168.1.0";std::string ipv4RangeEnd = "192.168.1.255";if (isIPv4InRange(ipv4Addr, ipv4RangeStart, ipv4RangeEnd)) {std::cout << ipv4Addr << " is within the IPv4 range.\n";} else {std::cout << ipv4Addr << " is outside the IPv4 range.\n";}// 示例:IPv4 地址是否在 IPv6 地址范围内std::string ipv4InIPv6Range = "192.168.1.10";std::string ipv6RangeStart = "2001:db8::";std::string ipv6RangeEnd = "2001:db8::ffff";if (isIPv4InIPv6Range(ipv4InIPv6Range, ipv6RangeStart, ipv6RangeEnd)) {std::cout << ipv4InIPv6Range << " is within the IPv6 range.\n";} else {std::cout << ipv4InIPv6Range << " is outside the IPv6 range.\n";}return 0;
}

代码解析:

isIPv4InRange:

使用 inet_pton 将 IPv4 地址转换为 in_addr 结构。
使用 ntohl 函数将 IP 地址从网络字节序转换为主机字节序,便于进行比较。
比较给定的 IPv4 地址是否位于指定的范围内。

isIPv6InRange:

使用 inet_pton 将 IPv6 地址转换为 in6_addr 结构。
使用 memcmp 按字节比较两个 IPv6 地址,判断目标地址是否在范围内。
isIPv4InIPv6Range:

将 IPv4 地址转换为一个包含 IPv4 地址的 IPv6 地址(通过将 IPv4 地址放入 IPv6 的低 32 位,其余位填充为 0)。
然后使用 memcmp 比较该 IPv6 地址是否在指定的 IPv6 范围内。
示例输出:

2001:db8::1 is within the IPv6 range.
192.168.1.10 is within the IPv4 range.
192.168.1.10 is outside the IPv6 range.

注意事项:

IPv4 地址与 IPv6 地址的范围比较:IPv4 地址转换为 IPv6 后进行比较,比较时需要确保 IPv4 地址被正确处理。IPv6 地址范围可能包括整个 IPv4 地址范围,但处理时需要注意协议版本差异。
地址格式的验证:代码使用 inet_pton 来验证 IP 地址的格式。如果输入的地址无效,函数将返回 false,避免错误的比较。
这样,您可以判断 IPv4 和 IPv6 地址是否在指定范围内,并处理它们之间的混合比较。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/35448.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Luma 视频生成 API 对接说明

Luma 视频生成 API 对接说明 随着 AI 的应用变广&#xff0c;各类 AI 程序已逐渐普及。AI 已逐渐深入到人们的工作生活方方面面。而 AI 涉及的行业也越来越多&#xff0c;从最初的写作&#xff0c;到医疗教育&#xff0c;再到现在的视频。 Luma 是一个专业高质量的视频生成平…

基础算法——搜索与图论

搜索与图论 图的存储方式2、最短路问题2.1、Dijkstra算法&#xff08;朴素版&#xff09;2.2、Dijkstra算法&#xff08;堆优化版&#xff09;2.3、Bellman-Ford算法2.4、SPFA求最短路2.5、SPFA判负环2.6、Floyd算法 图的存储方式 2、最短路问题 最短路问题可以分为单源最短路…

Online Monocular Lane Mapping

IROS 2023 港科大 文章链接&#xff1a;http://arxiv.org/abs/2307.11653 github&#xff1a;GitHub - HKUST-Aerial-Robotics/MonoLaneMapping: Online Monocular Lane Mapping Using Catmull-Rom Spline (IROS 2023) 动机 摆脱高精地图&#xff0c;使用车端的传感器来实现车端…

29.两数相除 python

两数相除 题目题目描述示例 1:示例 2:提示&#xff1a;题目链接 题解解题思路python实现代码解释提交结果 题目 题目描述 给你两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断&#x…

MicroBlaze软核开发(二):GPIO

实现功能&#xff1a;使用 MicroBlaze软核&#xff0c;配置GPIO用拨码开关控制LED灯 Vivado版本&#xff1a;2018.3 目录 引言 vivado部分&#xff1a; 一、配置GPIO 二、生成HDL文件编译 SDK部分&#xff1a; 一、导出硬件启动SDK 二、新建应用程序工程 三、编写程序代…

sdk项目的git 标记新tag的版本号

在 Git 中&#xff0c;tag 是用来标记某个特定的提交点&#xff08;通常是发布版本或重要的里程碑&#xff09;的工具。通过 git tag&#xff0c;你可以为版本号创建标记&#xff0c;帮助团队跟踪不同版本的代码。 如果你想创建一个新的版本号标签&#xff0c;可以按照以下步骤…

40分钟学 Go 语言高并发:服务注册与发现

服务注册与发现 一、系统架构设计 让我们先通过流程图了解服务注册与发现的整体架构&#xff1a; 二、核心组件实现 1. 服务注册中心 package discoveryimport ("context""sync""time" )// ServiceInstance 服务实例 type ServiceInstance…

〔 MySQL 〕索引

目录 1. 没有索引&#xff0c;可能会有什么问题 2. 认识磁盘 MySQL与存储 先来研究一下磁盘&#xff1a; 在看看磁盘中一个盘片​编辑 扇区 定位扇区​编辑 结论 磁盘随机访问(Random Access)与连续访问(Sequential Access) 3. MySQL 与磁盘交互基本单位 4. 建立共识…

微信小程序里的小游戏研发需要什么技术栈

研发小程序里的小游戏通常需要以下技术栈&#xff1a; 前端技术 HTML5 / CSS3&#xff1a;用于构建游戏的界面布局和样式。JavaScript&#xff1a;作为核心编程语言&#xff0c;实现游戏的逻辑和交互。小程序开发框架&#xff1a;如微信小程序的开发框架&#xff0c;了解其 API…

php 生产者-消费者实现

一、项目背景 mes报工需求&#xff0c;原项目接口接收产线上位抛来的数据&#xff0c;处理无误后存储在本地&#xff0c;最后抛给工厂接口。 但是有时候工厂数据响应太慢&#xff0c;也导致mes响应给上位变慢&#xff0c;拖慢了mes系统。 现要求&#xff0c;将原接口中抛给工厂…

SpringBoot 解决跨域问题

SpringBoot 解决跨域问题 遇到前端跨域访问问题&#xff0c;类似于这样的&#xff1a; 在Springboot项目里加上这个配置文件CorsConfig.java&#xff0c;重启之后即可实现跨域访问&#xff0c;前端无需再配置跨域。 1、添加跨域工具包CorsConfig 2、写跨域代码 import org.sp…

IO基础(缓冲流)

FileInputStream、FileOutputStream、FileReader、FileWriter属于基础流。 缓冲流是高级流。能够高效的处理数据。原理&#xff1a;底层自带了长度为8192的缓冲区提高性能 字节缓冲流&#xff1a;BufferedInputStream、BufferedOutputStream 字符缓冲流&#xff1a;Buffered…

云数据库 Memcache

Memcached 是一个高性能的分布式内存缓存系统&#xff0c;主要用于加速动态网页应用的访问速度&#xff0c;通过减少数据库查询次数来提高系统性能。Memcached 将常用的数据存储在内存中&#xff0c;因此提供了非常快速的读取和写入操作&#xff0c;通常用于缓存热点数据&#…

高转化的Facebook广告文案的秘诀

Facebook 广告文案是制作有效 Facebook 广告的关键方面。它侧重于伴随广告视觉元素的文本内容。今天我们的博客将深入探讨成功的 Facebook 广告文案的秘密&#xff01; 一、广告文案怎么写&#xff1f; 正文&#xff1a;这是帖子的正文&#xff0c;出现在您姓名的正下方。它可…

算法基础学习Day2(双指针)

文章目录 1.题目2.题目解答1.快乐数题目及题目解析算法学习代码提交 2.题目2题目及题目解析算法学习代码提交 1.题目 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09;11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 2.题目解答 1.快乐数 题目及题目解析 …

Web3与人工智能的跨界融合:数据隐私与去中心化的新机遇

随着Web3和人工智能&#xff08;AI&#xff09;技术的不断发展&#xff0c;两者的结合正在成为未来互联网的重要趋势。Web3代表着去中心化的未来&#xff0c;AI则提供了强大的智能化能力。当这两者结合时&#xff0c;不仅为数据隐私保护提供了新的解决方案&#xff0c;还推动了…

DevOps系统设计和技术选型

命名是一件痛苦的事情&#xff0c;除非你不想要一个好名字。 我正在做的这个管理系统叫什么合适&#xff0c;或者是什么类型的系统&#xff0c;想去想来不知所措&#xff0c;后来想想这么小的东西纠结什么&#xff0c;先从小的细节一点点来&#xff0c;能用就行&#xff0c;就用…

2024年华中杯数学建模A题太阳能路灯光伏板的朝向设计问题解题全过程文档及程序

2024年华中杯数学建模 A题 太阳能路灯光伏板的朝向设计问题 原题再现 太阳能路灯由太阳能电池板组件部分&#xff08;包括支架&#xff09;、LED灯头、控制箱&#xff08;包含控制器、蓄电池&#xff09;、市电辅助器和灯杆几部分构成。太阳能电池板通过支架固定在灯杆上端。…

sheng的学习笔记-AI-序列模型(Sequence Models),RNN,GRU,LSTM

Ai目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 基础知识 定义&#xff1a; 序列模型是输入输出均为序列数据的模型&#xff0c;它能够将输入序列数据转换为目标序列数据。常见的序列模型类型包括一对一、一对多、多对一、部分多对多和完全多对多。 重要的是需要有顺序…

《网络安全》相关知识点总结

第一章 安全现状及趋势 第二章 网络安全概述 2.1 信息保障阶段 信息保障技术框架IATF&#xff1a; 由美国国家安全局制定&#xff0c;提出“纵深防御策略” DiD&#xff08;Defense-in-Depth Strategy&#xff09; 在信息保障的概念下&#xff0c;信息安全保障的PDRR模型的内涵…