天天看點

linux實作shell指令支援ipv4位址轉換

這幾天一直都在和IP位址打交道.GDB出來一個變量,就到電腦裡面看看二進制,然後每八位的去計算得出IP位址,着實不勝其煩.搜了一下網上的資訊,也沒有找到類似的工具.可能大家都覺得寫這麼一個東西太簡單了.但是其實,無論是否簡單,真正能夠産生便利的指令,就都是不錯的指令.既然沒有現成的可用,那索性就自己寫一個.算來也沒有幾行代碼.

說說這個過程的波折吧.這麼簡單一個程式,寫出來各種問題.

1. 位址的整形表示是unsigned int .最初進行位址轉換的時候調用的是atoi這個函數.試了很多次,結果都不對.當然也有對的時候.比較差異,後來才發現,原來atoi的傳回值的int ,當我傳遞給atoi的參數轉成整數的範圍大于差不多2億多的時候,精度就開始出現問題,搞出來的就會被丢棄.是以就出現了錯誤.

2. 上述問題不行,換一個思路.使用sscanf.不過用了半天和上面的方法沒有差別,還是會出錯.找了半天發現.應該用%u,而不是%d.

3. 使用strtok.預設擷取到的值會覆寫掉第一個參數.也就是說strtok的第一個參數是值-結果參數.

吃了這麼多虧,總算寫完了.支援雙向轉換.代碼如下:

#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char ** argv)
{
    if (argc < 2)
    {
        printf("usage : unless two args\n");
        return 0;
    }

    int isstr = 0;
    int i = 0;
    for (i = 0; i < strlen(argv[1]); i++)
    {
        if (argv[1][i] == '.')
        {
            isstr = 1;
        }
    }

    if (isstr)
    {
        unsigned int ipnum = inet_addr(argv[1]);

        printf("%s : %u\n", argv[1], ipnum);
    }
    else
    {
        unsigned int ipnum;
        char *ip = NULL;
        struct in_addr addr;

        sscanf(argv[1], "%u", &ipnum);

        addr.s_addr = ipnum;
        ip = inet_ntoa(addr);

        printf("%u : %s \n", ipnum, ip);
    }

    return 0;
}
           

使用方法可以編譯出一個可執行檔案,然後放到/usr/bin.目錄下.後面就可以直接使用了.記得修改成可執行權限.

有的時候,看似簡單的事情,實作起來還是會有意想不到的結果發生.隻有體驗過,才能夠下結論.記得前一段時間去HW筆試,筆試題并沒有作出來,不是不會,在我看來其實很簡單.但是就是做錯了.回來跟GF說了,她說你隻要沒做出來就是不會,就是不簡單.想想也對.

不喜歡雞湯的各位可以直接看代碼,希望能夠幫助到你.