一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【經典面試題】請使用C語言編程實現(xiàn)對IPV4地址的合法性判斷

嵌入式物聯(lián)網開發(fā) ? 來源: 嵌入式物聯(lián)網開發(fā) ? 作者: 嵌入式物聯(lián)網開發(fā) ? 2023-05-16 15:23 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

**C語言編程實現(xiàn)對IPV4地址的合法性判斷**

> 有了解過我的朋友,可能有點印象,我在N年前的博客中,就寫了這個主題,當時確實是工作中遇到了這個問題。本想著等工作搞完之后,就把這個問題的解決代碼補上,結果一鴿,就是好幾年,真是慚愧。現(xiàn)在把這部分代碼公開,歡迎大家來下載測試。

@[toc]
# 1 寫在前面

有了解過我的朋友,可能有點印象,我在N年前的博客中,就寫了這個主題,當時確實是工作中遇到了這個問題。本想著等工作搞完之后,就把這個問題的解決代碼補上,結果一鴿,就是好幾年,真是慚愧?,F(xiàn)在把這部分代碼公開,歡迎大家來下載測試。

如果你發(fā)現(xiàn)代碼有問題,歡迎與我私信聯(lián)系。

# 2 需求分析

其實,本專題的需求很簡單,就是輸入一段字符串,判斷它是不是合法的IPv4地址。僅僅從功能上看,似乎很簡單,但是真正要做到很完美,也是需要下點功夫的。不信,你看看下文的拆解。

![IPV4 的圖像結果](https://img-blog.csdnimg.cn/img_convert/994e3109304e34a6bbd59db8247d37c6.jpeg)

# 3 簡單版本

我們先上一個簡單版本,直接看代碼:

```c
#include
#include
#include
#include

int is_valid_ipv4(const char *ip_address)
{
int num, dots = 0;
char *ptr;

if (ip_address == NULL) {
return 0;
}

ptr = strtok((char *)ip_address, ".");
if (ptr == NULL) {
return 0;
}

while (ptr) {
if (!isdigit(*ptr)) {
return 0;
}

num = atoi(ptr);
if (num < 0 || num > 255) {
return 0;
}

ptr = strtok(NULL, ".");
if (ptr != NULL) {
dots++;
}
}

if (dots != 3) {
return 0;
}

return 1;
}

int check_is_valid_ipv4(const char *ip)
{
int ret = 0;

ret = is_valid_ipv4(ip);

return ret;
}

int main(int argc, const char *argv[])
{
const char *ip = argv[1];

printf("check %sn", ip);
printf("ret %dn", check_is_valid_ipv4(ip));
}
```

編譯運行一下,輸入一個常見的ipv4地址是沒有問題,比如 "192.168.0.1";同時,非法的字符輸入也是會報錯的。

```c
~/ipv4]$gcc -o test ipv4.c
~/ipv4]$./test 192.168.0.1
check 192.168.0.1
ret 1
~/ipv4]$./test
check 192.168.w.2
ret 0
```

但是,如果我加一個限制:如何判斷一個IPV4地址是一個合法的 **主機地址** 呢?

比如這個:“238.171.84.41”,它的判斷還是合法的哦,實際上這不是合法的 **主機地址** 。

```c
~/ipv4]$./test 238.171.84.41
check 238.171.84.41
ret 1
```

另外一個,上面的代碼還檢測不到,諸如此類的輸入:“0192.168.1.1”

```c
~/ipv4]$./test 0192.168.1.1
check 0192.168.1.1
ret 1
```

所以,我們需要優(yōu)化一下。

# 4 進階一下

正如上面的分析,我們需要對代碼進行優(yōu)化:

首先得判斷按照 "." 分割后的數(shù)字段,不能以 "0" 字符開頭。

```c
while (ptr) {
if (!isdigit(*ptr)) {
return 0;
}

if (*ptr == '0') { //check start with '0'
return 0;
}

num = atoi(ptr);
if (num < 0 || num > 255) {
return 0;
}

ptr = strtok(NULL, ".");
if (ptr != NULL) {
dots++;
}
}

~/ipv4]$./test 0192.168.1.1
check 0192.168.1.1
ret 0
```

根據IPv4地址的分類:

- A類:(1.0.0.1-126.255.255.254)(默認子網掩碼:255.0.0.0或0xFF000000)第一個字節(jié)為網絡號,后三個字節(jié)為主機號,表示為網絡--主機--主機--主機。該類IP地址的最前面為“0”,所以地址的網絡號取值于1~126之間。共有16777214個主機地址,一般用于大型網絡。

- B類:(128.1.0.1-191.254.255.254)(默認子網掩碼:255.255.0.0或0xFFFF0000)前兩個字節(jié)為網絡號,后兩個字節(jié)為主機號。該類IP地址的最前面為“10”,所以地址的網絡號取值于128~191之間。共有65534個主機地址,一般用于中等規(guī)模網絡。

- C類:(192.0.1.1-223.255.254.254)(子網掩碼:255.255.255.0或0xFFFFFF00)前三個字節(jié)為網絡號,最后一個字節(jié)為主機號。該類IP地址的最前面為“110”,所以地址的網絡號取值于192~223之間。共有254個主機地址,一般用于小型網絡。

- D類:是多播地址。(224.0.0.1-239.255.255.254) 該類IP地址的前面4位為“1110”,所以網絡號取值于224~239之間;后面28位為組播地址ID。這是一個專門保留的地址。它并不指向特定的網絡,目前這一類地址被用在多點廣播(Multicasting)中。多點廣播地址用來一次尋址一組計算機,它標識共享同一協(xié)議的一組計算機。

- E類:是保留地址,為將來使用保留。(240.0.0.0---255.255.255.254) 該類IP地址的最前面為“1111”,所以網絡號取值于240~255之間。

可知,如果要符合一個正常的IPv4主機地址,只能是A、B、C類,而不能是D、E類。

所以在判斷時,我們應該增加IPv4地址的類別判斷。

在上面的判斷返回前,增加一個判斷:

```c
if (atoi(ip_address) >= 1 && atoi(ip_address) <= 126) {
printf("This is a Class A IP address.n");
return 1;
} else if (atoi(ip_address) >= 128 && atoi(ip_address) <= 191) {
printf("This is a Class B IP address.n");
return 1;
} else if (atoi(ip_address) >= 192 && atoi(ip_address) <= 223) {
printf("This is a Class C IP address.n");
return 1;
} else {
printf("This is not a Class A, B, or C IP address.n");
return 0;
}
```

完整的代碼如下:

```c
#include
#include
#include
#include

int is_valid_ipv4(const char *ip_address)
{
int num, dots = 0;
char *ptr;

if (ip_address == NULL) {
return 0;
}

ptr = strtok((char *)ip_address, ".");
if (ptr == NULL) {
return 0;
}

while (ptr) {
if (!isdigit(*ptr)) {
return 0;
}

if (*ptr == '0') { //check start '0'
return 0;
}

num = atoi(ptr);
if (num < 0 || num > 255) {
return 0;
}

ptr = strtok(NULL, ".");
if (ptr != NULL) {
dots++;
}
}

if (dots != 3) {
return 0;
}

if (atoi(ip_address) >= 1 && atoi(ip_address) <= 126) {
printf("This is a Class A IP address.n");
return 1;
} else if (atoi(ip_address) >= 128 && atoi(ip_address) <= 191) {
printf("This is a Class B IP address.n");
return 1;
} else if (atoi(ip_address) >= 192 && atoi(ip_address) <= 223) {
printf("This is a Class C IP address.n");
return 1;
} else {
printf("This is not a Class A, B, or C IP address.n");
return 0;
}

return 1;
}

int check_is_valid_ipv4(const char *ip)
{
int ret = 0;

ret = is_valid_ipv4(ip);

return ret;
}

int main(int argc, const char *argv[])
{
const char *ip = argv[1];

printf("check %sn", ip);
printf("ret %dn", check_is_valid_ipv4(ip));
}
```

這個時候,我們再試一下之前的非A/B/C類的IPv4地址:

```c
~/ipv4]$./test 238.171.84.41
check 238.171.84.41
This is not a Class A, B, or C IP address.
ret 0

~/ipv4]$./test 192.168.2.3
check 192.168.2.3
This is a Class C IP address.
ret 1
```

至此,基本得到了比較完美的判斷,但有沒有漏洞呢?留給讀者自己去思考吧。

# 5 高階版本

有經驗的程序一定會發(fā)現(xiàn),上面的各個判斷真的號麻煩啊!

每個case都需要這樣去比較判斷,那得多費勁??!

有沒有更加清爽一點的高階方法???

答案當然是有的,這個時候你就需要了解一下:**正則表達式** 了。

很多主流的編程語言都有標準庫來支持正則表達式,那么C語言里面有沒有呢?

其實C語言里面也是可以用正則表達式的,這個先留個懸念,且聽下回分解。

歡迎打擊提前預習下:[正則表達式語言 - 快速參考 | Microsoft Learn](https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expression-language-quick-reference)

# 6 完整測試用例

本小節(jié)給大家補充一下各種測試用例,希望對大家測試代碼有幫助:

```c
合法的測試輸入
192.168.0.1
10.0.0.1
172.16.0.1
255.255.255.255

非法的測試輸入
256.0.0.1
192.168.0.0.1
192.168.0
192.168.0.1.2

非法的測試輸入
256.0.0.1
192.168.0.0.1
192.168.0
192.168.0.1.2
300.300.300.300
1.2.3
1.2.3.4.5
1.2.3.4.
.1.2.3.4
1..2.3.4
```

測試用例是不斷豐富的,歡迎大家來補充。

審核編輯黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7630

    瀏覽量

    140970
  • IPv4
    +關注

    關注

    0

    文章

    144

    瀏覽量

    20403
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    C語言進階】面試題請使用宏定義實現(xiàn)字節(jié)對齊

    C語言進階】面試題請使用宏定義實現(xiàn)字節(jié)對齊
    的頭像 發(fā)表于 07-11 09:21 ?3188次閱讀
    【<b class='flag-5'>C</b><b class='flag-5'>語言</b>進階】<b class='flag-5'>面試題</b>:<b class='flag-5'>請使用</b>宏定義<b class='flag-5'>實現(xiàn)</b>字節(jié)對齊

    《Visual C# 2008程序設計經典案例設計與實現(xiàn)》---判斷主機IP合法性算法

    《Visual C# 2008程序設計經典案例設計與實現(xiàn)》---判斷主機IP合法性算法.zip[hide][/hide]
    發(fā)表于 05-14 10:16

    java經典面試題深度解析

    回答面試題Int 與Integer的區(qū)別第三節(jié) 以數(shù)據結構挖掘集合面試考點第四節(jié) 經典面試題重載與重寫第五節(jié) 如何回答面試官提問Java的接
    發(fā)表于 06-20 15:16

    C語言 經典面試題

    C語言經典面試題目.doc
    發(fā)表于 08-05 22:03

    c語言面試題,c++面試題下載

    c語言面試題,c++面試題1. static有什么用途?(請至少說明兩種) 1) 限制變量的作用域 2) 設置變量的存儲域 2.&
    發(fā)表于 10-22 11:19 ?5次下載

    c語言面試題

    c語言面試題集(單片機)C language problem(20151125084232)
    發(fā)表于 12-18 14:05 ?9次下載

    c語言面試題

    c語言面試題
    發(fā)表于 11-05 16:48 ?0次下載

    C語言經典面試題

    面試題
    發(fā)表于 12-20 22:41 ?0次下載

    C語言經典面試題

    C語言 經典面試題
    發(fā)表于 01-05 11:27 ?0次下載

    經典硬件面試題精選及解答

    經典硬件面試題精選及解答
    發(fā)表于 11-29 18:02 ?0次下載

    剩余地址分配完畢,全球IPv4地址徹底用完了

    長期以來,全球IPv4地址耗盡令人擔憂,今天這一時刻終于來臨——所有43億個IPv4地址已分配完畢,這意味著沒有更多的IPv4
    的頭像 發(fā)表于 11-26 10:39 ?6031次閱讀

    IPv4地址耗盡后,IPv6部署計劃如何了

    11月25日,歐洲的IPv4 地址正式宣布徹底分配完了。而早在2016年,亞太地區(qū)的IPv4地址池也已經完全耗盡,沒有新的IP 地址可供分配
    的頭像 發(fā)表于 12-03 14:54 ?3140次閱讀

    C語言經典面試題】static關鍵字的作用有哪些?

    經典面試題,有必要了解下!
    的頭像 發(fā)表于 10-02 12:00 ?2968次閱讀
    【<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>經典</b><b class='flag-5'>面試題</b>】static關鍵字的作用有哪些?

    C語言進階】面試題請使用代碼判斷主機存儲屬于大端模式還是小端模式?

    經典面試題,有必要了解下!
    的頭像 發(fā)表于 10-02 11:56 ?2670次閱讀
    【<b class='flag-5'>C</b><b class='flag-5'>語言</b>進階】<b class='flag-5'>面試題</b>:<b class='flag-5'>請使用</b>代碼<b class='flag-5'>判斷</b>主機存儲屬于大端模式還是小端模式?

    IP地址IPV4IPV6的區(qū)別

    IPV4互聯(lián)協(xié)議版本4,有版本V4之前就有IPV1 IPV2IPV3,同樣有IPV5
    發(fā)表于 10-26 10:41 ?3339次閱讀
    IP<b class='flag-5'>地址</b>:<b class='flag-5'>IPV4</b>和<b class='flag-5'>IPV</b>6的區(qū)別