【问题标题】:IP Address to Integer - CIP 地址转整数 - C
【发布时间】:2010-12-13 10:19:40
【问题描述】:

我之前发布了如何实现将整数转换为 IP 地址字符串的函数。那么我们如何反之亦然,也就是说,给定一个作为地址的字符串 (154.111.23.23),我们如何在不使用 inet 函数的情况下取回该整数。

【问题讨论】:

标签: c string ip-address


【解决方案1】:

将字符串扫描成四个字节,并将它们添加/移位为 32 位整数。

【讨论】:

    【解决方案2】:

    Posix.1-2001 为此任务提供inet_pton()。 这也有几个 ms-windows 版本。

    【讨论】:

      【解决方案3】:
      //No checking of the input    
      unsigned int c1,c2,c3,c4;
      scanf("%d.%d.%d.%d",&c1,&c2,&c3,&c4);
      unsigned long ip = (unsigned long)c4+c3*256+c2*256*256+c1*256*256*256;
      printf("The unsigned long integer is %lu\n",ip);
      

      编辑:对于那些对生成的代码感兴趣的人,GCC 足够聪明,可以用左移替换我的 256 乘法。 (在我的程序中,我也调用了 exit):

      0x80483d4   <main>:     lea    0x4(%esp),%ecx
      0x80483d8   <main+4>:       and    $0xfffffff0,%esp
      0x80483db   <main+7>:       pushl  -0x4(%ecx)
      0x80483de   <main+10>:      push   %ebp
      0x80483df   <main+11>:      mov    %esp,%ebp
      0x80483e1   <main+13>:      push   %ecx
      0x80483e2   <main+14>:      sub    $0x34,%esp
      0x80483e5   <main+17>:      lea    -0x14(%ebp),%eax
      0x80483e8   <main+20>:      mov    %eax,0x10(%esp)
      0x80483ec   <main+24>:      lea    -0x10(%ebp),%eax
      0x80483ef   <main+27>:      mov    %eax,0xc(%esp)
      0x80483f3   <main+31>:      lea    -0xc(%ebp),%eax
      0x80483f6   <main+34>:      mov    %eax,0x8(%esp)
      0x80483fa   <main+38>:      lea    -0x8(%ebp),%eax
      0x80483fd   <main+41>:      mov    %eax,0x4(%esp)
      0x8048401   <main+45>:      movl   $0x8048520,(%esp)
      0x8048408   <main+52>:      call   0x8048320 <scanf@plt>
      0x804840d   <main+57>:      mov    -0x8(%ebp),%eax
      0x8048410   <main+60>:      mov    %eax,%edx
      0x8048412   <main+62>:      shl    $0x8,%edx
          0x8048415   <main+65>:      mov    -0xc(%ebp),%eax
      0x8048418   <main+68>:      lea    (%edx,%eax,1),%eax
      0x804841b   <main+71>:      mov    %eax,%edx
      0x804841d   <main+73>:      shl    $0x8,%edx
      0x8048420   <main+76>:      mov    -0x10(%ebp),%eax
      0x8048423   <main+79>:      lea    (%edx,%eax,1),%eax
      0x8048426   <main+82>:      mov    %eax,%edx
      0x8048428   <main+84>:      shl    $0x8,%edx
      0x804842b   <main+87>:      mov    -0x14(%ebp),%eax
      0x804842e   <main+90>:      lea    (%edx,%eax,1),%eax
      0x8048431   <main+93>:      mov    %eax,-0x18(%ebp)
      0x8048434   <main+96>:      mov    -0x18(%ebp),%eax
      0x8048437   <main+99>:      mov    %eax,0x4(%esp)
      0x804843b   <main+103>:     movl   $0x804852c,(%esp)
      0x8048442   <main+110>:     call   0x8048330 <printf@plt>
      0x8048447   <main+115>:     movl   $0x0,(%esp)
      0x804844e   <main+122>:     call   0x8048340 <exit@plt>
      

      【讨论】:

        【解决方案4】:
        uint32_t getDecimalValueOfIPV4_String(const char* ipAddress)
        {
            uint8_t ipbytes[4]={};
            int i =0;
            int8_t j=3;
            while (ipAddress+i && i<strlen(ipAddress))
            {
               char digit = ipAddress[i];
               if (isdigit(digit) == 0 && digit!='.'){
                   return 0;
               }
                j=digit=='.'?j-1:j;
               ipbytes[j]= ipbytes[j]*10 + atoi(&digit);
        
                i++;
            }
        
            uint32_t a = ipbytes[0];
            uint32_t b =  ( uint32_t)ipbytes[1] << 8;
            uint32_t c =  ( uint32_t)ipbytes[2] << 16;
            uint32_t d =  ( uint32_t)ipbytes[3] << 24;
            return a+b+c+d;
        }
        

        【讨论】:

        • 我希望这会有所帮助。享受!!
        • 你初始化一个数组来存储你的字节都用零。您遍历 ip 字符串,如果在同一块中仍有数字(以点分表示法),即在点 (.) 之前,您遇到的每个数字都乘以 10 [这相当于二进制中的左 shif (x2)]。其余代码只是将正确的右移应用于每个块的整数值。
        猜你喜欢
        • 2010-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-11
        • 2020-03-20
        • 1970-01-01
        • 1970-01-01
        • 2014-03-03
        相关资源
        最近更新 更多