C語言寫的ipv6自動補全演算法食之無味棄之可惜

jqliang發表於2020-12-27

這是一個ipv6自動補全的一個演算法,空間複雜度有點高

int complete_ipv6(char* ipv6, char* complete_v6)
{
    char ipcom[40] = {"0000:0000:0000:0000:0000:0000:0000:0000"};
    char *tmpcomv6[128] = { 0 };
    char *p = NULL, *q = NULL, *q1 = NULL;
    int cnt = 0, i = 0, len = 0, l1 = 0, l2 = 0, l3 = 0, sum = 0, l1tmp = 0;
    // 將IPv6地址用::分開
    // 如果IPv6地址為::
    // 如果不包含::或以::結尾
    // 如果以::開頭或::在中間
    p = strchr(ipv6, '/');
    if (p != NULL) {
        *p = '\0';
    }
    p = strstr(ipv6, "::");
    len = strlen(ipcom);
    if (p != NULL) {
        if (p == ipv6) {
            // 地址以::開頭
            if (*(p + 2) == '\0') {
                // 地址為::
                memcpy(complete_v6, ipcom, 40);
            } else {
                // 地址為::xxx
                sum = 0;
                q1 = NULL;
                q = p + 2;
                l1 = strlen(q);
                for (i = 0; i < l1; i++) {
                    if (*(p + 1 + l1 -i) != ':') {
                        q1 = strrchr(q, ':');

                        *(ipcom + len - i -1 - sum) = *(p + 1 + l1 -i);
                    } else {
                        l1tmp = strlen(q);
                        sum += (4 - (l1tmp - (q1 - q) -1));
                        *q1 = '\0';
                        cnt += 1;
                    }
                }
            }
        } 
        // 地址形式xxx::xxx
        if (p != ipv6) {
            // 處理xxx::
            cnt = 0;
            q = ipv6;
            l3 = p - ipv6;
            for (i = 0; i < l3; i++) {
                if (*(ipv6 + i) != ':') {
                    q1 = strchr(q, ':');
                    *(ipcom + (4 - (q1 - q)) + sum  + i) = *(ipv6 + i);
                } else {
                    sum += (4 - (q1 - q));
                    q1 = q1 + 1;
                    q = q1;
                    cnt += 1;
                }
            }
            // 處理::xxx
            sum = 0;
            q1 = NULL;
            q = p + 2;
            l1 = strlen(q);
            l1tmp = 0;
            for (i = 0; i < l1; i++) {
                if (*(p + 1 + l1 -i) != ':') {
                    q1 = strrchr(q, ':');
                    *(ipcom + len - i -1 - sum) = *(p + 1 + l1 -i);
                } else {
                    l1tmp = strlen(q);
                    sum += (4 - (l1tmp - (q1 - q) -1));
                    *q1 = '\0';
                    cnt += 1;
                }
            }
        } else {
            
        }
    } else {
        // 不包含::
        l2 = strlen(ipv6);
        sum = 0;
        q1 = NULL;
        q = ipv6;
        for (i = 0; i < l2; i++) {
            if (*(ipv6 + i) != ':') {
                q1 = strchr(q, ':');
                if (q1 == NULL) {
                    q1 = strchr(q, '\0');
                }
                *(ipcom + (4 - (q1 - q)) + sum  + i) = *(ipv6 + i);
            } else {
                sum += (4 - (q1 - q));
                q1 = q1 + 1;
                q = q1;
                cnt += 1;
            }
        }
    } 
    
    memcpy(complete_v6, ipcom, 40);
    printf("------%s\n", complete_v6);
    return 0;
}

有需要的同學可以測試一下這個,我測過是可以滿足我寫這段程式碼時的所需邏輯。
如果你有所改進,請分享出來

相關文章