C++檢測(cè)IPv4和IPv6地址合法性的兩種方法
概述
在網(wǎng)絡(luò)編程中,經(jīng)常需要驗(yàn)證 IP 地址的合法性。本文介紹兩種在 C++ 中檢測(cè) IPv4 和 IPv6 地址合法性的方法:使用系統(tǒng)原生接口和手動(dòng)解析驗(yàn)證。系統(tǒng)接口方法簡(jiǎn)單可靠,推薦優(yōu)先使用;手動(dòng)解析方法適用于無法使用系統(tǒng)接口的特殊場(chǎng)景。
方法一:使用系統(tǒng)原生接口(推薦)
利用 POSIX 標(biāo)準(zhǔn)中的 inet_pton 函數(shù),該函數(shù)可同時(shí)支持 IPv4 和 IPv6 地址的驗(yàn)證,能正確處理各種合法格式(包括 IPv6 的壓縮格式)。
#include <iostream>
#include <string>
#include <arpa/inet.h> // 包含inet_pton函數(shù)
// 檢測(cè)IPv4地址合法性
bool is_valid_ipv4(const std::string& ip) {
struct in_addr addr;
// inet_pton返回1表示成功,0表示格式錯(cuò)誤,-1表示地址族錯(cuò)誤
return inet_pton(AF_INET, ip.c_str(), &addr) == 1;
}
// 檢測(cè)IPv6地址合法性
bool is_valid_ipv6(const std::string& ip) {
struct in6_addr addr;
return inet_pton(AF_INET6, ip.c_str(), &addr) == 1;
}
// 檢測(cè)是否為合法IP(IPv4或IPv6)
bool is_valid_ip(const std::string& ip) {
return is_valid_ipv4(ip) || is_valid_ipv6(ip);
}
int main() {
// 測(cè)試用例
std::string ipv4_test1 = "192.168.1.1";
std::string ipv4_test2 = "256.0.0.1"; // 非法(256超過255)
std::string ipv6_test1 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
std::string ipv6_test2 = "2001:db8:85a3::8a2e:370:7334"; // 壓縮格式
std::string ipv6_test3 = "2001:db8:85a3:::8a2e:370:7334"; // 非法(雙冒號(hào)過多)
std::cout << ipv4_test1 << " 是" << (is_valid_ipv4(ipv4_test1) ? "" : "非") << "合法IPv4\n";
std::cout << ipv4_test2 << " 是" << (is_valid_ipv4(ipv4_test2) ? "" : "非") << "合法IPv4\n";
std::cout << ipv6_test1 << " 是" << (is_valid_ipv6(ipv6_test1) ? "" : "非") << "合法IPv6\n";
std::cout << ipv6_test2 << " 是" << (is_valid_ipv6(ipv6_test2) ? "" : "非") << "合法IPv6\n";
std::cout << ipv6_test3 << " 是" << (is_valid_ipv6(ipv6_test3) ? "" : "非") << "合法IPv6\n";
return 0;
}
代碼解析
核心函數(shù):
inet_pton:將點(diǎn)分十進(jìn)制(IPv4)或冒號(hào)分隔(IPv6)的 IP 地址字符串轉(zhuǎn)換為二進(jìn)制格式- 函數(shù)返回值:1 表示轉(zhuǎn)換成功(地址合法),0 表示格式錯(cuò)誤,-1 表示地址族錯(cuò)誤
函數(shù)說明:
is_valid_ipv4:檢測(cè) IPv4 地址,使用AF_INET地址族is_valid_ipv6:檢測(cè) IPv6 地址,使用AF_INET6地址族is_valid_ip:檢測(cè)是否為合法 IP 地址(IPv4 或 IPv6)
測(cè)試用例:
- 包含合法和非法的 IPv4 地址
- 包含完整格式、壓縮格式和非法格式的 IPv6 地址
編譯與運(yùn)行
Linux/macOS:
g++ ip_checker.cpp -o ip_checker && ./ip_checker
Windows(需要鏈接 Winsock 庫):
g++ ip_checker.cpp -o ip_checker -lws2_32 && ip_checker.exe
方法二:手動(dòng)解析驗(yàn)證
當(dāng)無法使用系統(tǒng)接口時(shí),可以通過手動(dòng)解析字符串來驗(yàn)證 IP 地址格式。這種方法需要自己處理各種格式規(guī)則,實(shí)現(xiàn)相對(duì)復(fù)雜。
IPv4 手動(dòng)驗(yàn)證
#include <string>
#include <sstream>
#include <vector>
#include <cctype>
// 分割字符串
std::vector<std::string> split(const std::string& s, char delim) {
std::vector<std::string> parts;
std::string part;
std::istringstream iss(s);
while (std::getline(iss, part, delim)) {
parts.push_back(part);
}
return parts;
}
// 手動(dòng)檢測(cè)IPv4(點(diǎn)分十進(jìn)制)
bool is_valid_ipv4_manual(const std::string& ip) {
auto parts = split(ip, '.');
// 必須有4個(gè)部分
if (parts.size() != 4) return false;
for (const auto& part : parts) {
// 每個(gè)部分不能為空且長(zhǎng)度不能超過3
if (part.empty() || part.size() > 3) return false;
// 檢查是否全為數(shù)字
for (char c : part) {
if (!std::isdigit(c)) return false;
}
// 檢查范圍是否在0-255之間
int num = std::stoi(part);
if (num < 0 || num > 255) return false;
// 檢查是否有前導(dǎo)零(如"01"是非法的,"0"是合法的)
if (part.size() > 1 && part[0] == '0') return false;
}
return true;
}
IPv6 手動(dòng)驗(yàn)證
// 手動(dòng)檢測(cè)IPv6(冒號(hào)分隔)
bool is_valid_ipv6_manual(const std::string& ip) {
auto parts = split(ip, ':');
// IPv6地址段數(shù)應(yīng)在2-8之間
if (parts.size() < 2 || parts.size() > 8) return false;
// 檢查壓縮符"::"是否出現(xiàn)且僅出現(xiàn)一次
int double_colon_count = 0;
for (const auto& part : parts) {
if (part.empty()) {
double_colon_count++;
}
}
if (double_colon_count > 1) return false;
// 檢查每個(gè)段是否為合法的十六進(jìn)制值
for (const auto& part : parts) {
if (part.empty()) continue; // 跳過壓縮段
// 每個(gè)段長(zhǎng)度不能超過4
if (part.size() > 4) return false;
// 檢查是否為十六進(jìn)制字符
for (char c : part) {
if (!std::isxdigit(c)) return false;
}
}
return true;
}
手動(dòng)解析注意事項(xiàng)
IPv4 驗(yàn)證要點(diǎn):
- 必須由 4 個(gè)部分組成,用點(diǎn)號(hào)分隔
- 每個(gè)部分為 0-255 之間的整數(shù)
- 不能有前導(dǎo)零(除非該部分就是 0)
IPv6 驗(yàn)證要點(diǎn):
- 必須由 2-8 個(gè)部分組成,用冒號(hào)分隔
- 每個(gè)部分為 0-FFFF 之間的十六進(jìn)制數(shù)
- 支持壓縮格式(
::),但只能出現(xiàn)一次 - 不處理特殊地址(如本地回環(huán)地址
::1)的特殊驗(yàn)證
局限性:
- 手動(dòng)解析容易遺漏邊緣情況
- 不支持所有合法格式(如 IPv6 的內(nèi)嵌 IPv4 地址)
- 實(shí)現(xiàn)復(fù)雜,維護(hù)成本高
總結(jié)
| 方法 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場(chǎng)景 |
|---|---|---|---|
| 系統(tǒng)接口(inet_pton) | 簡(jiǎn)單可靠、支持所有合法格式、維護(hù)成本低 | 依賴系統(tǒng)接口 | 大多數(shù)常規(guī)場(chǎng)景 |
| 手動(dòng)解析 | 不依賴系統(tǒng)接口 | 實(shí)現(xiàn)復(fù)雜、易出錯(cuò)、不支持所有格式 | 無法使用系統(tǒng)接口的特殊場(chǎng)景 |
推薦優(yōu)先使用系統(tǒng)接口方法,它能正確處理各種復(fù)雜的 IP 地址格式,且實(shí)現(xiàn)簡(jiǎn)單可靠。在必須使用手動(dòng)解析的場(chǎng)景下,應(yīng)進(jìn)行充分的測(cè)試,覆蓋各種邊緣情況。
到此這篇關(guān)于C++檢測(cè)IPv4和IPv6地址合法性的文章就介紹到這了,更多相關(guān)C++檢測(cè)IPv4和IPv6地址內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- c/c++實(shí)現(xiàn)獲取域名的IP地址
- C++獲得本機(jī)所有網(wǎng)卡的IP和MAC地址信息的實(shí)現(xiàn)方法
- C/C++ ip地址與int類型的轉(zhuǎn)換實(shí)例詳解
- C++如何獲取本機(jī)的IP地址
- C++如何獲取系統(tǒng)信息 C++獲取IP地址、硬件信息等
- C++獲取本機(jī)MAC,IP,MASK地址的方法
- windows下用c++獲取本機(jī)ip地址的三種方法
- C++實(shí)現(xiàn)獲取本機(jī)MAC地址與IP地址
- C++實(shí)踐IP地址類項(xiàng)目參考
- C/C++通過IP獲取局域網(wǎng)網(wǎng)卡MAC地址
- C++實(shí)現(xiàn)LeetCode(93.復(fù)原IP地址)
相關(guān)文章
Qt編寫提示進(jìn)度條的實(shí)現(xiàn)示例
進(jìn)度條在很地方都可以使用到,Qt自帶的進(jìn)度條或者操作系統(tǒng)的進(jìn)度條樣式,不夠炫,本文就介紹一下Qt編寫自定義控件的提示進(jìn)度條的實(shí)現(xiàn)示例,感興趣的可以了解一下2021-12-12
C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例
今天小編就為大家分享一篇關(guān)于C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
C++實(shí)現(xiàn)線性表順序存儲(chǔ)的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線性表順序存儲(chǔ)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下2023-03-03
關(guān)于win32 gettimeofday替代方案
下面小編就為大家?guī)硪黄P(guān)于win32 gettimeofday替代方案。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
關(guān)于C語言中弱符號(hào)與弱引用的實(shí)際應(yīng)用問題
在編碼過程中,我們經(jīng)常遇到符號(hào)重定義的錯(cuò)誤問題,本文通過實(shí)例代碼展示給大家介紹了C語言弱符號(hào)與弱引用的實(shí)際應(yīng)用問題,一起看看吧2021-09-09
string,CString,char*之間的轉(zhuǎn)化
下面是MFC/C++/C中字符類型CString, int, string, char*之間的轉(zhuǎn)換的說明與舉例,經(jīng)常用的東西,相信對(duì)于用C/C++的朋友,還是比較有用的2013-03-03
C語言實(shí)現(xiàn)的統(tǒng)計(jì)素?cái)?shù)并求和代碼分享
這篇文章主要介紹了C語言實(shí)現(xiàn)的統(tǒng)計(jì)素?cái)?shù)并求和代碼分享,來自PAT平臺(tái)(浙江大學(xué)計(jì)算機(jī)程序設(shè)計(jì)能力考試系統(tǒng))的一個(gè)題目,需要的朋友可以參考下2014-08-08
C++之初識(shí)多態(tài)(Visual Studio 2019)的使用
文章主要解釋了C++中的多態(tài)概念、實(shí)現(xiàn)細(xì)節(jié)及一些相關(guān)特性,如虛函數(shù)、override和final關(guān)鍵字、純虛函數(shù)和抽象類,通過代碼示例展示了多態(tài)原理,包括虛函數(shù)表和動(dòng)態(tài)綁定的概念,并探討了多繼承下虛函數(shù)表的行為2026-04-04

